代码之家  ›  专栏  ›  技术社区  ›  vsync Qantas 94 Heavy

防止从元素滚动到窗口

  •  52
  • vsync Qantas 94 Heavy  · 技术社区  · 15 年前

    我有一个模式框窗口(弹出窗口),其中包含一个iframe,
    在里面 伊夫拉姆 有一个 分区 这是可滚动的。

    当我滚动iframe的内部div时,它已经达到了它的顶部或底部限制,
    浏览器本身的窗口开始滚动。这是一个 不需要的行为 .

    我试过这样的方法,当
    当鼠标进入弹出框区域时,OnMouseEnter:

    e.PreventDefault()由于某些原因无法正常工作…

    $("#popup").mouseenter(function(){
       $(window).bind("scroll", function(e){
            e.preventDefault();
       }); 
    }).mouseleave(function(){
        $(window).unbind("scroll");
    });
    

    更新

    好像现在是2013年 e.preventDefault(); 够了…

    14 回复  |  直到 6 年前
        1
  •  25
  •   bobince    15 年前

    抱歉,据我所知,无法取消任何滚动事件。

    两个 W3 MSDN 说:

    Cancelable  No
    Bubbles     No
    

    我想你得让浏览器作者来解决这个问题。firefox(Linux上的3.5版)对我来说似乎有更好的表现:它只会在孩子已经在顶端/底端的时候滚动父节点。 开始 使用滚轮。

        2
  •  17
  •   Christian Kohlschütter    14 年前

    如果我们不能阻止窗口滚动,为什么不撤消它呢? 也就是说,捕捉滚动事件,然后滚动回固定位置。

    以下代码将锁定Y轴,只要有一个悬停在 $("#popup") :

    // here we store the window scroll position to lock; -1 means unlocked
    var forceWindowScrollY = -1;
    
    $(window).scroll(function(event) {
      if(forceWindowScrollY != -1 && window.scrollY != forceWindowScrollY) {
        $(window).scrollTop(forceWindowScrollY);    
      }
    });
    
    $("#popup").hover(function() {
      if(forceWindowScrollY == -1) {
        forceWindowScrollY = $(window).scrollTop();
      }
    }, function() {
      forceWindowScrollY = -1;
    });
    

    我用这个查询建议框 http://bundestube.de/ (在顶部搜索框中输入一些字符,使可滚动窗格可见):

    Screenshot

    这在Chrome/Safari(WebKit)中是完美的,在Firefox和Opera中也有一些滚动故障。出于某种原因,它不适用于我的IE安装。我想这与jquery的hover方法有关,它在所有情况下似乎都不能正常工作。

        3
  •  4
  •   Nebril    12 年前

    我知道这是一个很古老的问题,但既然这是谷歌的一个顶级搜索结果…我不得不在没有jquery的情况下取消滚动冒泡,这段代码对我很有用:

    function preventDefault(e) {
      e = e || window.event;
      if (e.preventDefault)
        e.preventDefault();
      e.returnValue = false;  
    }
    
    document.getElementById('a').onmousewheel = function(e) { 
      document.getElementById('a').scrollTop -= e. wheelDeltaY; 
      preventDefault(e);
    }
    
        4
  •  3
  •   psycho brm    12 年前

    我的jquery插件:

    $('.child').dontScrollParent();
    
    $.fn.dontScrollParent = function()
    {
        this.bind('mousewheel DOMMouseScroll',function(e)
        {
            var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail;
    
            if (delta > 0 && $(this).scrollTop() <= 0)
                return false;
            if (delta < 0 && $(this).scrollTop() >= this.scrollHeight - $(this).height())
                return false;
    
            return true;
        });
    }
    
        5
  •  1
  •   Gianluca Ghettini    8 年前

    这就是我解决问题的方法:

    当我打开弹出窗口时,我调用以下命令:

    $('body').css('overflow','hidden');
    

    然后,当我关闭弹出窗口时,我称之为:

    $('body').css('overflow','auto');
    

    弹出窗口是模态的,因此不需要与底层实体进行交互。

    工作得很好

        6
  •  1
  •   vsync Qantas 94 Heavy    6 年前

    解决(用于) 现代的 浏览器)使用简单的CSS属性:
    overscroll-behavior

    body{
      height: 600px;
      overflow: auto;
    }
    
    section{
      width: 50%;
      height: 50%;
      overflow: auto;
      background: lightblue;
      overscroll-behavior: none; /*   <--- the trick    */
    }
    
    section::before{
      content: '';
      height: 200%;
      display: block;
    }
    <section>
     <input value='end' />
    </section>

    只需在滚动应该“锁定”到的元素上应用该样式属性,滚动事件就不会冒泡到可能有滚动的任何父元素。


    与上述演示相同,但 没有 诀窍:

    body{
      height: 600px;
      overflow: auto;
    }
    
    section{
      width: 50%;
      height: 50%;
      overflow: auto;
      background: lightblue;
    }
    
    section::before{
      content: '';
      height: 200%;
      display: block;
    }
    <科室;
    <input value='end'/gt;
    </section>
        7
  •  0
  •   Dan F    15 年前

    显然,你可以 overflow:hidden to prevent scrolling . 不知道如果文档已经滚动了会怎么样。我也在一台没有鼠标的笔记本电脑上,所以今晚不需要对我进行滚动轮测试:—)不过这可能值得一试。

        8
  •  0
  •   adardesign    15 年前

    您可以在iframe中尝试jscroll窗格来替换默认滚动。

    http://www.kelvinluck.com/assets/jquery/jScrollPane/jScrollPane.html

    我不确定,不过试试看

        9
  •  0
  •   parliament    10 年前

    我要做的是:

      $('.noscroll').on('DOMMouseScroll mousewheel', function(ev) {
         var prevent = function() {
             ev.stopPropagation();
             ev.preventDefault();
             ev.returnValue = false;
             return false;
         }
         return prevent();
      }); 
    

    demo fiddle

    使用CSS overflow:hidden 隐藏滚动条,因为如果拖动滚动条,它将不起任何作用。

    工作跨浏览器

        10
  •  0
  •   V Maharajh    9 年前

    这里是新的Web开发人员。这在IE和Chrome上对我都很有吸引力。

    static preventScrollPropagation(e: HTMLElement) {
        e.onmousewheel = (ev) => {
            var preventScroll = false;
            var isScrollingDown = ev.wheelDelta < 0;
            if (isScrollingDown) {
                var isAtBottom = e.scrollTop + e.clientHeight == e.scrollHeight;
                if (isAtBottom) {
                    preventScroll = true;
                }
            } else {
                var isAtTop = e.scrollTop == 0;
                if (isAtTop) {
                    preventScroll = true;
                }
            }
            if (preventScroll) {
                ev.preventDefault();
            }
        }
    }
    

    不要让行数愚弄你,这很简单——只是为了可读性有点冗长(自我记录代码ftw对吗?)

        11
  •  0
  •   Aleksandar Ivanov    8 年前

    我想添加一些我发现最有效的更新代码:

    var yourElement = $('.my-element');
    
    yourElement.on('scroll mousewheel wheel DOMMouseScroll', function (e) {
        var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail;
    
        if (delta > 0 && $(this).scrollTop() <= 0)
            return false;
        if (delta < 0 && $(this).scrollTop() >= this.scrollHeight - $(this).outerHeight())
            return false;
    
        return true;
    });
    

    这一个和上面已经提到的不同之处在于添加了更多的事件和使用 OUTHEAD() 而不是 Head() 为了避免在元素有填充物的情况下崩溃!

        12
  •  0
  •   Roland Soós    8 年前
    $('.scrollable').on('DOMMouseScroll mousewheel', function (e) {
        var up = false;
        if (e.originalEvent) {
            if (e.originalEvent.wheelDelta) up = e.originalEvent.wheelDelta / -1 < 0;
            if (e.originalEvent.deltaY) up = e.originalEvent.deltaY < 0;
            if (e.originalEvent.detail) up = e.originalEvent.detail < 0;
        }
    
        var prevent = function () {
            e.stopPropagation();
            e.preventDefault();
            e.returnValue = false;
            return false;
        }
    
        if (!up && this.scrollHeight <= $(this).innerHeight() + this.scrollTop + 1) {
            return prevent();
        } else if (up && 0 >= this.scrollTop - 1) {
            return prevent();
        }
    });
    
        13
  •  0
  •   Mustkeem K    6 年前

    截至目前2018年及以后,e.preventdefault已足够。

    $('.elementClass').on("scroll", function(e){
        e.preventDefault();
     }); 
    

    这将阻止滚动到父级。

        14
  •  -2
  •   fasih.rana    15 年前
    function stopPropogation(e)
    {
        e = e || window.event;
        e.cancelBubble = true;
        if (e.stopPropagation) e.stopPropagation();
        if (e.preventDefault) e.preventDefault();
    }
    

    这应该有效。