防止页面滚动 - 禁用拖动

时间:2015-01-20 19:06:54

标签: javascript jquery

防止滚动脚本

// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = [37, 38, 39, 40];

function preventDefault(e) {
  e = e || window.event;
  if (e.preventDefault)
      e.preventDefault();
  e.returnValue = false;  
}

function keydown(e) {
    for (var i = keys.length; i--;) {
        if (e.keyCode === keys[i]) {
            preventDefault(e);
            return;
        }
    }
}

function wheel(e) {
  preventDefault(e);
}

function disable_scroll() {
  if (window.addEventListener) {
      window.addEventListener('DOMMouseScroll', wheel, false);
  }
  window.onmousewheel = document.onmousewheel = wheel;
  document.onkeydown = keydown;
}

function enable_scroll() {
    if (window.removeEventListener) {
        window.removeEventListener('DOMMouseScroll', wheel, false);
    }
    window.onmousewheel = document.onmousewheel = document.onkeydown = null;  
}

用法

调用disable_scroll();停用页面滚动,然后enable_scroll()再次启用滚动。

问题

与Facebook模式框不同,您仍然可以单击并拖动页面向下滚动。

的jsfiddle

链接:http://jsfiddle.net/2rud0aLm/

2 个答案:

答案 0 :(得分:2)

这是一个相当基本的解决方案,我将解释我已经改变了什么以使其工作:

  1. CSS :对于叠加层,您实际上不需要嗅探视口尺寸。只需设置为position: fixed所有四个偏移,topleftbottomright设置为0将强制它填充屏幕:)
  2. 标记:将所有网页内容整理到一个容器中,例如<div class="page-wrap">。在切换模态框时,此元素设置为固定位置,以防止单击拖动滚动。
  3. JS
    • 将全局变量设置为fromTop,我们将用它来跟踪用户的滚动位置。
    • 打开模态框时,更新滚动位置。隐藏正文元素的垂直溢出,并垂直翻译整个页面内容,即.page-wrap以保留垂直位置
    • 当模态框关闭时,反转我们上面所做的:)我决定在.fadeOut()的末尾使用回调以防止抽搐。
  4. 完成所有这些操作后,您甚至无需阻止滚动事件触发或再次收听按键事件。不用多说,这里是代码(这里是functional demo):

    var fromTop;
    
    $('.modal_2').click(function(){
    
        // Disable scroll and fade in modal box
        disable_scroll();
        $('.block_page').fadeIn();
        $('.modal_box').fadeIn();
    
        // Fetch current scroll position
        fromTop = $(window).scrollTop();
    
        // Hide overflowing vertical content
        $('body').css({
            'overflow-y': 'hidden'
        });
        $('.page-wrap').css({
            'transform': 'translateY(-'+fromTop+'px)'
        });
    });
    $('.modal_close').click(function(e){
        e.preventDefault();
    
        // Enable scroll and fade out modal box
        $('.block_page').fadeOut(function() {
            // Wait for modal box to fade out before reversing things
            // Hide overflowing vertical content
            $('body').css({
                'overflow-y': 'visible'
            });
            $('.page-wrap').css({
                'transform': 'translateY(0)'
            });
            $(window).scrollTop(fromTop);
        });     
        $(this).parent().fadeOut();
        enable_scroll();        
    
    });
    

    概念验证小提琴:http://jsfiddle.net/teddyrised/mjq8gv29/


    更好:使用jQuery promises检查.block_page元素和父元素上是否已完成fadeOut动画。 如果要为任一元素设置可变动画持续时间

    ,这一点非常重要
    $('.modal_close').click(function(e){
        e.preventDefault();
    
        // Enable scroll and fade out modal box
        $('.block_page').fadeOut();     
        $(this).parent().fadeOut();
    
        // Use jQuery promises to check if all fadeOut animation has completed
        var p1 = $('.block_page').promise(),
            p2 = $(this).parent().promise();
    
        // When all animations have completed, reverse effects
        $.when(p1, p2).done(function() {
            // Hide overflowing vertical content
            $('body').css({
                'overflow-y': 'visible'
            });
            $('.page-wrap').css({
                'transform': 'translateY(0)'
            });
            $(window).scrollTop(fromTop);
        });
    });
    

    使用jQuery .promise()延迟对象的高级小提琴:http://jsfiddle.net/teddyrised/2rud0aLm/6/

答案 1 :(得分:2)

@ Terry的第一句话提供了一个快速的解决方案。只需在身体上将overflow更改为“隐藏”即可阻止滚动。

您还需要跟踪窗口的滚动位置,并在更改overflow属性后进行设置。

为防止鼠标滚轮能够拖动,请将scroll事件附加到窗口,该窗口会在打开模态对话框时将scrollTop设置为窗口的位置:

function disable_scroll() {
  var top= $(window).scrollTop();
  $('body').css({
    overflow: 'hidden'
  });
  $(window).scrollTop(top);
  $(window).on('scroll', function() {
    $(window).scrollTop(top);
  });    
}

function enable_scroll() {
  var top= $(window).scrollTop();
  $('body').css({
    overflow: ''
  });
  $(window).scrollTop(top);
  $(window).off('scroll');
}

由于代码中的modal_closemodal_2具有href="#",脚本将尝试跳转到页面顶部。您可以使用preventDefault

来阻止这种情况
$('a[href=#]').on('click', function(ev) {
  ev.preventDefault();
});

Fiddle