iOS Safari似乎永远不会触发滚动事件,如果鼠标下的元素只有"overflow-y: scroll&qu

iOS Safari appears to never fire scroll event if the element under mouse has only "overflow-y: scroll" and scrolling horizontally

本文关键字:元素 quot scroll qu overflow-y 鼠标 如果 永远 Safari 事件 滚动      更新时间:2023-09-26

我有两个元素,父节点和子节点。子节点只能垂直滚动(overflow: hidden; overflow-y: scroll;)。父节点只能水平滚动(overflow: hidden; overflow-x: scroll;)。当我在子节点上横向滑动时,尽管这样做了,但没有触发滚动事件:

//NEITHER of these are fired when swiping sideways on the child
child.addEventListener( "scroll", listener, true );
parent.addEventListener( "scroll", listener2, true );

浏览器只有触发一个滚动事件,如果我垂直滚动在孩子!listener listener2都没有被调用!如果子元素只有一个方向滚动,我如何让它为父元素触发水平滚动?

Fiddle Mobile示例: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 );

编辑:它出现即使overflow: scroll在孩子,如果没有什么可以水平滚动,它仍然不会触发滚动事件! https://jsfiddle.net/cn2hfLok/4/embedded/result/

如果孩子在你试图移动的方向上没有任何东西可以滚动,或者它不听那个方向,那么在iOS Safari上为父母捕获滚动事件是不可能的。为了克服这个问题,你需要监听子进程上的触摸事件,然后通过改变父进程的scrollLeftscrollTop将该移动传递给父进程,这将触发父进程的滚动事件处理程序。

听:

touchstart

捕捉起始位置

touchmove

检查当前位置对开始,如果它水平移动(和足够小的垂直),然后通过parent.scrollLeft += startX - e.clientX;传递给父,然后调用e.stopPropagation();e.preventDefault();,使它不移动页面。(同时将startX更新为e.clientX)

touchendtouchleave

设置一些变量来告诉你的touchmove处理器停止监听,例如notDragging = true;

我认为你应该按以下方向去做:

  1. 为处理程序启用捕获阶段:document.querySelector( ".parent" ).addEventListener( "scroll", scrollP, true );

  2. 停止父回调中的传播:e.stopPropagation();

在这种情况下,父端的监听器将拦截包括horizontal scroll在内的所有事件。但实际上你可以通过event.type和其他一些可访问的属性来过滤它们。

下面是更新后的示例:https://jsfiddle.net/cn2hfLok/7/