移动端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;
 }
相关推荐
她似晚风般温柔7894 小时前
Uniapp + Vue3 + Vite +Uview + Pinia 分商家实现购物车功能(最新附源码保姆级)
开发语言·javascript·uni-app
Jiaberrr5 小时前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
everyStudy5 小时前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
Ylucius6 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
200不是二百6 小时前
Vuex详解
前端·javascript·vue.js
LvManBa6 小时前
Vue学习记录之三(ref全家桶)
javascript·vue.js·学习
键盘敲没电6 小时前
【iOS】KVC
ios·objective-c·xcode
吾吾伊伊,野鸭惊啼6 小时前
2024最新!!!iOS高级面试题,全!(二)
ios
吾吾伊伊,野鸭惊啼6 小时前
2024最新!!!iOS高级面试题,全!(一)
ios
深情废杨杨6 小时前
前端vue-父传子
前端·javascript·vue.js