我正在创建一个全屏网络应用程序,它将包含一些模块/小部件,这些模块/小部件利用新的iOS 5溢出:滚动功能。 我想要的是在滚动html / body时禁用“弹性”效果(因为它是全屏)但是只在可滚动元素上保留该效果。
平滑我可滚动元素的效果:
html, body { overflow: hidden; }
.scrollable {
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
然后是以下禁用触摸滚动效果的脚本:
$(document).bind('touchmove', function (e) {
if (e.target === document.documentElement) {
e.preventDefault();
}
});
虽然这似乎根本不起作用,因为当将元素滚动到最底端或顶部时,它也会滚动documentElement
。
有没有办法只为body html元素禁用该效果?
这是影响功能的一个很好的例子:
答案 0 :(得分:2)
令人遗憾的是-webkit-overflow-scrolling
没有更好地处理这个问题。您需要跟踪y
位置才能使其正常工作。我将课程scroll
放在我要在页面上滚动的任何内容上,例如<ul>
元素。使用<div>
在填充视口的<ul>
周围包裹overflow-y: auto
。不要将overflow
或height
放在<ul>
上。 <ul>
将扩展为与其内容一样高,并且它是实际进行滚动的<div>
。 -webkit-overflow-scrolling
是继承的,所以把它放在你想要的DOM上。
演示:http://jsfiddle.net/ThinkingStiff/FDqH7/
脚本:
var swipeY = 0;
function onTouchMove( event ) {
var scroll = event.target.closestByClassName( 'scroll' );
if ( scroll ) {
var top = scroll.positionTop - scroll.parentNode.positionTop,
heightDifference = ( 0 - scroll.offsetHeight + scroll.parentNode.offsetHeight );
if( ( top >= 0 ) && ( event.touches[0].screenY > swipeY ) ) {
event.preventDefault(); //at top, swiping down
} else if( ( top <= heightDifference ) && ( event.touches[0].screenY < swipeY ) ) {
event.preventDefault(); //at bottom, swiping up
};
} else {
event.preventDefault();
};
};
function onTouchStart( event ) {
swipeY = event.touches[0].screenY;
};
Element.prototype.closestByClassName = function ( className ) {
return this.className && this.className.split( ' ' ).indexOf( className ) > -1
? this
: ( this.parentNode.closestByClassName && this.parentNode.closestByClassName( className ) );
};
window.Object.defineProperty( Element.prototype, 'positionTop', {
get: function () {
return this.offsetTop - this.parentNode.scrollTop;
}
} );
document.getElementById( 'viewport' ).addEventListener( 'touchmove', onTouchMove, false );
document.getElementById( 'viewport' ).addEventListener( 'touchstart', onTouchStart, false );
HTML:
<div id="viewport">
<div id="scroll-view">
<ul class="scroll">
<li>scroll scroll scroll scroll scroll </li>
<li>scroll scroll scroll scroll scroll </li>
<li>scroll scroll scroll scroll scroll </li>
. . .
</ul>
</div>
</div>
CSS:
#viewport {
border: 1px solid black;
height: 460px;
width: 320px;
-webkit-overflow-scrolling: touch;
}
#scroll-view {
height: 100%;
overflow-y: auto;
width: 100%;
}
答案 1 :(得分:2)
这是ThinkingStiff的类似答案,除了它不强制你的html结构。它会查找溢出内容的任何元素,并仅在用户与它们交互时才启用滚动。
缺点:
一旦用户点击可滚动节点的顶部或底部限制,就不会在该节点内弹跳(但如果您从限制下方/上方轻弹,它将会发生)。这可能意味着它不能满足您对刷新的要求:(
在计算滚动偏移时,我在测试用例中注意到了一个奇怪的2px差异。不确定它来自何处,您可能需要调整值
CoffeeScript的:
# Vertical scrolling behavior overrides.
#
# This disables vertical scrolling on the page for touch devices, unless the user is scrolling
# within an overflowed node. This requires some finessing of the touch events.
#
# **NOTE:** This code ends up disabling bounce behavior if the user tries to scroll on a node that
# is already at its upper or lower limit.
window$ = $(window)
initialY = null
nodeStack = []
# When a user begins a (potential) drag, we jot down positional and node information.
#
# The assumption is that page content isn't going to move for the duration of the drag, and that
# it would also be awkward if the drag were to change/stop part way through due to DOM
# modifications.
window$.bind 'touchstart', (evt) ->
initialY = evt.originalEvent.pageY
nodeStack = $(evt.target).parents().andSelf().filter(':not(body, html)').get().reverse()
nodeStack = nodeStack.map (node) -> $(node)
window$.bind 'touchend touchcancel', (evt) ->
initialY = null
nodeStack = []
# We override the `touchmove` event so that we only allow scrolls in allowable directions,
# depending on where the user first began the drag.
window$.bind 'touchmove', (evt) ->
return evt.preventDefault() if initialY == null
# A positive direction indicates that the user is dragging their finger down, thus wanting the
# content to scroll up.
direction = evt.originalEvent.pageY - initialY
for node$ in nodeStack
nodeHeight = node$.height()
# For some reason, the node's scrollHeight is off by 2 pixels in all cases. This may require
# tweaking depending on your DOM. Concerning.
scrollHeight = node$[0].scrollHeight - 2
nodeScrollTop = node$.scrollTop()
# If we have a scrollable element, we want to only allow drags under certain circumstances:
if scrollHeight > nodeHeight
# * The user is dragging the content up, and the element is already scrolled down a bit.
return if direction > 0 and nodeScrollTop > 0
# * And the reverse: the user is dragging the content down, and the element is up a bit.
return if direction < 0 and nodeScrollTop < scrollHeight - nodeHeight
# Otherwise, the default behavior is to disable dragging.
evt.preventDefault()
答案 2 :(得分:0)
对我而言,唯一有效的解决方案是使用joelambert/ScrollFix脚本,在没有滞后的情况下工作得非常好,事实上我已经在我的一个项目中使用它了。
您还可以在his blog post更详细地查看相关信息。 很抱歉其他用户回复了但我真的没有得到那些为我工作的答案。