Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
594 views
in Technique[技术] by (71.8m points)

javascript - 当内部元素滚动位置到达顶部/底部时,防止父元素滚动? [重复](Prevent scrolling of parent element when inner element scroll position reaches top/bottom? [duplicate])

This question already has an answer here:

(这个问题已经在这里有了答案:)

I have a little "floating tool box" - a div with position:fixed; overflow:auto

(我有一个小的“浮动工具箱”- position:fixed; overflow:auto为div的div position:fixed; overflow:auto)

position:fixed; overflow:auto .

(position:fixed; overflow:auto 。)

Works just fine.

(效果很好。)

But when scrolling inside that box (with the mouse wheel) and reaching the bottom OR top, the parent element "takes over" the "scroll request" : The document behind the tool box scrolls.

(但是,当在该框内滚动(使用鼠标滚轮)并到达底部或顶部时,父元素将“接管”“滚动请求”:工具箱后面的文档将滚动。)


- Which is annoying and not what the user "asked for".

(-这很烦人,而不是用户的“要求”。)

I'm using jQuery and thought I could stop this behaviour with event.stoppropagation():

(我正在使用jQuery,并认为可以使用event.stoppropagation()停止此行为:)


$("#toolBox").scroll( function(event){ event.stoppropagation() });

It does enter the function, but still, propagation happens anyway (the document scrolls)

(它确实输入了功能,但仍然会发生传播(文档滚动))


- It's surprisingly hard to search for this topic on SO (and Google), so I have to ask:

(-很难在SO(和Google)上搜索此主题,所以我不得不问:)


How to prevent propagation / bubbling of the scroll-event ?

(如何防止滚动事件的传播/冒泡?)

Edit:

(编辑:)


Working solution thanks to amustill (and Brandon Aaron for the mousewheel-plugin here:

(感谢amustill(以及Brandon Aaron的鼠标滚轮插件,在这里工作的解决方案:)


https://github.com/brandonaaron/jquery-mousewheel/raw/master/jquery.mousewheel.js

(https://github.com/brandonaaron/jquery-mousewheel/raw/master/jquery.mousewheel.js)

$(".ToolPage").bind('mousewheel', function(e, d)  
    var t = $(this);
    if (d > 0 && t.scrollTop() === 0) {
        e.preventDefault();
    }
    else {
        if (d < 0 && (t.scrollTop() == t.get(0).scrollHeight - t.innerHeight())) {
            e.preventDefault();
        }
    }
});
  ask by T4NK3R translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I am adding this answer for completeness because the accepted answer by @amustill does not correctly solve the problem in Internet Explorer .

(我添加此答案是出于完整性考虑,因为@amustill接受的答案不能正确解决Internet Explorer中的问题 。)

Please see the comments in my original post for details.

(请查看我的原始帖子中的评论以获取详细信息。)

In addition, this solution does not require any plugins - only jQuery.

(此外,此解决方案不需要任何插件-仅需要jQuery。)

In essence, the code works by handling the mousewheel event.

(本质上,该代码通过处理mousewheel事件来工作。)

Each such event contains a wheelDelta equal to the number of px which it is going to move the scrollable area to.

(每个此类事件都包含一个wheelDelta ,它等于将滚动区域移动到的px数。)

If this value is >0 , then we are scrolling up .

(如果该值>0 ,那么我们正在up滚动。)

If the wheelDelta is <0 then we are scrolling down .

(如果wheelDelta <0则我们down滚动。)

FireFox : FireFox uses DOMMouseScroll as the event, and populates originalEvent.detail , whose +/- is reversed from what is described above.

(FireFox :FireFox使用DOMMouseScroll作为事件,并填充originalEvent.detail ,其+/-与上述内容相反。)

It generally returns intervals of 3 , while other browsers return scrolling in intervals of 120 (at least on my machine).

(通常返回3间隔,而其他浏览器则以120间隔返回滚动(至少在我的机器上)。)

To correct, we simply detect it and multiply by -40 to normalize.

(要更正,我们只需检测它并乘以-40即可归一化。)

@amustill's answer works by canceling the event if the <div> 's scrollable area is already either at the top or the bottom maximum position.

(如果<div>的可滚动区域已位于顶部或底部最大位置,则@amustill的答案通过取消事件来起作用。)

However, Internet Explorer disregards the canceled event in situations where the delta is larger than the remaining scrollable space.

(但是,在delta大于剩余可滚动空间的情况下, Internet Explorer会忽略取消的事件。)

In other words, if you have a 200px tall <div> containing 500px of scrollable content, and the current scrollTop is 400 , a mousewheel event which tells the browser to scroll 120px further will result in both the <div> and the <body> scrolling, because 400 + 120 > 500 .

(换句话说,如果有200px<div>500px的滚动内容,且当前scrollTop400 ,一个mousewheel事件,告诉浏览器滚动120px进一步将导致两个<div><body>滚动,因为400 + 120 > 500 。)

So - to solve the problem, we have to do something slightly different, as shown below:

(所以-要解决该问题,我们必须做一些稍微不同的事情,如下所示:)

The requisite jQuery code is:

(必要的jQuery代码是:)

$(document).on('DOMMouseScroll mousewheel', '.Scrollable', function(ev) {
    var $this = $(this),
        scrollTop = this.scrollTop,
        scrollHeight = this.scrollHeight,
        height = $this.innerHeight(),
        delta = (ev.type == 'DOMMouseScroll' ?
            ev.originalEvent.detail * -40 :
            ev.originalEvent.wheelDelta),
        up = delta > 0;

    var prevent = function() {
        ev.stopPropagation();
        ev.preventDefault();
        ev.returnValue = false;
        return false;
    }

    if (!up && -delta > scrollHeight - height - scrollTop) {
        // Scrolling down, but this will take us past the bottom.
        $this.scrollTop(scrollHeight);
        return prevent();
    } else if (up && delta > scrollTop) {
        // Scrolling up, but this will take us past the top.
        $this.scrollTop(0);
        return prevent();
    }
});

In essence, this code cancels any scrolling event which would create the unwanted edge condition, then uses jQuery to set the scrollTop of the <div> to either the maximum or minimum value, depending on which direction the mousewheel event was requesting.

(从本质上讲,此代码取消了任何会产生不必要边缘条件的滚动事件,然后使用jQuery将<div>scrollTop设置为最大值或最小值,具体取决于mousewheel事件所请求的方向。)

Because the event is canceled entirely in either case, it never propagates to the body at all, and therefore solves the issue in IE, as well as all of the other browsers.

(由于无论在哪种情况下事件都被完全取消,因此它根本不会传播到body ,因此可以解决IE以及所有其他浏览器中的问题。)

I have also put up a working example on jsFiddle .

(我还在jsFiddle上提出了一个工作示例 。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...