美文网首页
JS实用控件——可滑动列表项

JS实用控件——可滑动列表项

作者: 丁俊杰_ | 来源:发表于2017-12-29 16:57 被阅读50次

    有时候我们在一个list中要为列表项添加左右滑动的效果,通过滑动出来的按钮实现一些点击事件,这时候就可以用到本文所介绍的插件了。

    照例,先上效果图:


    插件效果图

    我觉得这个效果还是挺高频且实用的,奈何weui里面没有这个扩展,只能自己在网上搜索并改进了。为了方便使用,我已经把左右滑动效果封装成了一个jquery插件了,读者也可以根据需要修改其代码做更多的扩展。

    1、列表项html
    先贴一下列表项的html代码:

    <a href="#" class="weui-media-box weui-media-box_appmsg swipte_item">
        <div class="weui-media-box__hd">
            <img class="weui-media-box__thumb" src="thumbnail.png">
        </div>
        <div class="weui-media-box__bd">
            <h4 class="weui-media-box__title"></h4>
            <p class="weui-media-box__desc"></p>
        </div>
        <li class="weui-swiped-btn weui-swiped-btn_warn swipe_btn">拒接</li>
        <li class="weui-swiped-btn accept_btn">接单</li>
    </a>
    

    其中,两个li标签的class属性可以自定义,后续生成滑动实例要用到,还有,我用的是weui,写出来是如上的效果,读者最好根据需求自行制作控件。

    2、列表项css
    随后是css代码:

    .weui-swiped-btn.weui-swiped-btn_warn.swipe_btn {
        color: white;
        position: absolute;
        right: -67px;
        width: 35px;
        text-align: center;
        height: 70px;
        line-height: 70px;
    }
    
    .weui-swiped-btn.accept_btn {
        color: white;
        background: #1AAD19;
        position: absolute;
        left: -67px;
        width: 35px;
        text-align: center;
        height: 70px;
        line-height: 70px;
    }
    

    读者根据自己的需求修改就好了,这里面有个问题,就是left、right的偏移和width不一样,我暂时没找出问题根源,只能在插件里通过增加滑动偏移来抵消掉负偏移,不知道哪位大神能指导一下。

    3、滑动插件js代码
    借鉴前人代码基础上,已经封装成了JQuery代码,能实现左右双向的滑动:

    /* * 
     * @brief 列表项左滑右滑功能创建
     *        使用方法:$('.itemWipe').touchWipe({itemBtn: '.item-button'});
     * @param itemWipe  条目样式名
     *        itemBtn   滑动后出现的按钮样式名(左右按钮大小应一致,传入任一个即可)
     * @return 带滑动效果的列表项
     * */
    (function ($) {
        $.fn.touchWipe = function (option) {
            var defaults = {
                itemBtn: '.item-delete', //删除元素
            };
            var opts = $.extend({}, defaults, option); //配置选项
            var btnWidth = $(opts.itemBtn).width() + 32;  //此处有文章中说的问题,望指导
    
            var initX; //触摸位置X
            var initY; //触摸位置Y
            var moveX; //滑动时的位置X
            var moveY; //滑动时的位置Y
            var X = 0; //移动距离X
            var Y = 0; //移动距离Y
            var flagX = 0; //是否是左右滑动 0为初始,1为左右,2为上下,在move中设置,在end中归零
            var objX = 0; //目标对象位置
    
            $(this).on('touchstart', function (event) {
                //console.log('start..');
                var obj = this;
                initX = event.targetTouches[0].pageX;
                initY = event.targetTouches[0].pageY;
                //console.log(initX + ':' + initY);
                objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
                //console.log(objX);
                if (objX == 0) {
                    $(this).on('touchmove', function (event) {
                        // 判断滑动方向,X轴阻止默认事件,Y轴跳出使用浏览器默认
                        if (flagX == 0) {
                            setScrollX(event);
                            return;
                        } else if (flagX == 1) {
                            event.preventDefault();
                        } else {
                            return;
                        }
    
                        var obj = this;
                        moveX = event.targetTouches[0].pageX;
                        X = moveX - initX;
                        if (X >= 0) {
                            var l = Math.abs(X);
                            obj.style.WebkitTransform = "translateX(" + l + "px)";
                            if (l > btnWidth) {
                                l = btnWidth;
                                obj.style.WebkitTransform = "translateX(" + l + "px)";
                            }
                        } else if (X < 0) {
                            var l = Math.abs(X);
                            obj.style.WebkitTransform = "translateX(" + -l + "px)";
                            if (l > btnWidth) {
                                l = btnWidth;
                                obj.style.WebkitTransform = "translateX(" + -l + "px)";
                            }
                        }
                    });
                } else if (objX < 0) {
                    $(this).on('touchmove', function (event) {
                        // 判断滑动方向,X轴阻止默认事件,Y轴跳出使用浏览器默认
                        if (flagX == 0) {
                            setScrollX(event);
                            return;
                        } else if (flagX == 1) {
                            event.preventDefault();
                        } else {
                            return;
                        }
    
                        var obj = this;
                        moveX = event.targetTouches[0].pageX;
                        X = moveX - initX;
                        if (X >= 0) {
                            var r = -btnWidth + Math.abs(X);
                            obj.style.WebkitTransform = "translateX(" + r + "px)";
                            if (r > 0) {
                                r = 0;
                                obj.style.WebkitTransform = "translateX(" + r + "px)";
                            }
                        } else { //向左滑动
                            obj.style.WebkitTransform = "translateX(" + -btnWidth + "px)";
                        }
                    });
                } else {
                    $(this).on('touchmove', function (event) {
                        // 判断滑动方向,X轴阻止默认事件,Y轴跳出使用浏览器默认
                        if (flagX == 0) {
                            setScrollX(event);
                            return;
                        } else if (flagX == 1) {
                            event.preventDefault();
                        } else {
                            return;
                        }
    
                        var obj = this;
                        moveX = event.targetTouches[0].pageX;
                        X = moveX - initX;
                        if (X <= 0) {
                            var r = btnWidth + Math.abs(X);
                            obj.style.WebkitTransform = "translateX(" + r + "px)";
                            if (r > 0) {
                                r = 0;
                                obj.style.WebkitTransform = "translateX(" + r + "px)";
                            }
                        } else { //向右滑动
                            obj.style.WebkitTransform = "translateX(" + btnWidth + "px)";
                        }
                    });
                }
            })
    
            //结束时判断,并自动滑动到底或返回
            $(this).on('touchend', function (event) {
                var obj = this;
                objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
                if (objX > -btnWidth / 2 && objX <= 0) {
                    obj.style.transition = "all 0.2s";
                    obj.style.WebkitTransform = "translateX(" + 0 + "px)";
                    obj.style.transition = "all 0";
                    objX = 0;
                } else if (objX > btnWidth / 2) {
                    obj.style.transition = "all 0.2s";
                    obj.style.WebkitTransform = "translateX(" + btnWidth + "px)";
                    obj.style.transition = "all 0";
                } else if (objX < btnWidth / 2 && objX > 0) {
                    obj.style.transition = "all 0.2s";
                    obj.style.WebkitTransform = "translateX(" + 0 + "px)";
                    obj.style.transition = "all 0";
                    objX = 0;
                } else {
                    obj.style.transition = "all 0.2s";
                    obj.style.WebkitTransform = "translateX(" + -btnWidth + "px)";
                    obj.style.transition = "all 0";
                    objX = -btnWidth;
                }
                flagX = 0;
            })
    
            //设置滑动方向
            function setScrollX(event) {
                moveX = event.targetTouches[0].pageX;
                moveY = event.targetTouches[0].pageY;
                X = moveX - initX;
                Y = moveY - initY;
    
                if (Math.abs(X) > Math.abs(Y)) {
                    flagX = 1;
                } else {
                    flagX = 2;
                }
                return flagX;
            }
    
            //链式返回
            return this;
        };
    
    })(jQuery);
    

    接下来,我会其中关键的地方和思路解释清楚,具体内容就需要读者自己理解了:

    1、获得首次点击时的像素点(x,y)坐标值,并通过WebkitTransform获得当前列表项偏移的像素(objX等于0说明没有偏移,大于0说明向右偏移了,小于0说明向左偏移了)。

    2、touchmove事件触发后,获得当前的手指点住的像素点(x,y)坐标,通过与初始坐标相减,获得手指滑动的方向(变量X大于0是右滑,小于0是左滑)。

    3、随后,判断当前x轴的偏移量,当超过按钮一半是自动滑动到底,小于一半是返回。

    4、最后,在你的js代码中,通过$('.itemWipe').touchWipe({itemBtn: '.item-button'});即可为指定html标签绑定此功能。

    以上。

    github传送地址:https://github.com/JunJieDing666/YouZhiGou

    若有错误烦请指出,有地方不理解欢迎讨论。

    相关文章

      网友评论

          本文标题:JS实用控件——可滑动列表项

          本文链接:https://www.haomeiwen.com/subject/bcfbgxtx.html