簡體   English   中英

滾動子 div 滾動窗口,我該如何停止?

[英]Scrolling child div scrolls the window, how do I stop that?

我有一個帶有滾動條的 div,當它到達末尾時,我的頁面開始滾動。 無論如何我可以阻止這種行為嗎?

您可以通過執行以下操作來停用整個頁面的滾動:

<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>

找到了解決辦法。

http://jsbin.com/itajok

這就是我所需要的。

這是代碼。

http://jsbin.com/itajok/edit#javascript,html

使用 jQuery 插件。


由於棄用通知而更新

jquery-mousewheel

向事件處理程序添加三個參數( deltadeltaXdeltaY )的舊行為現在已棄用,並將在以后的版本中刪除。

然后,現在必須使用event.deltaY

var toolbox = $('#toolbox'),
    height = toolbox.height(),
    scrollHeight = toolbox.get(0).scrollHeight;

toolbox.off("mousewheel").on("mousewheel", function (event) {
  var blockScrolling = this.scrollTop === scrollHeight - height && event.deltaY < 0 || this.scrollTop === 0 && event.deltaY > 0;
  return !blockScrolling;
});

演示

所選的解決方案是一件藝術品。 認為它值得一個插件......

$.fn.scrollGuard = function() {
    return this
        .on( 'wheel', function ( e ) {
            var event = e.originalEvent;
            var d = event.wheelDelta || -event.detail;
            this.scrollTop += ( d < 0 ? 1 : -1 ) * 30;
            e.preventDefault();
        });
};    

這對我來說一直是一個不便,與我見過的其他黑客相比,這個解決方案非常干凈。 很想知道它是如何工作的以及它會得到多廣泛的支持,但是為 Jeevan 和最初提出這個的人歡呼。 順便說一句 - stackoverflow 答案編輯器需要這個!

更新

我相信這更好,因為它根本不嘗試操作 DOM,只是有條件地防止冒泡......

$.fn.scrollGuard2 = function() {
  return this
    .on( 'wheel', function ( e ) {
      var $this = $(this);
      if (e.originalEvent.deltaY < 0) {
        /* scrolling up */
        return ($this.scrollTop() > 0);
      } else {
        /* scrolling down */
        return ($this.scrollTop() + $this.innerHeight() < $this[0].scrollHeight);
      }
    })
  ;
};    

在 chrome 中效果很好,比其他解決方案簡單得多……讓我知道它在其他地方的表現……

小提琴

您可以在 div 上使用 mouseover 事件禁用主體滾動條,然后使用 mouseout 事件再次激活它?

例如 HTML

<div onmouseover="disableBodyScroll();" onmouseout="enableBodyScroll();">
    content
</div>

然后像這樣的javascript:

var body = document.getElementsByTagName('body')[0];
function disableBodyScroll() {
    body.style.overflowY = 'hidden';
}
function enableBodyScroll() {
    body.style.overflowY = 'auto';
}

這是在 Y 軸上執行此操作的跨瀏覽器方式,它適用於桌面和移動設備。 在 OSX 和 iOS 上測試。

var scrollArea = this.querySelector(".scroll-area");
scrollArea.addEventListener("wheel", function() {
    var scrollTop = this.scrollTop;
    var maxScroll = this.scrollHeight - this.offsetHeight;
    var deltaY = event.deltaY;
    if ( (scrollTop >= maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
        event.preventDefault();
    }
}, {passive:false});

scrollArea.addEventListener("touchstart", function(event) {
    this.previousClientY = event.touches[0].clientY;
}, {passive:false});

scrollArea.addEventListener("touchmove", function(event) {
    var scrollTop = this.scrollTop;
    var maxScroll = this.scrollHeight - this.offsetHeight;
    var currentClientY = event.touches[0].clientY;
    var deltaY = this.previousClientY - currentClientY;
    if ( (scrollTop >= maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
        event.preventDefault();
    }
    this.previousClientY = currentClientY;
}, {passive:false});

我寫了解決這個問題

  var div;
  div = document.getElementsByClassName('selector')[0];

  div.addEventListener('mousewheel', function(e) {
    if (div.clientHeight + div.scrollTop + e.deltaY >= div.scrollHeight) {
      e.preventDefault();
      div.scrollTop = div.scrollHeight;
    } else if (div.scrollTop + e.deltaY <= 0) {
      e.preventDefault();
      div.scrollTop = 0;
    }
  }, false);

正如這里所回答的,大多數現代瀏覽器現在都支持overscroll-behavior: none; CSS 屬性,可防止滾動鏈接。 就是這樣,只有一行!

如果我正確理解您的問題,那么您希望在鼠標懸停在 div 上時防止滾動主要內容(比如說側邊欄)。 為此,側邊欄可能不是主要內容(即瀏覽器窗口)的滾動容器的子項,以防止滾動事件冒泡到其父項。

這可能需要按以下方式進行一些標記更改:

<div id="wrapper"> 
    <div id="content"> 
    </div> 
</div> 
<div id="sidebar"> 
</div> 

看到它在這個示例小提琴中工作,並將它與這個示例小提琴進行比較,它的側邊欄的鼠標離開行為略有不同。

另請參閱使用瀏覽器的主滾動條僅滾動一個特定的 div

如果您輸入選擇器元素,這將禁用窗口上的滾動。 像魅力一樣工作。

elements = $(".selector");

elements.on('mouseenter', function() {
    window.currentScrollTop = $(window).scrollTop();
    window.currentScrollLeft = $(window).scrollTop();
    $(window).on("scroll.prevent", function() {
        $(window).scrollTop(window.currentScrollTop);
        $(window).scrollLeft(window.currentScrollLeft);
    });
});

elements.on('mouseleave', function() {
    $(window).off("scroll.prevent");
});

您可以通過執行類似的操作來停用整個頁面的滾動,但顯示滾動條!

<div onmouseover="document.body.style.overflow='hidden'; document.body.style.position='fixed';" onmouseout="document.body.style.overflow='auto'; document.body.style.position='relative';"></div>
$this.find('.scrollingDiv').on('mousewheel DOMMouseScroll', function (e) {
  var delta = -e.originalEvent.wheelDelta || e.originalEvent.detail;
  var scrollTop = this.scrollTop;
  if((delta < 0 && scrollTop === 0) || (delta > 0 && this.scrollHeight - this.clientHeight - scrollTop === 0)) {
    e.preventDefault();
  }
});

根據 ceed 的回答,這是一個允許嵌套滾動保護元素的版本。 只有鼠標經過的元素才會滾動,而且滾動非常流暢。 這個版本也是可重入的。 它可以在同一個元素上多次使用,並將正確刪除和重新安裝處理程序。

jQuery.fn.scrollGuard = function() {
    this
        .addClass('scroll-guarding')
        .off('.scrollGuard').on('mouseenter.scrollGuard', function() {
            var $g = $(this).parent().closest('.scroll-guarding');
            $g = $g.length ? $g : $(window);
            $g[0].myCst = $g.scrollTop();
            $g[0].myCsl = $g.scrollLeft();
            $g.off("scroll.prevent").on("scroll.prevent", function() {
                $g.scrollTop($g[0].myCst);
                $g.scrollLeft($g[0].myCsl);
            });
        })
        .on('mouseleave.scrollGuard', function() {
            var $g = $(this).parent().closest('.scroll-guarding');
            $g = $g.length ? $g : $(window);
            $g.off("scroll.prevent");
        });
};

一種簡單的使用方法是向頁面中允許滾動的所有元素添加一個類,例如scroll-guard 然后使用$('.scroll-guard').scrollGuard()來保護它們。

如果您應用overflow: hidden樣式它應該消失

編輯:實際上我讀錯了你的問題,這只會隱藏滾動條,但我認為這不是你要找的。

我無法在 Chrome 和 Firefox 中找到任何答案,所以我想出了這個合並:

$someElement.on('mousewheel DOMMouseScroll', scrollProtection);

function scrollProtection(event) {
    var $this = $(this);
    event = event.originalEvent;
    var direction = (event.wheelDelta * -1) || (event.detail);
    if (direction < 0) {
        if ($this.scrollTop() <= 0) {
            return false;
        }
    } else {
        if ($this.scrollTop() + $this.innerHeight() >= $this[0].scrollHeight) {
            return false;
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM