防止整页滚动iOS

在移动Safari浏览器下,是否可以允许一个绝对定位的div滚动,而不允许整个页面上下滚动,当滚动到达边缘(弹性滚动)?

这是我正面临的问题的一个最小工作示例:

 <!doctype html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="apple-mobile-web-app-capable" content="yes" /> <style> * { margin: 0; padding: 0; box-sizing: border-box; } #a, #b { position: absolute; top: 0; left: 0; height: 100%; padding: 10px; overflow: auto; } #a { width: 80px; background: #f00; } #b { background: #00f; left: 80px; width: 100%; } </style> <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> function pdcb(e) { e.preventDefault(); } function npcb(e) { e.stopPropagation(); } $(document).on('touchstart touchmove', pdcb). on('touchstart touchmove', '.scrollable', npcb); </script> </head> <body> <div id="a" class="scrollable"> This<br> should<br> be<br> scrollable<br> but<br> not<br> scroll<br> the<br> whole<br> page<br> This<br> should<br> be<br> scrollable<br> but<br> not<br> scroll<br> the<br> whole<br> page<br> This<br> should<br> be<br> scrollable<br> but<br> not<br> scroll<br> the<br> whole<br> page<br> This<br> should<br> be<br> scrollable<br> but<br> not<br> scroll<br> the<br> whole<br> page<br> This<br> should<br> be<br> scrollable<br> but<br> not<br> scroll<br> the<br> whole<br> page<br> </div> <div id="b"> this should never scroll </div> </body> </html> 

解:

 $(document).on('touchmove', function(e) { e.preventDefault(); }).ready(function() { $(".scrollable").on('touchstart', function(e) { this.allowUp = (this.scrollTop > 0); this.allowDown = (this.scrollTop < this.scrollHeight - this.clientHeight); this.prevTop = null; this.prevBot = null; this.lastY = e.originalEvent.pageY; }).on('touchmove', function(e) { var event = e.originalEvent; var up = (event.pageY > this.lastY), down = !up; this.lastY = event.pageY; if ((up && this.allowUp) || (down && this.allowDown)) event.stopPropagation(); else event.preventDefault(); }); }); 

虽然你没有触及div内容的边缘,但你需要允许native touchmove事件在这个元素上工作(所以它可以滚动),但是你想要停止事件冒泡DOM它不会触发页面主体上的滚动

当你击中元素的边界时,你需要防止本地动量完全滚动

我为此使用的代码如下( 原始作者道歉,这是从这个主题的教程改编我在过去的互联网上find的地方…似乎现在虽然找不到url ):

elem是你的DOM节点

 elem.addEventListener('touchstart', function(event){ this.allowUp = (this.scrollTop > 0); this.allowDown = (this.scrollTop < this.scrollHeight - this.clientHeight); this.prevTop = null; this.prevBot = null; this.lastY = event.pageY; }); elem.addEventListener('touchmove', function(event){ var up = (event.pageY > this.lastY), down = !up; this.lastY = event.pageY; if ((up && this.allowUp) || (down && this.allowDown)) event.stopPropagation(); else event.preventDefault(); }); 

我通常定义一个元素数组并循环遍历它们 – 迭代地将这个代码应用到每一个元素上。

祝你好运,希望这有助于。

原来的答案是太棒了,但有一些我解决的缺陷:

  • 如果元素在顶部或底部,则不会分别上下滚动。
  • 如果一个元素dynamic添加,它将不会有滚动处理程序。
  • 有没有使用的variables(prevTop,prevBot)

我的回答解决了这些。 (请注意,我使用.scroll-y而不是.scrollable

首先,添加这些CSS规则:

 .scroll-y { overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; /* nice webkit native scroll */ } 

.scroll-y类添加到您想要滚动的任何元素。

然后,在某处添加这个JS:

 // Disable scroll for the document, we'll handle it ourselves $(document).on('touchmove', function(e) { e.preventDefault(); }); // Check if we should allow scrolling up or down $(document.body).on("touchstart", ".scroll-y", function (e) { // If the element is scrollable (content overflows), then... if (this.scrollHeight !== this.clientHeight) { // If we're at the top, scroll down one pixel to allow scrolling up if (this.scrollTop === 0) { this.scrollTop = 1; } // If we're at the bottom, scroll up one pixel to allow scrolling down if (this.scrollTop === this.scrollHeight - this.clientHeight) { this.scrollTop = this.scrollHeight - this.clientHeight - 1; } } // Check if we can scroll this.allowUp = this.scrollTop > 0; this.allowDown = this.scrollTop < (this.scrollHeight - this.clientHeight); this.lastY = e.originalEvent.pageY; }); $(document.body).on('touchmove', ".scroll-y", function(e) { var event = e.originalEvent; var up = event.pageY > this.lastY; var down = !up; this.lastY = event.pageY; if ((up && this.allowUp) || (down && this.allowDown)) { event.stopPropagation(); } else { event.preventDefault(); } }); 

我相信bouncefix.js是这个问题的一个解决scheme。

Aaron Gray提供的说明帮了大忙!

见链接: http : //blog.christoffer.me/six-things-i-learnt-about-ios-safaris-rubber-band-scrolling/

 <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="minimum-scale=1.0, width=device-width, maximum-scale=1.0, user-scalable=no, initial-scale=1"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <style> .page{ font-size: 24px; overflow: scroll; } .menu{ position: fixed; top: 0; bottom: 0; left: 0; width: 80%; background: gray; z-index: 1; font-size: 10px; overflow: scroll; /* uncomment to get smooth momentum scroll, but also a rubber band effect */ /*-webkit-overflow-scrolling: touch;*/ } .menu-item{ padding: 10px; background: darkgray; font-size: 24px; } </style> </head> <body> <div class="menu scrollable"> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> </div> <div class="page disable-scrolling"> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </div> <script> document.ontouchmove = function ( event ) { var isTouchMoveAllowed = true, target = event.target; while ( target !== null ) { if ( target.classList && target.classList.contains( 'disable-scrolling' ) ) { isTouchMoveAllowed = false; break; } target = target.parentNode; } if ( !isTouchMoveAllowed ) { event.preventDefault(); } }; function removeIOSRubberEffect( element ) { element.addEventListener( "touchstart", function () { var top = element.scrollTop, totalScroll = element.scrollHeight, currentScroll = top + element.offsetHeight; if ( top === 0 ) { element.scrollTop = 1; } else if ( currentScroll === totalScroll ) { element.scrollTop = top - 1; } } ); } removeIOSRubberEffect( document.querySelector( ".scrollable" ) ); </script> </body> </html>