简体   繁体   English

iScroll 内 iScroll - 嵌套 iScroll 意外行为

[英]iScroll inside iScroll - nested iScroll unexpected behavior

I have 2 lists and I use iScroll for vertical scrolling.我有 2 个列表,我使用 iScroll 进行垂直滚动。

The second list is inside the first list.第二个列表第一个列表中。

When I scroll the second list, the first list is also scrolling.当我滚动第二个列表时,第一个列表也在滚动。
I want that when I scroll the inside list (the second list), the main list (the first list) will not scroll.我希望当我滚动内部列表(第二个列表)时,主列表(第一个列表)不会滚动。

How can I do that?我怎样才能做到这一点?

Here is an Example:这是一个例子:

<div id="wrapper" style="overflow: hidden;">
    <div id="scroller">
        <ul id="thelist">
            <li>Pretty row 1</li>
            <li>Pretty row 2</li>
            <li>Pretty row 3</li>
            <li>Pretty row 4</li>
            <li>Pretty row 5</li>
            <li>Pretty row 6</li>
            <li id='inWarper'>
                <div  id="scroller">
                    <br/>
                    <ul>
            <li>Pretty row 1</li>
            <li>Pretty row 2</li>
            <li>Pretty row 3</li>
            <li>Pretty row 4</li>
            <li>Pretty row 5</li>
            <li>Pretty row 6</li>
            <li>Pretty row 7</li>
            <li>Pretty row 8</li>
            <li>Pretty row 9</li>
            <li>Pretty row 10</li>
                    </ul>
                </div>
            </li>
            <li>Pretty row 7</li>
            <li>Pretty row 8</li>
            <li>Pretty row 9</li>
            <li>Pretty row 10</li>
            <li>Pretty row 11</li>
            <li>Pretty row 12</li>
            <li>Pretty row 13</li>
            <li>Pretty row 14</li>
            <li>Pretty row 15</li>
            <li>Pretty row 16</li>
            <li>Pretty row 17</li>
            <li>Pretty row 18</li>
        </ul>
         <br/>
    </div>
</div>

And in Load event:在 Load 事件中:

myScroll = new iScroll('wrapper');
myScroll2 = new iScroll('inWarper');

CSS: CSS:

#scroller ul {
list-style: none;
padding: 0;
margin: 0;
width: 100%;
text-align: left;
}

#scroller {
position: absolute;
z-index: 1;
/* -webkit-touch-callout: none; */
-webkit-tap-highlight-color: rgba(0,0,0,0);
width: 100%;
padding: 0;
}

#wrapper {
position: absolute;
z-index: 1;
top: 45px;
bottom: 48px;
left: 0;
width: 100%;
background: #aaa;
overflow: auto;
    height:150px;
}

#inWarper {
    color:red;
position: absolute;
z-index: 1;
height:100px;
left: 0;
width: 100%;
background: #aaa;
overflow: auto;
}

JSFiddle: http://jsfiddle.net/PPtWs/64/ JSFiddle: http : //jsfiddle.net/PPtWs/64/

The idea to fix this problem is to prevent (stop) propagation of the scrolling firing event to the parent div解决这个问题的想法是防止(停止)滚动触发事件传播到父 div

This is how to fix it这是修复它的方法

myScroll = new iScroll('wrapper');
myScroll2 = new iScroll('inWarper' , {
    onBeforeScrollStart : function(e) { 
    e.stopPropagation();
}});

Example http://jsfiddle.net/khaledalyawad/4p7t8ymp/示例http://jsfiddle.net/khaledalawad/4p7t8ymp/

I know that this is an old thread, but for anyone who finds this:我知道这是一个旧线程,但对于任何发现此问题的人:

Foreword: iScroll is now no longer maintained, so I recommend having a look at some alternatives, for example https://github.com/ustbhuangyi/better-scroll (which I did not try out myself, though).前言: iScroll 现在不再维护,所以我建议看看一些替代方案,例如https://github.com/ustbhuangyi/better-scroll (不过我自己没有尝试过)。 But if, for whatever reason, you have to use the iScroll and you want a smooth behaviour, the above answer might not be sufficient for you.但是,如果出于某种原因,您必须使用 iScroll 并且想要平稳的行为,那么上述答案可能对您来说还不够。

Issues with e.stopPropagation() e.stopPropagation()问题

What the native browser does when scrolling is actually first detecting what content is being scrolled and then scrolling that content.滚动时本机浏览器所做的实际上是首先检测正在滚动的内容,然后滚动该内容。

For example: if you touch a scrollable textarea on your mobile (imagine writing an answer here on StackOverflow on your mobile – you can try that out) it will scroll that area and not it's parent, even if your touch ends outside the area (you slide far up), as long as you hold your finger on the screen.例如:如果你在你的手机上触摸一个可滚动的 textarea(想象一下在你的手机上的 StackOverflow 上写一个答案——你可以试试)它会滚动那个区域而不是它的父区域,即使你的触摸结束在该区域之外(你向上滑动),只要您将手指放在屏幕上。 That is first case where the e.stopPropagation fails.这是 e.stopPropagation 失败的第一种情况。

Second issue is: if the nested scroll is fully scrolled to top/bottom and you scroll in that direction, then the above behaviour is negated and you actually scroll the outside area (again, try that on your mobile or even when mouse-wheel scrolling).第二个问题是:如果嵌套滚动完全滚动到顶部/底部并且您向该方向滚动,则上述行为被否定并且您实际上滚动了外部区域(再次,在您的手机上甚至在鼠标滚轮滚动时尝试)。 Try it out: simply be at the bottom of an area, then scroll down for a while, then quickly up - the main scrollbar will scroll down at first and then up later - even if your mouse is actually over the nested area.试试看:只需在一个区域的底部,然后向下滚动一段时间,然后快速向上滚动 -滚动条首先向下滚动然后向上滚动 - 即使您的鼠标实际上位于嵌套区域上。

Solution解决方案

The only way around this is to first detect the parent iScroll (or even a natively scrolling element) and then, as long as it is „the same scroll“, keep scrolling that area.解决此问题的唯一方法是首先检测父 iScroll(甚至是本机滚动元素),然后只要它是“相同的滚动”,就继续滚动该区域。 What is „the same scroll“ is simple for touch (from touch-start to touch-end event) and a bit complicated for mouse scroll (browsers seem to detect an „unbroken chain“ of succeeding scrolls, which is broken if you stop scrolling for a certain time - that time is browser-dependent, so it is up to you, what you want in your app).什么是“同一个滚动”对于触摸来说很简单(从触摸开始到触摸结束事件),对于鼠标滚动来说有点复杂(浏览器似乎检测到连续滚动的“不间断链”,如果您停止滚动,它就会被破坏一段时间 - 那个时间取决于浏览器,所以这取决于你,你想要什么在你的应用程序中)。

That is what I came up after diving quite deep into this.这就是我在深入研究之后想到的。 I actually have a working code for iScroll that works very smooth and feels like a native browser/app behaviour.我实际上有一个 iScroll 的工作代码,它运行起来非常流畅,感觉就像一个本机浏览器/应用程序的行为。 It has been a lot more work than I would like and it is quite long, but if anyone was interested, I can provide said code.这比我想要的要多得多,而且很长,但如果有人感兴趣,我可以提供所述代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM