iOS 如果鼠标下的元素只有 "overflow-y: scroll" 并且水平滚动,Safari 似乎永远不会触发滚动事件
iOS Safari appears to never fire scroll event if the element under mouse has only "overflow-y: scroll" and scrolling horizontally
我有两个元素,一个 parent 节点和 child。 child 只能垂直滚动 (overflow: hidden; overflow-y: scroll;
)。 parent 只能水平滚动 (overflow: hidden; overflow-x: scroll;
)。当我在 child 节点上横向滑动时,尽管这样做也没有触发任何滚动事件:
//NEITHER of these are fired when swiping sideways on the child
child.addEventListener( "scroll", listener, true );
parent.addEventListener( "scroll", listener2, true );
如果我在 child 上垂直滚动,浏览器 仅 触发滚动事件! listener
和 listener2
都没有被调用!如果 child 元素只有一个方向滚动,我如何让它为 parent 元素触发水平滚动?
Fiddle 手机示例:https://jsfiddle.net/cn2hfLok/2/embedded/result/
HTML:
<div class="parent">
<div class="child">
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
</div>
<div style="width: 5000px;">s</div>
</div>
CSS:
.parent
{
position:relative;
width: 600px;
height: 100%;
background-color: yellow;
overflow: hidden;
overflow-x: scroll;
}
.child
{
position:relative;
width: 50%;
height: 200px;
background-color: blue;
overflow: hidden;
overflow-y: scroll;
}
JavaScript:
function scrollC(e)
{
console.log( "child" );
}
function scrollP(e)
{
console.log( "parent" );
}
document.querySelector( ".child" ).addEventListener( "scroll", scrollC );
document.querySelector( ".parent" ).addEventListener( "scroll", scrollP );
编辑:即使在 child 上显示 overflow: scroll
,如果没有可水平滚动的内容,它 仍然 不会'不要触发滚动事件! https://jsfiddle.net/cn2hfLok/4/embedded/result/
我认为你应该朝着以下方向前进:
为处理程序启用捕获阶段:document.querySelector( ".parent" ).addEventListener( "scroll", scrollP, true );
在父回调中停止传播:e.stopPropagation();
在这种情况下,父级的侦听器将拦截所有事件,包括 horizontal scroll
。但实际上你可以通过 event.type
和一堆其他可访问的属性来过滤它们。
这是更新后的示例:https://jsfiddle.net/cn2hfLok/7/
如果 child 在您尝试移动的方向上没有可滚动的内容,或者它没有,则无法在 iOS Safari 上为 parent 捕获滚动事件听那个方向。为了克服这个问题,您需要监听 child 上的触摸事件,然后通过更改 parent 的 scrollLeft
或 [=11] 将该移动传递给 parent =] 这将触发 parent 的滚动事件处理程序。
收听:
touchstart
夺取起始位置
touchmove
根据开始检查当前位置,如果它水平移动(并且垂直移动足够小),然后通过 parent.scrollLeft += startX - e.clientX;
传递给 parent 然后调用 e.stopPropagation();e.preventDefault();
所以它不会' 移动页面。 (同时将您的 startX
更新为 e.clientX
)
touchend
和 touchleave
设置一些变量来告诉您的 touchmove
处理程序停止监听,例如 notDragging = true;
我有两个元素,一个 parent 节点和 child。 child 只能垂直滚动 (overflow: hidden; overflow-y: scroll;
)。 parent 只能水平滚动 (overflow: hidden; overflow-x: scroll;
)。当我在 child 节点上横向滑动时,尽管这样做也没有触发任何滚动事件:
//NEITHER of these are fired when swiping sideways on the child
child.addEventListener( "scroll", listener, true );
parent.addEventListener( "scroll", listener2, true );
如果我在 child 上垂直滚动,浏览器 仅 触发滚动事件! listener
和 listener2
都没有被调用!如果 child 元素只有一个方向滚动,我如何让它为 parent 元素触发水平滚动?
Fiddle 手机示例:https://jsfiddle.net/cn2hfLok/2/embedded/result/
HTML:
<div class="parent">
<div class="child">
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
content<br />content<br />content<br />content<br />content<br />content<br />content<br />
</div>
<div style="width: 5000px;">s</div>
</div>
CSS:
.parent
{
position:relative;
width: 600px;
height: 100%;
background-color: yellow;
overflow: hidden;
overflow-x: scroll;
}
.child
{
position:relative;
width: 50%;
height: 200px;
background-color: blue;
overflow: hidden;
overflow-y: scroll;
}
JavaScript:
function scrollC(e)
{
console.log( "child" );
}
function scrollP(e)
{
console.log( "parent" );
}
document.querySelector( ".child" ).addEventListener( "scroll", scrollC );
document.querySelector( ".parent" ).addEventListener( "scroll", scrollP );
编辑:即使在 child 上显示 overflow: scroll
,如果没有可水平滚动的内容,它 仍然 不会'不要触发滚动事件! https://jsfiddle.net/cn2hfLok/4/embedded/result/
我认为你应该朝着以下方向前进:
为处理程序启用捕获阶段:
document.querySelector( ".parent" ).addEventListener( "scroll", scrollP, true );
在父回调中停止传播:
e.stopPropagation();
在这种情况下,父级的侦听器将拦截所有事件,包括 horizontal scroll
。但实际上你可以通过 event.type
和一堆其他可访问的属性来过滤它们。
这是更新后的示例:https://jsfiddle.net/cn2hfLok/7/
如果 child 在您尝试移动的方向上没有可滚动的内容,或者它没有,则无法在 iOS Safari 上为 parent 捕获滚动事件听那个方向。为了克服这个问题,您需要监听 child 上的触摸事件,然后通过更改 parent 的 scrollLeft
或 [=11] 将该移动传递给 parent =] 这将触发 parent 的滚动事件处理程序。
收听:
touchstart
夺取起始位置
touchmove
根据开始检查当前位置,如果它水平移动(并且垂直移动足够小),然后通过 parent.scrollLeft += startX - e.clientX;
传递给 parent 然后调用 e.stopPropagation();e.preventDefault();
所以它不会' 移动页面。 (同时将您的 startX
更新为 e.clientX
)
touchend
和 touchleave
设置一些变量来告诉您的 touchmove
处理程序停止监听,例如 notDragging = true;