移动端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;
 }
相关推荐
gis开发之家1 小时前
vue3直击架构痛点 依赖倒置与接口隔离——打造坚如磐石的插件与高阶组件(HOC)模式
javascript·架构·typescript·前端框架·vue3
柒和远方1 小时前
LeetCode 139. 单词拆分 —— 从暴力回溯到 DP 完全背包
javascript·python·算法
先吃饱再说1 小时前
流式输出完全指南:让 AI 对话像打字机一样流畅
javascript·vue.js
LDyun_2 小时前
.2026主流云手机测评,8款机型高压挂机实测
ios·智能手机·安卓·玩游戏
এ慕ོ冬℘゜3 小时前
原生 JS 实现自定义单选日历组件(无 UI 库、纯手写、禁用过去日期)
开发语言·javascript·ui
mONESY3 小时前
Skill 技能与 MCP 协议的底层逻辑与协同真相
javascript
南川琼语4 小时前
HTTP——AJAX
前端·javascript·ajax
pop_xiaoli4 小时前
【iOS】YYModel源码学习
学习·ios·objective-c·cocoa
霍霍哈嗨4 小时前
swiftUI框架基础
ios·swiftui·swift
不简说5 小时前
JS 代码技巧 vol.2 — 20 个数组/对象/字符串/正则的实用技巧
前端·javascript·面试