我想让我的身体在使用鼠标滚轮时停止滚动,而我的网站上的Modal(来自http://twitter.github.com/bootstrap)是打开的。

当模式被打开时,我试图调用下面的javascript片段,但没有成功

$(window).scroll(function() { return false; });

AND

$(window).live('scroll', function() { return false; });

请注意,我们的网站放弃了对IE6的支持,IE7+需要兼容。


当前回答

如果modal的高度/宽度为100%,“mouseenter/leave”可以很容易地启用/禁用滚动。这对我来说真的很管用:

var currentScroll=0;
function lockscroll(){
    $(window).scrollTop(currentScroll);
} 
$("#myModal").mouseenter(function(){
    currentScroll=$(window).scrollTop();
    $(window).bind('scroll',lockscroll); 
}).mouseleave(function(){
    currentScroll=$(window).scrollTop();
    $(window).unbind('scroll',lockscroll); 
});

其他回答

对于那些想知道如何获得滚动事件的引导3模态:

$(".modal").scroll(function() {
    console.log("scrolling!);
});

这是我的香草JS解决方案基于@jpap jquery:

let bodyElement = document.getElementsByTagName('body')[0];

// lock body scroll
    let width = bodyElement.scrollWidth;
    bodyElement.classList.add('overflow-hidden');
    bodyElement.style.width = width + 'px';

// unlock body scroll
    bodyElement.classList.remove('overflow-hidden');
    bodyElement.style.width = 'auto';

我读的大多数答案都是关于React的。

我的React功能组件的最佳解决方案是使用@arcticmatt最初提供的解决方案

我在下面的代码示例中包含了一些在其他答案中提到的改进(注意useEffect定义):

import {useEffect, useRef} from "react";

export default function PopoverMenu({className, handleClose, children}) {
  const selfRef = useRef(undefined);

  useEffect(() => {
    const isPopoverOpenned = selfRef.current?.style.display !== "none";
    const focusedElement = document?.activeElement;
    const scrollPosition = {x: window.scrollX, y: window.scrollY};
    if (isPopoverOpenned) {
      preventDocBodyScrolling();
    } else {
      restoreDocBodyScrolling();
    }

    function preventDocBodyScrolling() {
      const width = document.body.clientWidth;
      const hasVerticalScrollBar = (window.innerWidth > document.documentElement.clientWidth);
      document.body.style.overflowX = "hidden";
      document.body.style.overflowY = hasVerticalScrollBar ? "scroll" : "";
      document.body.style.width = `${width}px`;
      document.body.style.position = "fixed";

    }

    function restoreDocBodyScrolling() {
      document.body.style.overflowX = "";
      document.body.style.overflowY = "";
      document.body.style.width = "";
      document.body.style.position = "";
      focusedElement?.focus();
      window.scrollTo(scrollPosition.x, scrollPosition.y);
    }


    return () => {
      restoreDocBodyScrolling(); // cleanup on unmount
    };
  }, []);

  return (
    <>
      <div
        className="backdrop"
        onClick={() => handleClose && handleClose()}
      />
      <div
        className={`pop-over-menu${className ? (` ${className}`) : ""}`}
        ref={selfRef}
      >
        <button
          className="pop-over-menu--close-button" type="button"
          onClick={() => handleClose && handleClose()}
        >
          X
        </button>
        {children}
      </div>
    </>
  );
}

大部分的片段都在这里,但我没有看到任何答案把它们放在一起。

这个问题有三个方面。

(1)防止底层页面滚动

$('body').css('overflow', 'hidden')

(2)并移除滚动条

var handler = function (e) { e.preventDefault() }
$('.modal').bind('mousewheel touchmove', handler)

(3)模态解散时进行清理

$('.modal').unbind('mousewheel touchmove', handler)
$('body').css('overflow', '')

如果模式不是全屏,那么将.modal绑定应用到全屏覆盖。

警告:下面的选项与Bootstrap v3.0无关。X,因为在这些版本中滚动被显式地限制在模态本身。如果禁用轮事件,可能会无意中阻止一些用户在高度大于视口高度的模态中查看内容。


还有另一个选择:车轮事件

滚动事件不可取消。但是,可以取消鼠标滚轮和滚轮事件。需要注意的是,并不是所有的传统浏览器都支持它们,Mozilla最近才在Gecko 17.0中添加了对后者的支持。我不知道它们的全部分布,但IE6+和Chrome确实支持它们。

下面是如何利用它们的方法:

$('#myModal')
  .on('shown', function () {
    $('body').on('wheel.modal mousewheel.modal', function () {
      return false;
    });
  })
  .on('hidden', function () {
    $('body').off('wheel.modal mousewheel.modal');
  });

JSFiddle