我正在使用scrollTo jQuery插件,想知道是否有可能通过Javascript暂时禁用窗口元素上的滚动?我想禁用滚动的原因是,当你滚动而scrollTo是动画,它变得非常难看;)
当然,我可以做$("body").css("overflow", "hidden");然后当动画停止时把它放回自动,但如果滚动条仍然可见但不活跃会更好。
我正在使用scrollTo jQuery插件,想知道是否有可能通过Javascript暂时禁用窗口元素上的滚动?我想禁用滚动的原因是,当你滚动而scrollTo是动画,它变得非常难看;)
当然,我可以做$("body").css("overflow", "hidden");然后当动画停止时把它放回自动,但如果滚动条仍然可见但不活跃会更好。
当前回答
无法取消滚动事件。但是你可以通过取消这些交互事件来实现: 鼠标和触摸滚动和与滚动相关的按钮。
(工作演示)
// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {37: 1, 38: 1, 39: 1, 40: 1};
function preventDefault(e) {
e.preventDefault();
}
function preventDefaultForScrollKeys(e) {
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
}
// modern Chrome requires { passive: false } when adding event
var supportsPassive = false;
try {
window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
get: function () { supportsPassive = true; }
}));
} catch(e) {}
var wheelOpt = supportsPassive ? { passive: false } : false;
var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';
// call this to Disable
function disableScroll() {
window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF
window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop
window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile
window.addEventListener('keydown', preventDefaultForScrollKeys, false);
}
// call this to Enable
function enableScroll() {
window.removeEventListener('DOMMouseScroll', preventDefault, false);
window.removeEventListener(wheelEvent, preventDefault, wheelOpt);
window.removeEventListener('touchmove', preventDefault, wheelOpt);
window.removeEventListener('keydown', preventDefaultForScrollKeys, false);
}
更新:固定Chrome桌面和现代移动浏览器被动监听器
其他回答
无法取消滚动事件。但是你可以通过取消这些交互事件来实现: 鼠标和触摸滚动和与滚动相关的按钮。
(工作演示)
// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {37: 1, 38: 1, 39: 1, 40: 1};
function preventDefault(e) {
e.preventDefault();
}
function preventDefaultForScrollKeys(e) {
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
}
// modern Chrome requires { passive: false } when adding event
var supportsPassive = false;
try {
window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
get: function () { supportsPassive = true; }
}));
} catch(e) {}
var wheelOpt = supportsPassive ? { passive: false } : false;
var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';
// call this to Disable
function disableScroll() {
window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF
window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop
window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile
window.addEventListener('keydown', preventDefaultForScrollKeys, false);
}
// call this to Enable
function enableScroll() {
window.removeEventListener('DOMMouseScroll', preventDefault, false);
window.removeEventListener(wheelEvent, preventDefault, wheelOpt);
window.removeEventListener('touchmove', preventDefault, wheelOpt);
window.removeEventListener('keydown', preventDefaultForScrollKeys, false);
}
更新:固定Chrome桌面和现代移动浏览器被动监听器
这里有一个非常基本的方法:
window.onscroll = function () { window.scrollTo(0, 0); };
在IE6中有点不稳定。
这个解决方案将保持当前的滚动位置,而滚动是禁用的,不像有些跳回用户顶部。
它是基于galambalazs的答案,但支持触摸设备,并重构为一个单一的对象与jquery插件包装。
演示。
在github上。
/**
* $.disablescroll
* Author: Josh Harrison - aloof.co
*
* Disables scroll events from mousewheels, touchmoves and keypresses.
* Use while jQuery is animating the scroll position for a guaranteed super-smooth ride!
*/
;(function($) {
"use strict";
var instance, proto;
function UserScrollDisabler($container, options) {
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
// left: 37, up: 38, right: 39, down: 40
this.opts = $.extend({
handleKeys : true,
scrollEventKeys : [32, 33, 34, 35, 36, 37, 38, 39, 40]
}, options);
this.$container = $container;
this.$document = $(document);
this.lockToScrollPos = [0, 0];
this.disable();
}
proto = UserScrollDisabler.prototype;
proto.disable = function() {
var t = this;
t.lockToScrollPos = [
t.$container.scrollLeft(),
t.$container.scrollTop()
];
t.$container.on(
"mousewheel.disablescroll DOMMouseScroll.disablescroll touchmove.disablescroll",
t._handleWheel
);
t.$container.on("scroll.disablescroll", function() {
t._handleScrollbar.call(t);
});
if(t.opts.handleKeys) {
t.$document.on("keydown.disablescroll", function(event) {
t._handleKeydown.call(t, event);
});
}
};
proto.undo = function() {
var t = this;
t.$container.off(".disablescroll");
if(t.opts.handleKeys) {
t.$document.off(".disablescroll");
}
};
proto._handleWheel = function(event) {
event.preventDefault();
};
proto._handleScrollbar = function() {
this.$container.scrollLeft(this.lockToScrollPos[0]);
this.$container.scrollTop(this.lockToScrollPos[1]);
};
proto._handleKeydown = function(event) {
for (var i = 0; i < this.opts.scrollEventKeys.length; i++) {
if (event.keyCode === this.opts.scrollEventKeys[i]) {
event.preventDefault();
return;
}
}
};
// Plugin wrapper for object
$.fn.disablescroll = function(method) {
// If calling for the first time, instantiate the object and save
// reference. The plugin can therefore only be instantiated once per
// page. You can pass options object in through the method parameter.
if( ! instance && (typeof method === "object" || ! method)) {
instance = new UserScrollDisabler(this, method);
}
// Instance already created, and a method is being explicitly called,
// e.g. .disablescroll('undo');
else if(instance && instance[method]) {
instance[method].call(instance);
}
};
// Global access
window.UserScrollDisabler = UserScrollDisabler;
})(jQuery);
我知道这是一个老问题,但我不得不做一些非常相似的事情,在花了一段时间寻找答案并尝试了不同的方法后,我最终使用了一个非常简单的解决方案。
我的问题非常相似,几乎相同,唯一的区别是我不需要实际显示滚动条-我只需要确保它的宽度仍然被使用,所以当我的覆盖显示时,页面的宽度不会改变。
当我开始滑动覆盖到屏幕,我做:
$('body').addClass('stop-scrolling').css('margin-right', 8);
在我将覆盖层从屏幕上滑动后,我这样做:
$('body').removeClass('stop-scrolling').css('margin-right', 0);
重要:这是完美的工作,因为我的叠加是绝对定位,对:0px时可见。
根据galambalazs的帖子,我将添加对触摸设备的支持,允许我们触摸但不能上下滚动:
function disable_scroll() {
...
document.ontouchmove = function(e){
e.preventDefault();
}
}
function enable_scroll() {
...
document.ontouchmove = function(e){
return true;
}
}