【发布时间】:2012-04-29 23:19:03
【问题描述】:
我有一个带有滚动条的 div,当它到达末尾时,我的页面开始滚动。无论如何我可以阻止这种行为吗?
【问题讨论】:
-
@NGLN 不是重复的不同问题。
标签: javascript html
我有一个带有滚动条的 div,当它到达末尾时,我的页面开始滚动。无论如何我可以阻止这种行为吗?
【问题讨论】:
标签: javascript html
这是一种在 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});
【讨论】:
scrollTop === maxScroll 更改为scrollTop >= maxScroll。 1个案例似乎很奇怪,这是需要的
正如here 的回答,大多数现代浏览器现在都支持overscroll-behavior: none; CSS 属性,它可以防止滚动链接。就是这样,只有一行!
【讨论】:
overscroll-behavior: contain;。
我无法在 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;
}
}
}
【讨论】:
根据 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() 保护它们。
【讨论】:
如果您输入选择器元素,这将禁用窗口上的滚动。 像魅力一样工作。
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");
});
所选解决方案是一件艺术品。觉得值得一个插件....
$.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 中效果很好,比其他解决方案简单得多...让我知道它在其他地方的表现如何...
【讨论】:
wheel event
找到了解决办法。
这是我需要的。
这是代码。
http://jsbin.com/itajok/edit#javascript,html
使用 jQuery 插件。
因弃用通知而更新
添加三个参数(
delta、deltaX和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;
});
【讨论】:
$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();
}
});
【讨论】:
我写了解决这个问题的方法
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);
【讨论】:
e.currentTarget。
addEventListener 指定false,因为这是默认设置。此外,比较应该是简单的不等式(> 和<),而不是>= 或<=。
您可以通过执行类似操作来禁用整个页面的滚动,但显示滚动条!
<div onmouseover="document.body.style.overflow='hidden'; document.body.style.position='fixed';" onmouseout="document.body.style.overflow='auto'; document.body.style.position='relative';"></div>
【讨论】:
如果我正确理解了您的问题,那么您希望在鼠标悬停在 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。
【讨论】:
您可以通过执行以下操作来停用整个页面的滚动:
<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>
【讨论】:
您可以在 div 上使用 mouseover 事件来禁用 body 滚动条,然后使用 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';
}
【讨论】:
document.body。
如果您应用 overflow: hidden 样式,它应该会消失
编辑:实际上我读错了你的问题,这只会隐藏滚动条,但我认为这不是你要找的。
【讨论】: