如何实现滑动翻页效果并解决移动端click事件问题?

2026-04-01 16:062阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2061个文字,预计阅读时间需要9分钟。

如何实现滑动翻页效果并解决移动端click事件问题?

前言:本文简要概述了一个问题,主要内容是关于移动端click事件和js事件机制导致的困扰。

摘要:主要讨论了由于移动端click事件和js事件机制引起的困扰,并总结了相关解决方案。

问题:近期制作了一个小活动,其中涉及到移动端的click事件和js事件机制。在实际开发过程中,发现点击事件有时会出现延迟响应或无法触发的问题,给用户体验带来不便。以下是具体问题和解决方案。

问题分析:

1.移动端click事件存在300ms延迟,导致用户体验不佳。

2.js事件机制中,事件冒泡和捕获顺序可能导致click事件无法正常触发。

解决方案:

1.使用fastclick库解决click事件延迟问题。

2.优化事件绑定方式,确保click事件能够正常触发。

具体实现:

1.引入fastclick库,并在页面加载完成后绑定到需要点击的元素上。

2.优化事件绑定,使用addEventListener添加事件监听器,确保事件能够正常触发。

总结:

通过以上方法,成功解决了移动端click事件和js事件机制导致的困扰,提高了用户体验。在实际开发过程中,要注意事件绑定和优化,以确保功能的稳定性和可靠性。

前述

本文很短~
主要是为了总结和讲述移动端click和js事件机制导致的一个问题。
(:咳咳,其实几句话就能写完的还要水一篇文章,不愧是我…


正文

最近做了一个小活动,里面要用到一个效果:滑动翻页。大概是这样的:

<!-- HTML代码 --> <div class="page-container"> <div class="page" style="background: #dc3b26">1</div> <div class="page" style="background: #f3b03d">2</div> <div class="page" style="background: #44a2f8">3</div> </div>

在css中,首先因为是滑动翻页,所以我们要保证“始终只有一屏”,这个可以放在全局样式表里控制,然后是其中的“每一页”都要占满父元素 —— 这里其实用了“div是块元素,无外力情况下竖直排列”的特性。

/** css样式 */ html, body{ margin: 0; padding: 0; width: 100%; height: 100vh; overflow: hidden; font-size: 60px; } .page-container{ width: 100%; height: 100%; } .page-container .page{ width: 100%; height: 100%; }

其JS实现也很简单:因为在移动端,所以使用了touchstarttouchmovetouchend事件来实现手势滑动功能:

  • start(刚按下)时记录此时的手指位置——作为初始值;
  • 在move(触摸滑动)时根据实时的手指位置和初始手指位置变量实现要求判断,在本文场景为代表的场景下这一步一般还要求出“移动距离”实时赋值;
  • 在end(手指离开)时(也有直接在move时进行的)进行收尾工作——比如:图片滑动完全划过去、元素跑到结束位置、将事件监听取消;

// 这里是控制全局js的文件 // 全局阻止浏览器默认行为 document.addEventListener("touchstart",function(e){ if(e.cancelable){ e.preventDefault(); } },{passive: false}) // {passive: false}就是告诉前面可能有需要重置行为的代码 document.addEventListener("touchmove",function(e){ if(e.cancelable){ e.preventDefault(); } },{passive: false})

// JavaScript代码 let curPageIndex=0; let pageContainer=document.querySelector(".page-container"); let pageNumber=pageContainer.children.length; //页面的数量 // 文档的视窗高度(这里就是一屏的高度) let cHeight=document.documentElement.clientHeight; // 设置页面容器的margin-top为合适的值,让其显示在视野中 function toPage(){ pageContainer.style.transition="all .5s ease"; pageContainer.style.marginTop=-curPageIndex*cHeight+"px"; // 变化完成后去掉过渡效果 ! pageContainer.addEventListener("transitionend",function(){ pageContainer.style.transition="none"; },{once:true}) } toPage() pageContainer.ontouchstart=function(e){ let y=e.changedTouches[0].clientY; //手指按下的纵坐标 pageContainer.ontouchmove=function(e){ let dis=e.changedTouches[0].clientY-y; //计算距离 // 计算page-container的margin-top let mtop=-curPageIndex*cHeight+dis if(mtop>0){ mtop=0; }else if(mtop<-(pageNumber-1)*cHeight){ mtop=-(pageNumber-1)*cHeight; } // 实时改变位置 pageContainer.style.marginTop=mtop+"px"; } pageContainer.ontouchend=function(e){ let dis=e.changedTouches[0].clientY-y; // 如果滑动距离实在太短,就回到滑动前的位置状态 if(Math.abs(dis)<=60){ toPage() }else if(dis>0 && curPageIndex>0){ curPageIndex--; toPage() }else if(dis<0 && curPageIndex<pageNumber-1){ curPageIndex++; toPage() } // 手指离开后,取消监听事件 pageContainer.ontouchmove=null; pageContainer.ontouchend=null; } }


至此,功能上似乎很完美。但这时候,我们在第一个page里添加一个button:

<div class="page" style="background: #dc3b26"> <button onclick="alert('哈哈哈')" class="but">click me!</button> 1 </div>

然后到页面上查看效果:

无效!

这是因为在上方全局js文件里我们加了“阻止浏览器默认事件”的代码。
——在移动端浏览器中,click事件和mousestart事件是同时被触发的。因为移动端浏览器是没有click事件的,它是由mouse事件模拟的! :也正是这个原因,才有了所谓的“移动端浏览器300ms延迟”的问题 1 。
——还有就是,在微信自带的浏览器中,有一个“触顶下拉回弹”的操作,这其实是不应该的。它也属于浏览器默认事件。
所以一般我们需要禁止掉这些东西。

但是如上面所示,全部禁止掉总会造成一些困扰,怎么办?
H5提供了“自定义属性”,针对本文方法,我们完全可以 —— 在全局事件里检测当前触发的元素有没有某一个自定义属性,如果有,就什么也不拦截;否则就执行禁止默认行为的代码:
比如

<button data-default="true" onclick="alert('哈哈哈')" class="but">click me!</button>

将上面“控制全局js的文件”内容改为如下:

如何实现滑动翻页效果并解决移动端click事件问题?

// 全局阻止浏览器默认行为 document.addEventListener("touchstart",function(e){ if(e.target.dataset.default){ return; } if(e.cancelable){ e.preventDefault(); } },{passive: false}) document.addEventListener("touchmove",function(e){ if(e.target.dataset.default){ return; } if(e.cancelable){ e.preventDefault(); } },{passive: false})

就OK了:


其实还有另一种“解法”:既然上面说了,移动端click实际上是通过mouse事件模拟的,那么我们可以从mousestart事件入手;又因为button元素是“第一个页面”内的(子)元素,所以可以用阻止事件冒泡

<!-- button就是普通的button --> <button class="but">click me!</button>

document.querySelector(".but").addEventListener("touchstart",function(e){ e.stopPropagation(); alert('噶哈哈'); },false)

关于捕获和冒泡→

我们首先要知道的是:当我们鼠标按下一个按钮时,并不是“点击了一个按钮”,而是在这个区域内,鼠标(上的按键)被按下,操作系统和浏览器把这个信息对应到了“按钮”所在区域并触发其逻辑。
事实上鼠标点击并没有位置信息,是操作系统一直在监听鼠标移动,根据累积的位移计算出来的坐标,将其传给浏览器。
那么,把这个坐标转换为具体的元素上的事件的过程,就可称作“捕获”。那“冒泡”呢?这个不好解释,但有一点想必你是明白的:当你按下电视开关时,你也按到了电视!
这就是很多文章会讲到的“冒泡过程由内向外,捕获过程由外向内”,或者说是“洋葱模型”。
还有一点就是:事件addEventListener的第三个参数 true/false ,即为“是捕获/冒泡”。(别多想,这只是浏览器提供的事件模型之一。无论是否监听,在一个事件发生时,捕获和冒泡总是先后发生的)

到此这篇关于滑动翻页效果实现和移动端click事件问题的文章就介绍到这了,更多相关滑动翻页效果内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!

本文共计2061个文字,预计阅读时间需要9分钟。

如何实现滑动翻页效果并解决移动端click事件问题?

前言:本文简要概述了一个问题,主要内容是关于移动端click事件和js事件机制导致的困扰。

摘要:主要讨论了由于移动端click事件和js事件机制引起的困扰,并总结了相关解决方案。

问题:近期制作了一个小活动,其中涉及到移动端的click事件和js事件机制。在实际开发过程中,发现点击事件有时会出现延迟响应或无法触发的问题,给用户体验带来不便。以下是具体问题和解决方案。

问题分析:

1.移动端click事件存在300ms延迟,导致用户体验不佳。

2.js事件机制中,事件冒泡和捕获顺序可能导致click事件无法正常触发。

解决方案:

1.使用fastclick库解决click事件延迟问题。

2.优化事件绑定方式,确保click事件能够正常触发。

具体实现:

1.引入fastclick库,并在页面加载完成后绑定到需要点击的元素上。

2.优化事件绑定,使用addEventListener添加事件监听器,确保事件能够正常触发。

总结:

通过以上方法,成功解决了移动端click事件和js事件机制导致的困扰,提高了用户体验。在实际开发过程中,要注意事件绑定和优化,以确保功能的稳定性和可靠性。

前述

本文很短~
主要是为了总结和讲述移动端click和js事件机制导致的一个问题。
(:咳咳,其实几句话就能写完的还要水一篇文章,不愧是我…


正文

最近做了一个小活动,里面要用到一个效果:滑动翻页。大概是这样的:

<!-- HTML代码 --> <div class="page-container"> <div class="page" style="background: #dc3b26">1</div> <div class="page" style="background: #f3b03d">2</div> <div class="page" style="background: #44a2f8">3</div> </div>

在css中,首先因为是滑动翻页,所以我们要保证“始终只有一屏”,这个可以放在全局样式表里控制,然后是其中的“每一页”都要占满父元素 —— 这里其实用了“div是块元素,无外力情况下竖直排列”的特性。

/** css样式 */ html, body{ margin: 0; padding: 0; width: 100%; height: 100vh; overflow: hidden; font-size: 60px; } .page-container{ width: 100%; height: 100%; } .page-container .page{ width: 100%; height: 100%; }

其JS实现也很简单:因为在移动端,所以使用了touchstarttouchmovetouchend事件来实现手势滑动功能:

  • start(刚按下)时记录此时的手指位置——作为初始值;
  • 在move(触摸滑动)时根据实时的手指位置和初始手指位置变量实现要求判断,在本文场景为代表的场景下这一步一般还要求出“移动距离”实时赋值;
  • 在end(手指离开)时(也有直接在move时进行的)进行收尾工作——比如:图片滑动完全划过去、元素跑到结束位置、将事件监听取消;

// 这里是控制全局js的文件 // 全局阻止浏览器默认行为 document.addEventListener("touchstart",function(e){ if(e.cancelable){ e.preventDefault(); } },{passive: false}) // {passive: false}就是告诉前面可能有需要重置行为的代码 document.addEventListener("touchmove",function(e){ if(e.cancelable){ e.preventDefault(); } },{passive: false})

// JavaScript代码 let curPageIndex=0; let pageContainer=document.querySelector(".page-container"); let pageNumber=pageContainer.children.length; //页面的数量 // 文档的视窗高度(这里就是一屏的高度) let cHeight=document.documentElement.clientHeight; // 设置页面容器的margin-top为合适的值,让其显示在视野中 function toPage(){ pageContainer.style.transition="all .5s ease"; pageContainer.style.marginTop=-curPageIndex*cHeight+"px"; // 变化完成后去掉过渡效果 ! pageContainer.addEventListener("transitionend",function(){ pageContainer.style.transition="none"; },{once:true}) } toPage() pageContainer.ontouchstart=function(e){ let y=e.changedTouches[0].clientY; //手指按下的纵坐标 pageContainer.ontouchmove=function(e){ let dis=e.changedTouches[0].clientY-y; //计算距离 // 计算page-container的margin-top let mtop=-curPageIndex*cHeight+dis if(mtop>0){ mtop=0; }else if(mtop<-(pageNumber-1)*cHeight){ mtop=-(pageNumber-1)*cHeight; } // 实时改变位置 pageContainer.style.marginTop=mtop+"px"; } pageContainer.ontouchend=function(e){ let dis=e.changedTouches[0].clientY-y; // 如果滑动距离实在太短,就回到滑动前的位置状态 if(Math.abs(dis)<=60){ toPage() }else if(dis>0 && curPageIndex>0){ curPageIndex--; toPage() }else if(dis<0 && curPageIndex<pageNumber-1){ curPageIndex++; toPage() } // 手指离开后,取消监听事件 pageContainer.ontouchmove=null; pageContainer.ontouchend=null; } }


至此,功能上似乎很完美。但这时候,我们在第一个page里添加一个button:

<div class="page" style="background: #dc3b26"> <button onclick="alert('哈哈哈')" class="but">click me!</button> 1 </div>

然后到页面上查看效果:

无效!

这是因为在上方全局js文件里我们加了“阻止浏览器默认事件”的代码。
——在移动端浏览器中,click事件和mousestart事件是同时被触发的。因为移动端浏览器是没有click事件的,它是由mouse事件模拟的! :也正是这个原因,才有了所谓的“移动端浏览器300ms延迟”的问题 1 。
——还有就是,在微信自带的浏览器中,有一个“触顶下拉回弹”的操作,这其实是不应该的。它也属于浏览器默认事件。
所以一般我们需要禁止掉这些东西。

但是如上面所示,全部禁止掉总会造成一些困扰,怎么办?
H5提供了“自定义属性”,针对本文方法,我们完全可以 —— 在全局事件里检测当前触发的元素有没有某一个自定义属性,如果有,就什么也不拦截;否则就执行禁止默认行为的代码:
比如

<button data-default="true" onclick="alert('哈哈哈')" class="but">click me!</button>

将上面“控制全局js的文件”内容改为如下:

如何实现滑动翻页效果并解决移动端click事件问题?

// 全局阻止浏览器默认行为 document.addEventListener("touchstart",function(e){ if(e.target.dataset.default){ return; } if(e.cancelable){ e.preventDefault(); } },{passive: false}) document.addEventListener("touchmove",function(e){ if(e.target.dataset.default){ return; } if(e.cancelable){ e.preventDefault(); } },{passive: false})

就OK了:


其实还有另一种“解法”:既然上面说了,移动端click实际上是通过mouse事件模拟的,那么我们可以从mousestart事件入手;又因为button元素是“第一个页面”内的(子)元素,所以可以用阻止事件冒泡

<!-- button就是普通的button --> <button class="but">click me!</button>

document.querySelector(".but").addEventListener("touchstart",function(e){ e.stopPropagation(); alert('噶哈哈'); },false)

关于捕获和冒泡→

我们首先要知道的是:当我们鼠标按下一个按钮时,并不是“点击了一个按钮”,而是在这个区域内,鼠标(上的按键)被按下,操作系统和浏览器把这个信息对应到了“按钮”所在区域并触发其逻辑。
事实上鼠标点击并没有位置信息,是操作系统一直在监听鼠标移动,根据累积的位移计算出来的坐标,将其传给浏览器。
那么,把这个坐标转换为具体的元素上的事件的过程,就可称作“捕获”。那“冒泡”呢?这个不好解释,但有一点想必你是明白的:当你按下电视开关时,你也按到了电视!
这就是很多文章会讲到的“冒泡过程由内向外,捕获过程由外向内”,或者说是“洋葱模型”。
还有一点就是:事件addEventListener的第三个参数 true/false ,即为“是捕获/冒泡”。(别多想,这只是浏览器提供的事件模型之一。无论是否监听,在一个事件发生时,捕获和冒泡总是先后发生的)

到此这篇关于滑动翻页效果实现和移动端click事件问题的文章就介绍到这了,更多相关滑动翻页效果内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!