纯js实现移动端滑动控件,以上下滑动自取中间位置年龄为例;

<!-- 
    需求:上下滑动,在一个大的div块里显示5个小的值,滑动过程中自动获取中间位置的值
           需要注意的是:
                  1 touchmove会多次被触发;
                  2 获取中间位置的值可以通过定位得top值来获取
                  3 以1到99为例,上下滑动时一定注意若取中间值,首尾一定需要切值滑动到中间位置;
                    当页面显示为 93 94 95 96 97时,在向上滑动时 ,假设在滑动divHeight*5的距离,
                        这样最后页面显示将只存在98 99 ,取中间值时将为空;
                    同样显示为 3,4,5,6,7时,在向下滑动滑动时 ,假设在滑动divHeight*5的距离,
                        这样最后页面显示将只存在98 99 ,取中间值时将为空;
                    但是需要注意的是最小值和最大值必须在中间位置出现
 -->
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimal-ui" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    <meta name="format-detection" content="telephone=no, email=no" />
    <title>Document</title>
    <style>
        #id {
            width: 200px;
            height: 150px;
            background: red;
            position: fixed;
            left: 34%;
            top:0px;
            overflow:hidden;
        }
        .box{
            width:100%;
            height:100%;
        }
        .age-item{
            width: 30px;
            height: 30px;
            background: green;
            border: solid 1px grey;
            position:absolute;
            /*top:0;*/
        }
        .box .age-option-select{
            font-size: 16px;
            color: #ffffff;
            background-color: #0000ff;
        }
    </style>
    <script>
        function cons(idx){
            console.log(idx)
        }
        function load() {
            /*单指拖动*/
            var itemHeight = 30;  //每个item选项的高度
            var obj = document.querySelector('.box');
            var html2 = '';
            for(var i=1;i<100;i++){
                html2+='<div class="age-item" onclick="cons('+i+')" style="top:'+(i-1)*itemHeight+'px">'+i+'</div>'
            }
            obj.innerHTML = html2;
            var touchStart = 0;
            var touchEnd =0;
            var ageOption = document.getElementsByClassName('age-item');
            changeSelectStyle(ageOption);
            obj.addEventListener("touchstart", function(event) {
                var touch = event.targetTouches[0];
                touchStart = touch.pageY;
                obj.addEventListener('touchmove', function(event) {
                    // 如果这个元素的位置内只有一个手指的话  
                    if (event.targetTouches.length == 1) {    
                        event.preventDefault(); // 阻止浏览器默认事件
                        var touch = event.targetTouches[0]; 
                        touchEnd = touch.pageY;
                    }
                }, false);
            });
            obj.addEventListener("touchend", function() {
                var ages = document.getElementsByClassName('age-item');
                if(touchEnd-touchStart>0){  //向下滑
                    var ageItem = 0;
                    for(let j=0;j<ages.length;j++){
                        if(ages[j].style.top == '0px'|| ages[j].style.top == 0){
                            ageItem = ages[j].innerHTML;
                            break;
                        }
                    }
                    if(parseInt(ages[0].style.top)>=2*itemHeight){
                        return;
                    }else{
                        if(parseInt(ageItem)+1 < Math.ceil((touchEnd-touchStart)/itemHeight)){
                             var diff = parseInt(ageItem)+1;
                             changeTop(ages,diff);
                        }else{
                            var diff = Math.ceil((touchEnd-touchStart)/itemHeight);
                             changeTop(ages,diff);
                        }
                    }
                }else{       //向上滑
                    var ageItem = 0;
                    for(let k=ages.length-1;k>0;k--){
                        if(ages[k].style.top == 4*itemHeight +'px'){
                            ageItem = ages[k].innerHTML;
                            break;
                        }
                    }
                   if(parseInt(ages[ages.length-1].style.top)<=2*itemHeight){
                        return;
                    }else{
                        if(ageItem==''){
                            var diff = -1;
                            changeTop(ages,diff);
                        }else if((99-parseInt(ageItem))+2<Math.ceil(Math.abs(touchEnd-touchStart)/itemHeight)){
                            var diff = parseInt(ageItem)-99-2;
                            changeTop(ages,diff);
                        }else{
                            var diff = Math.ceil((touchEnd-touchStart)/itemHeight);
                            changeTop(ages,diff);
                        }
                    }
                }
                // 由于上面需要修改99次样式,需要进行99次的重绘;可以修改为重新插入一次,在此不详细列出
                delEvent(obj,'touchstart');
                delEvent(obj,'touchmove');
            });
            function delEvent(obj,evt,fn,useCapture){
               if (obj.removeEventListener) {
               //先使用W3C的方法移除事件处理函数
                   obj.removeEventListener(evt,fn,!!useCapture);
               }else {
                  if(obj.__EventHandles){
                     var fns = obj.__EventHandles[evt];
                     if(fns){delete fns[fn.__EventID];}
                  }
                }
            }
            function changeTop(obj,diff){
                for(let k=0;k<obj.length;k++){
                    obj[k].style.top = parseInt(obj[k].style.top) + diff*itemHeight +'px';
                }
                changeSelectStyle(ageOption);
            }
            function changeSelectStyle(arr){
                for(var i=0 ; i < arr.length ; i++){
                    if(hasClass('age-option-select',arr[i])){
                        removeClass('age-option-select',arr[i])
                    }
                    if(arr[i].style.top!=undefined && arr[i].style.top == 2*itemHeight+'px'){
                        if(!hasClass('age-option-select',arr[i])){
                            addClass('age-option-select',arr[i])
                        }
                    }
                }
            }
        }
        // 公有方法
        function hasClass(cla, element) {
            if(element.className.trim().length === 0) return false;
            var allClass = element.className.trim().split(" ");
            return allClass.indexOf(cla) > -1;
        }
        function addClass(cla,element){
            if(!hasClass(cla,element)){
                if(element.setAttribute){
                    element.setAttribute("class",element.getAttribute("class")+" "+cla);
                }else{
                    element.className = element.className+" "+cla;
                }
            }
        }
        function removeClass(cla,element){
            if(hasClass(cla,element)){
                var allClass = element.className.trim().split(" ");
                allClass.splice(allClass.indexOf(cla),1);
                element.className = allClass.join(' ');
            }
        }
    </script>

</head>

<body onload="load()">
    <div id="inp"></div>
    <div id="id" style="top:0px;">
        <div class="box" style="top:0px;">
            
        </div>
    </div>
</body>

</html>

  

猜你喜欢

转载自www.cnblogs.com/xhliang/p/8992320.html
今日推荐