這篇文章帶給大家的內容是關於原生js實現行動端Touch滑動反彈的方法(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
行動裝置 Touch 滑動反彈
什麼是Touch滑動?就是類似PC端的滾動事件,但是在行動端是沒有滾動事件的,所以就要用到Touch事件結合js去實現,效果如下:1. 準備工作
什麼是行動端的Touch事件?在行動端Touch事件可以細分成三種,分別是:touchstart、touchmove和touchend,而且touch事件必須要用addEventListener去監聽。touchStart當手指觸碰到螢幕的時候觸發
touchmove當手指在螢幕上不斷移動的時候觸發
touchend當手指離開螢幕的時候觸發
#Touch 事件觸發的Event 物件:
// 手指触碰到屏幕时触发 element.addEventListener('touchstart', function (e) { // 打印的事件对象 console.log(e); })
changedTouches、targetTouches、touches都是偽數組,裡面裝的是手指列表
三種返回對象的區別:
其實這三種返回的對象,都是表示用戶觸摸事件時的手指信息,之所以是一個偽數組,是因為有可能出現多指同時觸摸,但是在實際工作中一般不去考慮多指的情況。而它們唯一的區別就是在touchstart和touchmove事件的時候,changedTouches、targetTouches、touches都能獲取到手指的信息,但是在touchend事件的時候,targetTouches、touches對像是不能返回離開屏幕時的手指信息,只有changedTouches對象能回傳。有哪些手指資訊?
我們可以看下上面的圖片,在changedTouche[0]中,有些值:clientX:74 // 触摸点相对于浏览器的 viewport 左边缘的 x 坐标,不会包括左边的滚动距离。 clientY:73 // 触摸点相对于浏览器的 viewport 上边缘的 Y 坐标,不会包括上边的滚动距离。 screenX:2202 // 触摸点相对于屏幕左边缘的 x 坐标。 screenY:327 // 触摸点相对于屏幕上边缘的 Y 坐标。 pageX:65 // 触摸点相对于 document 的左边缘的 x 坐标,包括左边的滚动距离 pageY:18 // 触摸点相对于 document 的上边缘的 Y 坐标,包括左边的滚动距离
2. 基本結構
HTML部分:
<aside> <div> <ul> <li>列表一</li> <li>列表二</li> <li>列表三</li> <li>列表四</li> <li>列表五</li> <li>列表六</li> <li>列表七</li> <li>列表八</li> <li>列表九</li> <li>列表十</li> </ul> </div> </aside>
css部分:
在列表的父盒子上设定一个overflow: hidden属性,使超出盒子部分的列表暂时隐藏掉,后面会通过js去实现滑动。
/* 样式初始化 */ * { margin: 0; padding: 0; } html, body { width: 100%; } aside { height: 100%; width: 100%; } /* 列表的父盒子,限制宽高 */ /* 注意设置overflow: hidden;样式后,超出这个盒子的ul将不会显示 */ .draw { width: 60px; height: 500px; border: 2px solid #ccc; overflow: hidden; position: fixed; left: 10px; top: 50%; transform: translateY(-50%); } /* li 设置了浮动, 所以 ul 要清除浮动 */ ul:after { content: ""; display: block; visibility: hidden; height: 0; clear: both; } ul { zoom: 1; } li { list-style: none; float: left; width: 60px; height: 60px; line-height: 60px; text-align: center; }
效果图:
3. 首次滑动
手指触摸到列表向下滑动的时候,列表应该跟着向下滑动,当手指离开屏幕的时候,列表应该停在滑动的位置。这里就会用到上面准备阶段的知识点了,不明白的可以参考上面的概念。实现原理:
1、touchstart的时候,获取手指触摸的落点A,通过这个点对象里面的clientY属性,获取距离顶部可视区的距离;
2、touchmove的时候,获取手指的点B,同样的获取移动时距离顶部可视区的距离;
3、touchmove的时候,还要做另一件事情,就是获取两点的差值(B.clientY-A.clientY),将这个差值动态赋值给ul,ul只需要设置向Y轴方向偏移这个距离,就能实现列表随手指滑动
先来张示意图,怎么通过 js 让列表滑动起来:
示例代码:
var draw = document.querySelector('#draw'); var ul = draw.children[0]; // touchstart 时,记录手指在 Y 轴上的落点距离可视顶部距离 var startY = 0 ul.addEventListener('touchstart', function (e) { startY = e.changedTouches[0].clientY; }) // touchmove 时,记录此时手指在 Y 轴上的落点距离可视顶部距离 ul.addEventListener('touchmove', function (e) { // 获取差值 var dy = e.changedTouches[0].clientY - startY; // 设置 ul 在 Y 轴上的偏移 ul.style.transform = 'translateY(' + dy + 'px)'; })
效果图:
4. 再次滑动
上面的效果图,细心的朋友可能已经发现了问题,在第一次的时候,得到了我们想要的效果,但是在第二次的时候,我们继续向下移动了一段距离,但是ul并没有接着第一次的位置继续向下,而是瞬间跳了上去。问题分析:
虽然第二次是继续向下移动了一段距离,但是触摸结束后,最终是将此时的差值,重新赋值给了ul的Y轴偏移,所以视觉上“跳了上去”。解决方法:
每一次滑动结束之后,都应该记录下此次滑动的距离,与之前的进行累加,待下一次滑动的时候,ul在Y轴的偏移值应该是之前的距离加上本次滑动的距离。新增touchend事件,在该事件里同样的可以获取到本次滑动的距离,将它与上一次的距离相加,赋值给一个全局变量;
在touchmove事件里有点小改动,就是在给ul设置偏移值的时候,除了本次滑动的差值还要加上这个上一次的值;
示意图:
示例代码:
var draw = document.querySelector('#draw'); var ul = draw.children[0]; var startY = 0 // 刚触碰到屏幕的时的手指信息 var centerY = 0 // 用来记录每次触摸时上一次的偏移距离 // touchstart 时,记录手指在 Y 轴上的落点距离可视顶部距离 ul.addEventListener('touchstart', function (e) { startY = e.changedTouches[0].clientY; }) // touchmove 时,记录此时手指在 Y 轴上的落点距离可视顶部距离 ul.addEventListener('touchmove', function (e) { // 获取差值 var dy = e.changedTouches[0].clientY - startY; // 上次的滑动距离加上本次的滑动距离 var tempY = centerY + dy; // 设置 ul 在 Y 轴上的偏移 ul.style.transform = 'translateY(' + tempY + 'px)'; }) // touchend 时,记录此时手指在 Y 轴上的落点距离可视顶部距离 ul.addEventListener('touchend', function (e) { // 获取差值 var dy = e.changedTouches[0].clientY - startY; // 记录移动的距离 centerY = centerY + dy; })
效果图:
5. 限制滑动区间
到上面一步,我们已经可以实现列表的滑动了,但是也存在一个问题,就是向上或者向下的时候没有限制,上下可以无限的滑动,甚至再用点力,就看不到列表了。为了美观和实用,这样肯定不行的,需要给它设定一个区间,设定向上或者向下最多只能留白多少。
限制向下滑动最大区间:
设定向下最大区间的值比较简单,直接设定一个值,当上一次滑动的距离加上本次滑动的距离大于这个值的时候,就不让它再继续往下滑了,让他直接等于这个设定的值。
示例代码:
var maxDown = 50; // 设定一个最大向下滑动的距离 // touchmove 时,记录此时手指在 Y 轴上的落点距离可视顶部距离 ul.addEventListener('touchmove', function (e) { // 获取差值 var dy = e.changedTouches[0].clientY - startY; // 上次的滑动距离加上本次的滑动距离 var tempY = centerY + dy; // 当上次滑动的距离加上本次滑动的距离 大于 设定的最大向下距离的时候 if (tempY > maxDown) { // 直接让偏移的值 等于这个设定值 tempY = maxDown; } // 设置 ul 在 Y 轴上的偏移 ul.style.transform = 'translateY(' + tempY + 'px)'; })
限制向上滑动最大区间:
向上滑动时,当ul
的底部距盒子底部的距离大于设定值的时候,不让其继续向上滑动,关键是这个值怎么去判断?
求出向上滑动最大值:
注意:因为ul
是向上滑动的,所以求得的距离前面要加上一个负号(-
)
示例代码:
// 设定一个最大向下滑动的距离 var maxDown = 50; // 求得一个最大向上滑动的距离 var maxUp = -(ul.offsetHeight - draw.offsetHeight + maxDown); // touchmove 时,记录此时手指在 Y 轴上的落点距离可视顶部距离 ul.addEventListener('touchmove', function (e) { // 获取差值 var dy = e.changedTouches[0].clientY - startY; // 上次的滑动距离加上本次的滑动距离 var tempY = centerY + dy; // 当上次滑动的距离加上本次滑动的距离 大于 设定的最大向下距离的时候 if (tempY > maxDown) { tempY = maxDown; } // 当上次滑动的距离加上本次滑动的距离 小于 设定的最大向上距离的时候 else if (tempY <p><strong>效果图:</strong></p><p><span class="img-wrap"><img src="/static/imghwm/default1.png" data-src="https://img.php.cn//upload/image/937/124/609/1547174327646668.gif?x-oss-process=image/resize,p_40" class="lazy" title="1547174327646668.gif" alt="原生js實作行動端Touch滑動反彈的方法(程式碼範例)"></span></p><p><em>认真观察上图,虽然成功的设置了最大滑动区间,但是你有没有发现,一直往一个方向滑动的时候,虽然列表不会继续往下滑动,但是接着往相反方向滑动的时候,感觉列表滑不动,需要滑一段距离后,列表才会跟着走,这是为什么呢?因为滑动的过程<code>centerY</code>是一直变的,列表虽然视觉上不动了,但是在<code>touchend</code>事件的时候,它的<code>centerY</code>值一直在累加。解决方法请往下看:</em></p><h3 id="设定反弹区间">6. 设定反弹区间</h3><blockquote>“滑动反弹”,这里的反弹是本篇文章的最后一步,上面说到的问题,就在这里解决。因为每一次触发<code>touchend</code>事件的时候,<code>centerY</code>值就累加一次,所以需要在<code>touchend</code>事件里做判断。我们设定一个反弹区间,就是当<code>centerY</code>的值大于或者小于某个值的时候,让它触发反弹。</blockquote><p><strong>设定向上反弹值:</strong></p><blockquote>向上的值比较简单,设置成“<code>0</code>”。为什么是“<code>0</code>”呢?我们限定只要手指离开时,上一次的滑动距离加上本次的距离<code>> 0</code>的时候,就让它触发反弹,并且反弹回<code>0</code>点的位置,也就是两次滑动的距离和<code>= 0</code>。</blockquote><p><span class="img-wrap"><img src="/static/imghwm/default1.png" data-src="https://img.php.cn//upload/image/328/173/328/1547174343276403.jpg?x-oss-process=image/resize,p_40" class="lazy" title="1547174343276403.jpg" alt="原生js實作行動端Touch滑動反彈的方法(程式碼範例)"></span></p><p><strong><em>示例代码:</em></strong></p><pre class="brush:php;toolbar:false">// 向上反弹 var maxUpBounce = 0; // touchend 时,记录此时手指在 Y 轴上的落点距离可视顶部距离 ul.addEventListener('touchend', function (e) { // 获取差值 var dy = e.changedTouches[0].clientY - startY; // 记录移动的距离 centerY = centerY + dy; // 两次滑动的距离 大于 设定的 向上 反弹值时 if (centerY > maxUpBounce) { // 让两次滑动的距离 等于 设置的值 centerY = maxUpBounce; // 添加过渡 ul.style.transition = 'transform .5s'; ul.style.transform = 'translateY(' + centerY + 'px)'; } })
设定向下反弹值:
向下的值其实跟之前求滑动区间差不多,我们参考下图,当列表向上滑动,滑动到列表底部的时候,只要此时再向上滑动,就让它向下反弹。向下反弹值就是-(ul.offsetHeight - draw.offsetHeight)
,只要滑动的差值小于这个设定值,就让它向下反弹,并且反弹回设定值的位置。
示例代码:
// 向上反弹值 var maxUpBounce = 0; // 向下反弹值 var maxDownBounce = -(ul.offsetHeight - draw.offsetHeight); // touchend 时,记录此时手指在 Y 轴上的落点距离可视顶部距离 ul.addEventListener('touchend', function (e) { // 获取差值 var dy = e.changedTouches[0].clientY - startY; // 记录移动的距离 centerY = centerY + dy; // 两次滑动的距离 大于 设定的 向上 反弹值时 if (centerY > maxUpBounce) { // 让两次滑动的距离 等于 设置的值 centerY = maxUpBounce; // 添加过渡 ul.style.transition = 'transform .5s'; ul.style.transform = 'translateY(' + centerY + 'px)'; } // 两次滑动的距离 小于 设定的 向下 反弹值时 else if (centerY注意: 在
touchend
事件的时候,给列表添加了transition
属性才会有反弹的效果,但是,下一次滑动的时候,touchmove
事件的时候,这个属性还存在,所以就会出现滑动的时候有顿挫感,所以在touchmove
事件的时候,一进来就清一下过渡ul.style.transition = 'none';
。完成后效果图:
7. 完整代码
nbsp;html>移动端 Touch 滑动反弹 <aside> <div> <ul> <li>列表一</li> <li>列表二</li> <li>列表三</li> <li>列表四</li> <li>列表五</li> <li>列表六</li> <li>列表七</li> <li>列表八</li> <li>列表九</li> <li>列表十</li> </ul> </div> </aside> <script> var draw = document.querySelector('#draw'); var ul = draw.children[0]; var startY = 0; // 刚触碰到屏幕的时的手指信息 var centerY = 0; // 用来记录每次触摸时上一次的偏移距离 var maxDown = 50; // 设定一个最大向下滑动的距离 var maxUp = -(ul.offsetHeight - draw.offsetHeight + maxDown); // 求得一个最大向上滑动的距离 var maxUpBounce = 0; // 向上反弹值 var maxDownBounce = -(ul.offsetHeight - draw.offsetHeight); // 向下反弹值 // touchstart 时,记录手指在 Y 轴上的落点距离可视顶部距离 ul.addEventListener('touchstart', function (e) { startY = e.changedTouches[0].clientY; }) // touchmove 时,记录此时手指在 Y 轴上的落点距离可视顶部距离 ul.addEventListener('touchmove', function (e) { // 清除过渡 ul.style.transition = 'none'; // 获取差值 var dy = e.changedTouches[0].clientY - startY; // 上次的滑动距离加上本次的滑动距离 var tempY = centerY + dy; // 当上次滑动的距离加上本次滑动的距离 大于 设定的最大向下距离的时候 if (tempY > maxDown) { tempY = maxDown; } // 当上次滑动的距离加上本次滑动的距离 小于 设定的最大向上距离的时候 else if (tempY < maxUp) { tempY = maxUp; } // 设置 ul 在 Y 轴上的偏移 ul.style.transform = 'translateY(' + tempY + 'px)'; }) // touchend 时,记录此时手指在 Y 轴上的落点距离可视顶部距离 ul.addEventListener('touchend', function (e) { // 获取差值 var dy = e.changedTouches[0].clientY - startY; // 记录移动的距离 centerY = centerY + dy; // 两次滑动的距离 大于 设定的 向上 反弹值时 if (centerY > maxUpBounce) { // 让两次滑动的距离 等于 设置的值 centerY = maxUpBounce; // 添加过渡 ul.style.transition = 'transform .5s'; ul.style.transform = 'translateY(' + centerY + 'px)'; } // 两次滑动的距离 小于 设定的 向下 反弹值时 else if (centerY < maxDownBounce) { // 让两次滑动的距离 等于 设置的值 centerY = maxDownBounce; // 添加过渡 ul.style.transition = 'transform .5s'; ul.style.transform = 'translateY(' + centerY + 'px)'; } }) </script>
以上是原生js實作行動端Touch滑動反彈的方法(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Atom編輯器mac版下載
最受歡迎的的開源編輯器

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Dreamweaver CS6
視覺化網頁開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。