이 글의 내용은 모바일 단말에서 터치 슬라이딩 리바운드를 구현하기 위한 네이티브 js의 방법(코드 예제)에 관한 것입니다. 필요한 친구들이 참고할 수 있기를 바랍니다. 당신에게 도움이 될 것입니다.
모바일 터치 슬라이드 리바운드
터치 슬라이드란 무엇인가요? PC측의 스크롤 이벤트와 유사하지만, 모바일측에서는 스크롤 이벤트가 없으므로 js와 결합된 Touch 이벤트를 이용하여 구현해야 합니다.# 🎜🎜## 🎜🎜#
1. 준비모바일측 터치이벤트란? 모바일 측의 터치 이벤트는 touchstart, touchmove, touchend 3가지로 세분화할 수 있으며, 터치 이벤트는 addEventListener로 모니터링해야 합니다. 손가락이 화면을 터치하면 touchStart가 실행됩니다
손가락이 화면에서 계속 움직일 때 touchmove가 실행됩니다
손가락이 화면에서 벗어날 때 touchend가 실행됩니다# ###### 🎜🎜#Touch 이벤트 이벤트 객체:
🎜🎜#r#🎜🎜 ## 🎜🎜 ## 🎜🎜 ## 🎜🎜 ## 🎜🎜 #changedTouches, targetTouches 및 touches는 모두 손가락 목록을 포함하는 의사 배열세 가지 유형의 반환된 개체 간의 차이점: 사실, 이 세 가지 반환된 개체 개체는 모두 사용자의 터치 이벤트에 대한 손가락 정보를 의사 배열로 하는 이유는 여러 손가락이 동시에 터치하는 것이 가능하기 때문입니다. 그러나 실제 작업에서는 일반적으로 여러 손가락의 상황을 고려하지 않습니다. 이들 간의 유일한 차이점은 touchstart 및 touchmove 이벤트 중에 selectedTouches, targetTouches 및 touches가 모두 손가락 정보를 얻을 수 있다는 것입니다. 그러나 touchend 이벤트 중에 targetTouches 및 touches 객체는 화면을 떠날 때 손가락 정보를 반환할 수 없습니다. 개체를 반환할 수 있습니다.
어떤 손가락 정보가 있나요? 위 그림을 보면changedTouche[0]에서 일부 값은 다음과 같습니다. // 手指触碰到屏幕时触发
element.addEventListener('touchstart', function (e) {
// 打印的事件对象
console.log(e);
})
HTML部分: css部分: 在列表的父盒子上设定一个overflow: hidden属性,使超出盒子部分的列表暂时隐藏掉,后面会通过js去实现滑动。 效果图:
3. 首次滑动 实现原理: 1、touchstart的时候,获取手指触摸的落点A,通过这个点对象里面的clientY属性,获取距离顶部可视区的距离; 2、touchmove的时候,获取手指的点B,同样的获取移动时距离顶部可视区的距离; 3、touchmove的时候,还要做另一件事情,就是获取两点的差值(B.clientY-A.clientY),将这个差值动态赋值给ul,ul只需要设置向Y轴方向偏移这个距离,就能实现列表随手指滑动 先来张示意图,怎么通过 js 让列表滑动起来:
示例代码: 效果图:
4. 再次滑动 问题分析:
解决方法: 新增touchend事件,在该事件里同样的可以获取到本次滑动的距离,将它与上一次的距离相加,赋值给一个全局变量; 在touchmove事件里有点小改动,就是在给ul设置偏移值的时候,除了本次滑动的差值还要加上这个上一次的值; 示意图:
示例代码: 效果图:
到上面一步,我们已经可以实现列表的滑动了,但是也存在一个问题,就是向上或者向下的时候没有限制,上下可以无限的滑动,甚至再用点力,就看不到列表了。为了美观和实用,这样肯定不行的,需要给它设定一个区间,设定向上或者向下最多只能留白多少。
限制向下滑动最大区间: 示例代码: 限制向上滑动最大区间:
求出向上滑动最大值:
注意:因为 示例代码: 设定向下反弹值: 示例代码: 注意: 在 完成后效果图:<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>
/* 样式初始化 */
* {
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;
}
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)';
})
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="https://img.php.cn//upload/image/937/124/609/1547174327646668.gif" title="1547174327646668.gif" alt="Native JS를 이용하여 모바일 단말에서 터치 슬라이딩 리바운드를 구현하는 방법(코드 예시)"></span></p><p><em>认真观察上图,虽然成功的设置了最大滑动区间,但是你有没有发现,一直往一个方向滑动的时候,虽然列表不会继续往下滑动,但是接着往相反方向滑动的时候,感觉列表滑不动,需要滑一段距离后,列表才会跟着走,这是为什么呢?因为滑动的过程<code>centerY</code>是一直变的,列表虽然视觉上不动了,但是在<code>touchend</code>事件的时候,它的<code>centerY</code>值一直在累加。解决方法请往下看:</em></p><h3>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="https://img.php.cn//upload/image/328/173/328/1547174343276403.jpg" title="1547174343276403.jpg" alt="Native JS를 이용하여 모바일 단말에서 터치 슬라이딩 리바운드를 구현하는 방법(코드 예시)"></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>
위 내용은 Native JS를 이용하여 모바일 단말에서 터치 슬라이딩 리바운드를 구현하는 방법(코드 예시)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!