这个:
$('body').on('touchmove',function(e) { e.preventDefault(); });
工程,但将禁用滚动整个页面,这是远远不理想。
这个:
$('*').on('touchstart',function(e){ var element = $(this).get(0); if ( element.scrollTop <= 0 ) element.scrollTop = 1; if ( element.scrollTop + element.offsetHeight >= element.scrollHeight ) element.scrollTop = element.scrollHeight - element.offsetHeight - 1; });
适用于具有滚动区域的页面。但是当没有什么要滚动它将再次显示橡皮筋。
所以我的问题:
如何禁用橡皮筋效果,仍然保持-webkit溢出滚动区域可滚动?
[更新]
最佳解决方案
停用所有不可滚动元素(如标签栏或导航栏)上的滚动。
anElement.addEventListener('touchmove',function( event ){ event.preventDefault() };
将滚动处理程序附加到可滚动元素(例如主要内容)。
anElement.addEventListener('touchstart',function( event ){ if( this.scrollTop === 0 ) { this.scrollTop += 1; } else if( this.scrollTop + this.offsetHeight >= this.scrollHeight ) { this.scrollTop -= 1; } }
解决方法
最近在SPA中进入相同的问题,其中< body>橡胶带减少了经验,但我需要在子区域滚动。非常感谢dSquared的建议,因为方法1最适合我。这里是我的小扩展他的建议,我实现在一个工作的项目,看起来一直在树上找到任何元素(不只是div)有.scroll类上:
// Prevent rubber-banding of the body,but allow for scrolling elements $('body').on('touchmove',function (e) { var searchTerms = '.scroll,.scroll-y,.scroll-x',$target = $(e.target),parents = $target.parents(searchTerms); if (parents.length || $target.hasClass(searchTerms)) { // ignore as we want the scroll to happen // (This is where we may need to check if at limit) } else { e.preventDefault(); } });
这里是CSS的外观:
body { height: 100%; overflow: hidden; } .scroll,.scroll-x { -webkit-overflow-scrolling: touch; } .scroll > *,.scroll-y > *,.scroll-x > * { -webkit-transform : translateZ(0); } .scroll { overflow: auto; } .scroll-y { overflow-y: auto; } .scroll-x { overflow-x: auto; }
你只需要一个库(jQuery或Zepto),你得到本机滚动与动量和身体上没有橡皮筋。此外,我已经添加了translateZ来修复一些问题,我已经与元素在滚动期间消失,它可以用于GPU accelerate your elements。
BUT(这是一个大的但是),如dSquared指出,整个页面的橡皮筋,当滚动元素在其极限,并试图进一步滚动。就我个人而言,我认为这是一个失败,所以我继续努力,只是想尝试弄明白这一点。添加一个检查沿着OP的代码行可能是答案,但我没有试过。
更新(10/7/12):
经过大量的工作,我得到了以下代码在iOS6(没有测试过任何其他)。没有橡皮筋在身上,没有更多的问题,当在滚动区域的极限,它具有本机滚动性能。这显然是更多的代码,最初,但我认为这将给予最接近OP的目标的行为。
(function registerScrolling($) { var prevTouchPosition = {},scrollYClass = 'scroll-y',scrollXClass = 'scroll-x',searchTerms = '.' + scrollYClass + ',.' + scrollXClass; $('body').on('touchstart',function (e) { var $scroll = $(e.target).closest(searchTerms),targetTouch = e.originalEvent.targetTouches[0]; // Store prevIoUs touch position if within a scroll element prevTouchPosition = $scroll.length ? { x: targetTouch.pageX,y: targetTouch.pageY } : {}; }); $('body').on('touchmove',function (e) { var $scroll = $(e.target).closest(searchTerms),targetTouch = e.originalEvent.targetTouches[0]; if (prevTouchPosition && $scroll.length) { // Set move helper and update prevIoUs touch position var move = { x: targetTouch.pageX - prevTouchPosition.x,y: targetTouch.pageY - prevTouchPosition.y }; prevTouchPosition = { x: targetTouch.pageX,y: targetTouch.pageY }; // Check for scroll-y or scroll-x classes if ($scroll.hasClass(scrollYClass)) { var scrollHeight = $scroll[0].scrollHeight,outerHeight = $scroll.outerHeight(),atUpperLimit = ($scroll.scrollTop() === 0),atLowerLimit = (scrollHeight - $scroll.scrollTop() === outerHeight); if (scrollHeight > outerHeight) { // If at either limit move 1px away to allow normal scroll behavior on future moves,// but stop propagation on this move to remove limit behavior bubbling up to body if (move.y > 0 && atUpperLimit) { $scroll.scrollTop(1); e.stopPropagation(); } else if (move.y < 0 && atLowerLimit) { $scroll.scrollTop($scroll.scrollTop() - 1); e.stopPropagation(); } // If only moving right or left,prevent bad scroll. if(Math.abs(move.x) > 0 && Math.abs(move.y) < 3){ e.preventDefault() } // Normal scrolling behavior passes through } else { // No scrolling / adjustment when there is nothing to scroll e.preventDefault(); } } else if ($scroll.hasClass(scrollXClass)) { var scrollWidth = $scroll[0].scrollWidth,outerWidth = $scroll.outerWidth(),atLeftLimit = $scroll.scrollLeft() === 0,atRightLimit = scrollWidth - $scroll.scrollLeft() === outerWidth; if (scrollWidth > outerWidth) { if (move.x > 0 && atLeftLimit) { $scroll.scrollLeft(1); e.stopPropagation(); } else if (move.x < 0 && atRightLimit) { $scroll.scrollLeft($scroll.scrollLeft() - 1); e.stopPropagation(); } // If only moving up or down,prevent bad scroll. if(Math.abs(move.y) > 0 && Math.abs(move.x) < 3){ e.preventDefault(); } // Normal scrolling behavior passes through } else { // No scrolling / adjustment when there is nothing to scroll e.preventDefault(); } } } else { // Prevent scrolling on non-scrolling elements e.preventDefault(); } }); })(jQuery);