我正在使用scrollTo jQuery插件,想知道是否有可能通过Javascript暂时禁用窗口元素上的滚动?我想禁用滚动的原因是,当你滚动而scrollTo是动画,它变得非常难看;)
当然,我可以做$("body").css("overflow", "hidden");然后当动画停止时把它放回自动,但如果滚动条仍然可见但不活跃会更好。
我正在使用scrollTo jQuery插件,想知道是否有可能通过Javascript暂时禁用窗口元素上的滚动?我想禁用滚动的原因是,当你滚动而scrollTo是动画,它变得非常难看;)
当然,我可以做$("body").css("overflow", "hidden");然后当动画停止时把它放回自动,但如果滚动条仍然可见但不活跃会更好。
当前回答
为了防止跳楼,我用了这个
export function toggleBodyScroll(disable) {
if (!window.tempScrollTop) {
window.tempScrollTop = window.pageYOffset;
// save the current position in a global variable so I can access again later
}
if (disable) {
document.body.classList.add('disable-scroll');
document.body.style.top = `-${window.tempScrollTop}px`;
} else {
document.body.classList.remove('disable-scroll');
document.body.style.top = `0px`;
window.scrollTo({top: window.tempScrollTop});
window.tempScrollTop = 0;
}
}
在CSS中
.disable-scroll {
height: 100%;
overflow: hidden;
width: 100%;
position: fixed;
}
其他回答
Galambalazs的解决方案很棒!它在Chrome和Firefox中都非常适合我。它还可以扩展,以防止来自浏览器窗口的任何默认事件。 假设你在画布上做一个应用。你可以这样做:
var events = {
preventDefault: function(e) {
e = e || window.event;
if (e.preventDefault) e.preventDefault();
e.returnValue = false;
},
//spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36,
//left: 37, up: 38, right: 39, down: 40
keys: [32, 33, 34, 35, 36, 37, 38, 39, 40],
keydown: function(e) {
for (var i = events.keys.length; i--;) {
if (e.keyCode === events.keys[i]) {
events.preventDefault(e);
return;
}
}
},
wheel: function(e) {
events.preventDefault(e);
},
disable: function() {
if (window.addEventListener) {
window.addEventListener('DOMMouseScroll', events.wheel, false);
}
window.onmousewheel = document.onmousewheel = events.wheel;
document.onkeydown = helpers.events.keydown;
},
enable: function() {
if (window.removeEventListener) {
window.removeEventListener('DOMMouseScroll', events.wheel, false);
}
window.onmousewheel = document.onmousewheel = document.onkeydown = null;
}
}
然后在你的应用程序中,假设你要处理你自己的事件,比如鼠标、键盘、触摸事件等等。你可以在鼠标进入画布时禁用默认事件,并在鼠标离开时重新启用它们:
function setMouseEvents(canvas) {
var useCapture = false;
//Mouse enter event
canvas.addEventListener('mouseenter', function(event) {
events.disable();
}, useCapture);
//Mouse leave event
canvas.addEventListener('mouseleave', function(event) {
events.enable();
}, useCapture);
}
你甚至可以禁用右键菜单与此hack:
function disableRightClickMenu(canvas) {
var my_gradient = canvas.context.createLinearGradient(0, 0, 0, 225);
my_gradient.addColorStop(0, "white");
my_gradient.addColorStop(1, "white");
canvas.context.fillStyle = my_gradient;
canvas.context.fillRect(0, 0, canvas.width, canvas.height);
canvas.oncontextmenu = function() { return false; };
}
使用Javascript函数切换overflowY,同时切换移动菜单的可见性。比如这个:
function handleClickMobileMenu() {
document.body.style.overflowY = isMobileMenuOpen ? "hidden" : "scroll";
//...
}
在打开和关闭移动菜单时调用该函数。 最好的用例是当你的移动菜单是完全视口区域。
您可以阻止空格条滚动和隐藏浏览器滚动条:
$(document).keydown(function(event) {
if (event.keyCode == 32) {
return false;
}
});
document.documentElement.style.overflow = 'hidden';
document.body.scroll = 'no';
我在移动屏幕上有类似的动画问题,但在笔记本电脑上没有,当尝试使用jquery的animate命令动画一个div时。所以我决定使用一个计时器来频繁地恢复窗口的滚动位置,这样肉眼就能看到文档是静态的。这一解决方案在三星Galaxy-2或iphone-5等小屏幕移动设备上运行良好。
该方法的主要逻辑:设置窗口滚动位置到原始滚动位置的定时器应该在jquery animate命令之前启动,然后当动画完成时,我们需要清除这个定时器(原始滚动位置是动画开始之前的位置)。
我惊喜地发现,如果计时器间隔为1毫秒,文档在动画持续时间内实际上是静态的,这正是我的目标。
//get window scroll position prior to animation
//so we can keep this position during animation
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;
//NOTE:restoreTimer needs to be global variable
//start the restore timer
restoreTimer = setInterval(function() {
window.scrollTo(xPosition, yPosition);
}, 1);
//animate the element emt
emt.animate({
left: "toggle",
top: "toggle",
width: "toggle",
height: "toggle"
}, 500, function() {
//when animation completes, we stop the timer
clearInterval(restoreTimer);
});
另一个有效的解决方案:根据Mohammad Anini在这篇文章中关于启用/禁用滚动的回答,我还发现修改后的代码版本如下所示有效。
//get current scroll position
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;
//disable scrolling
window.onscroll = function() {
window.scrollTo(xPosition, yPosition);
};
//animate and enable scrolling when animation is completed
emt.animate({
left: "toggle",
top: "toggle",
width: "toggle",
height: "toggle"
}, 500, function() {
//enable scrolling when animation is done
window.onscroll = function() {};
});
我知道这是一个老问题,但我不得不做一些非常相似的事情,在花了一段时间寻找答案并尝试了不同的方法后,我最终使用了一个非常简单的解决方案。
我的问题非常相似,几乎相同,唯一的区别是我不需要实际显示滚动条-我只需要确保它的宽度仍然被使用,所以当我的覆盖显示时,页面的宽度不会改变。
当我开始滑动覆盖到屏幕,我做:
$('body').addClass('stop-scrolling').css('margin-right', 8);
在我将覆盖层从屏幕上滑动后,我这样做:
$('body').removeClass('stop-scrolling').css('margin-right', 0);
重要:这是完美的工作,因为我的叠加是绝对定位,对:0px时可见。