移动端ios阻止橡皮筋效果

问题由来

  • 在移动端开发中,像 ios 的微信浏览器、Safari 浏览器等,在网页进行滑动的时候会出现橡皮筋效果

  • 橡皮筋效果: 当页面拉到尽头时还能继续拉动,露出浏览器的底色,松手会回弹回去

  • 这样的效果一般只会出现在 ios 中,安卓倒没有这个问题

解决办法

  • 首先想到的是 event.preventDefault() 阻止滑动的默认行为,但如果直接添加到页面上,整个页面就不会滚动了
  • 那么只有达到临界值时,再阻止事件默认行为即可,于是只需判断页面是否滚动到了顶端和底部

原生写法:

javascript 复制代码
 (function () {
   if (terminal() !== "ios") return;
   let startY, endY;
   window.addEventListener("touchstart", function (e) {
     startY = e.touches[0].pageY;
   }, { passive: false })
 ​
   window.addEventListener("touchmove", function (e) {
     endY = e.touches[0].pageY; // 记录手指触摸的移动中的坐标
     // 判断是否为向上滑行为,并且页面已经到达顶端
     const isCanUpslide = endY > startY && this.scrollY <= 0; 
     // 判断是否为向下滑行为,并且页面已经到达底部
     const isCanDownslide =
       endY < startY && this.scrollY + this.innerHeight >= document.body.scrollHeight;
     // 手指滑动页面,到达两端都不能继续滑动
     if ((isCanDownslide || isCanUpslide) && e.cancelable) e.preventDefault();
   }, { passive: false });
 })();

Jquery 写法:

javascript 复制代码
 // 使用 $.event.special 对象创建一个带有 passive 选项的自定义事件
 $.event.special.touchmove = {
   setup(_, ns, handle) {
     this.addEventListener('touchmove', handle, { passive: false });
   }
 };
 ​
 (function () {
   if (terminal() !== "ios") return;
   let startY, endY;
   $(window)
     .on("touchstart", function (e) {
       startY = e.originalEvent.touches[0].pageY;
     })
     .on("touchmove", function (e) {
       // e.preventDefault && e.preventDefault()
       endY = e.originalEvent.touches[0].pageY; // 记录手指触摸的移动中的坐标
       // 判断是否为向上滑行为,并且页面已经到达顶端
       const isCanUpslide = endY > startY && $(this).scrollTop() <= 0;
       // 判断是否为向下滑行为,并且页面已经到达底部
       const isCanDownslide =
       endY < startY && $(this).scrollTop() + $(this).height() >= $('body')[0].scrollHeight;
       if ((isCanDownslide || isCanUpslide) && e.cancelable) e.preventDefault();
     });
 })();

为什么需要判断上下滑动行为?

  • 当到达页面底部或顶部时,如果不判断滑动方向,此时无论做什么方向的滑动都会被阻止默认行为,这就造成页面不能滑动
  • 也就是说不判断上下滑动方向,和直接阻止默认行为没有什么区别

注意:需要找准自己的滚动对象,不一定是 windowbody

判断设备方法

  • 通过 navigator.userAgen 可以判断当前是不是 ios
javascript 复制代码
 function terminal() {
   var u = navigator.userAgent;
   let osType;
   if ((u && u.indexOf("Android") > -1) || u.indexOf("Linux") > -1) {
     osType = "Android";
   }
   if (u && !!u.match(/(i[^;]+;( U;)? CPU.+Mac OS X/)) {
     osType = "ios";
   }
   return osType;
 }
相关推荐
Lysun0011 小时前
dispaly: inline-flex 和 display: flex 的区别
前端·javascript·css
山禾女鬼0011 小时前
Vue 3 自定义指令
前端·javascript·vue.js
啊卡无敌1 小时前
Vue 3 reactive 和 ref 区别及 失去响应性问题
前端·javascript·vue.js
涵信2 小时前
第九节:React HooksReact 18+新特性-React 19的use钩子如何简化异步操作?
前端·javascript·react.js
百锦再2 小时前
Android Studio 项目文件夹结构详解
android·java·ide·ios·app·android studio·idea
我是仙女你信不信2 小时前
生成pdf并下载
前端·javascript·vue.js
vvilkim3 小时前
React 组件类型详解:类组件 vs. 函数组件
前端·javascript·react.js
啊吧啊吧曾小白3 小时前
作用域、闭包与this指向问题
前端·javascript·面试
HiF3 小时前
Hexo博客集成LivePhoto
javascript
八了个戒3 小时前
「数据可视化 D3系列」入门第七章:坐标轴的使用
前端·javascript·数据可视化·canvas·d3