移动端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();
     });
 })();

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

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

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

判断设备方法

  • 通过 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;
 }
相关推荐
admin and root4 小时前
「AI安全篇」实战AntiDebug自动化JS逆向加解密MCP
javascript·人工智能·网络安全·自动化·漏洞挖掘·cnvd·src赏金
wengad6 小时前
从 wangEditor 迁到 wangEditor-next
前端·javascript·vue.js
行者-全栈开发7 小时前
【前端/JS框架】CVE-2026-3854:GitHub Enterprise Server X-Stat注入XSS漏洞深度剖析与紧急修复指南
前端·javascript·github
怕浪猫8 小时前
2026年金九银十,我面了22个前端
前端·javascript·面试
前端的日常9 小时前
一个人+AI做情侣食谱小程序,30天纯赚
前端·javascript·后端
qq_316837759 小时前
阿里云百炼 fun-asr-realtime uniapp vue3 调用
javascript·vue.js·uni-app
默_笙10 小时前
🚊 别再让 AI 的记忆写两遍了:PostgreSQL 把关系查询和语义检索装进一张表
前端·javascript
lzhdim10 小时前
C#不为人知的10个魔法特性:资深开发者也会震惊的底层奥秘
java·前端·javascript·算法·c#
传奇开心果编程10 小时前
【SwiftUI入门练中学】第7课 动画与手势:让界面更灵动
学习·macos·ui·ios·swiftui·swift
只睡四小时11 小时前
JS 手写 D-pad 空间导航:电视端焦点引擎实战
android·开发语言·前端·javascript·ecmascript·hls·空间导航