<!-- 需求:上下滑動,在一個大的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>
用戶在移動端瀏覽H5的時候,會使用手指進行一連串的操作,單擊、雙擊、上拉、下拉等等一系列操作,這里主要針對touch事件進行一些簡單的介紹;
用戶從手指觸碰到屏幕到手指離開屏幕這中間,會觸發一系列的touch事件:
①touchstart:當手指觸碰到屏幕的時候觸發
②touchmove:當手指在屏幕上滑動的時候觸發
③touchend:當手指離開屏幕的時候時候觸發
④touchcancel事件:當系統停止跟蹤觸摸的時候觸發(這個事件很少會用,一般不做深入研究)。
一般來講,從手指觸碰到屏幕,到手指離開屏幕,至少會觸發touchstart、touchmove、touchend三個事件,因為手指按下與抬起時候的位置,不可能完全相同(當然也會有例外);
使用:
監聽這3個事件:
1. window.touchstart= function(event){}
2. window.touchmove= function(event){}
3. window.touchend= function(event){}
event:
1. touches:表示當前跟蹤的觸摸操作的touch對象的數組。
2. targetTouches:特定於事件目標的Touch對象的數組。
3. changeTouches:表示自上次觸摸以來發生了什么改變的Touch對象的數組。
每個touch對象包含的屬性
1. clientX:觸摸目標在視口中的x坐標。
2. clientY:觸摸目標在視口中的y坐標。
3. identifier:標識觸摸的唯一ID。
4. pageX:觸摸目標在頁面中的x坐標。
5. pageY:觸摸目標在頁面中的y坐標。
6. screenX:觸摸目標在屏幕中的x坐標。
7. screenY:觸摸目標在屏幕中的y坐標。
8. target:觸目的DOM節點目標。