2012-04-18 161 views

回答

41

找到解決方案。

http://jsbin.com/itajok

這就是我所需要的。

這是代碼。

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

使用一個jQuery插件。


更新由於取消通知

jquery-mousewheel

添加三個參數(deltadeltaX,並deltaY) 到事件處理程序的舊的行爲現在已經過時並將在稍後的 版本中刪除。

然後,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; 
}); 

Demo

+6

你的鏈接使用github的js和休息,因爲內容類型等等等等這裏這個工程:http://jsbin.com/itajok/207/ – 2013-09-02 20:17:11

+0

這兩個jsbins似乎並沒有在Chrome設備模擬器和在蘋果手機。有誰知道這是否仍然有效? – 2015-06-11 07:51:15

+2

您的「解決方案」僅適用於鼠標滾動事件,不適用於頁面向上/向下或箭頭鍵。 – Scott 2016-06-22 21:33:22

0

如果您將overflow: hidden風格應該走

編輯:其實我看了你的問題錯了,只會隱藏滾動條,但我不認爲這是你在找什麼。

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

我需要兩個滾動條。我在談論這個行爲。當我滾動使用我的鼠標軌跡球達到div的滾動結束時,它不能滾動整個頁面。 – Jeevan 2012-04-18 14:16:34

66

你可以做這樣的事情滅活整個頁面的滾動?

E.g.該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'; 
} 
+30

不錯,但是當你將鼠標懸停在div上時,它會使瀏覽器的滾動條消失。 – cstack 2012-08-09 19:26:44

+0

@cstack你是對的,這就是爲什麼OP(Jeevan)自己的答案更好。 – 2014-07-04 07:03:40

+2

許多瀏覽器滾輪消失,現在基於用戶移動鼠標重新出現,因此上述評論不再是問題。 – 2015-10-16 03:42:49

8

你可以在DIV上使用鼠標懸停事件禁用身體滾動條,然後mouseOut事件再次激活它:

+10

您也可以使用'document.body'。 – Ryan 2012-04-18 14:36:44

7

如果我正確理解你的問題,那麼你要防止的主要內容滾動當鼠標移動到一個div(假設側欄)。爲此,側欄可能不是主內容(它是瀏覽器窗口)的滾動容器的子項,以防止滾動事件冒泡到其父項。

這可能需要通過以下方式標記的一些變化:

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

看到它的工作在this sample fiddle和比較,與this sample fiddle具有側邊欄的一個稍微不同的鼠標離開的行爲。請參閱scroll only one particular div with browser's main scrollbar

+0

在這種情況下,側欄位於包裝div外部。所以我不認爲卷軸會冒泡給父母 – Jeevan 2012-04-19 05:03:28

+0

通過「這種情況」你的意思是你的情況?如果不是的話:你完全正確。如果是這樣的話:如果你的頁面在div滾動結束時滾動,那麼滾動消息會冒泡到div父級,所以我認爲你的頁面和div不是兄弟,而是父母和孩子。 – NGLN 2012-04-19 06:22:17

+0

是的,頁面是我的div的父母,所以在到達最後時,它開始滾動頁面,我不想這樣做。 – Jeevan 2012-04-19 08:06:15

15

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

$.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的答案編輯器需要這個!

UPDATE

我相信這是因爲它並不試圖在所有操作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); 
     } 
    }) 
    ; 
};  

工程在鉻和許多偉大的比其他解決方案更簡單...讓我知道它是如何票價別處......

FIDDLE

+3

添加DOMMouseScroll事件使其與Firefox一起工作→http://jsfiddle.net/chodorowicz/egqy7mbz/1/ – chodorowicz 2015-07-03 17:35:20

+0

我很驚訝這不是寫入jquery。我認爲其中一個要點並不在乎你使用的瀏覽器。 – robisrob 2015-12-14 17:09:56

+0

實際上它看起來像兩個都不贊成... ['wheel' event](https://developer.mozilla.org/en-US/docs/Web/Events/wheel) – robisrob 2015-12-14 17:12:06

2

您可以通過做這樣的事情來禁用整個頁面的滾動,但顯示滾動條!

<div onmouseover="document.body.style.overflow='hidden'; document.body.style.position='fixed';" onmouseout="document.body.style.overflow='auto'; document.body.style.position='relative';"></div> 
+1

完美工作@joseantgv – 2018-02-09 08:58:25

7

我寫了解決此問題

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); 
+0

這裏的幾個解決方案之一,沒有頁面元素惱人地跳躍,因爲溢出隱藏被設置。 – 2015-11-11 14:55:43

+0

+1這是一個可靠的解決方案。如果你將它附加到一個可滾動的容器中,你會希望在這個例子中的div是'e.currentTarget'。 – Matt 2016-12-04 11:26:49

+0

很乾淨的解決方案。謝謝 – 2017-06-14 14:57:04

2
$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(); 
    } 
}); 
2

如果輸入選擇器元素此禁用窗口上的滾動。 的作品像魅力。

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"); 
}); 
1

基於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()來保護他們。

0

我不能得到任何答案在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; 
     } 
    } 
} 
4

這裏是一個跨瀏覽器的方式做到這一點在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(); 
    } 
}); 

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

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; 
}); 
+0

這個工程真棒!哇,正是我所搜索的,它需要絕對更多upvotes。 – delato468 2017-09-01 14:16:24

+0

此解決方案工作得很好,但需要很少調整: 需要通過'scrollTop> = maxScroll'來更改'scrollTop === maxScroll'。 對於1個案例來說,這似乎很奇怪。 – 2017-12-21 11:32:52