Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jquery 滚动DIV元素时如何防止页面滚动?_Jquery_Mousewheel - Fatal编程技术网

Jquery 滚动DIV元素时如何防止页面滚动?

Jquery 滚动DIV元素时如何防止页面滚动?,jquery,mousewheel,Jquery,Mousewheel,我已经检查并测试了防止身体在div内滚动的各种功能,并结合了一个应该可以工作的功能 $('.scrollable').mouseenter(function() { $('body').bind('mousewheel DOMMouseScroll', function() { return false; }); $(this).bind('mousewheel DOMMouseScroll', function() { return tr

我已经检查并测试了防止身体在div内滚动的各种功能,并结合了一个应该可以工作的功能

$('.scrollable').mouseenter(function() {
    $('body').bind('mousewheel DOMMouseScroll', function() {
        return false;
    });
    $(this).bind('mousewheel DOMMouseScroll', function() {
        return true;
    });
});
$('.scrollable').mouseleave(function() {
    $('body').bind('mousewheel DOMMouseScroll', function() {
        return true;
    });
});
  • 这将停止所有的滚动,因为我希望在容器内仍然可以滚动
  • 这也不会在鼠标离开时停用
有什么想法或更好的方法吗?

看看这是否有助于您:

演示:

编辑:

试试这个:

    $("body").delegate("div.scrollable","mouseover mouseout", function(e){
       if(e.type === "mouseover"){
           $('body').bind('mousewheel',function(){
               return false;
           });
       }else if(e.type === "mouseout"){
           $('body').bind('mousewheel',function(){
               return true;
           });
       }
    });

更新2:我的解决方案是完全禁用浏览器的本机滚动(当光标位于DIV内时),然后使用JavaScript手动滚动DIV(通过设置其
.scrollTop
属性)。另一种更好的方法是仅选择性地禁用浏览器的滚动,以防止页面滚动,而不是DIV滚动。看看下面Rudie的答案,它演示了这个解决方案


给你:

$( '.scrollable' ).on( 'mousewheel DOMMouseScroll', function ( e ) {
    var e0 = e.originalEvent,
        delta = e0.wheelDelta || -e0.detail;

    this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;
    e.preventDefault();
});
$('.scrollable')。打开('mousewheel-DOMMouseScroll',函数(e){
var e0=e.原始事件,
delta=e0.车轮delta | |-e0.详图;
这个.scrollTop+=(增量<0?1:-1)*30;
e、 预防默认值();
});
现场演示:

因此,您可以手动设置滚动位置,然后仅阻止默认行为(即滚动DIV或整个网页)


更新1:正如Chris在下面的评论中指出的,在较新版本的jQuery中,增量信息嵌套在
.originalEvent
对象中,也就是说,jQuery不再在其自定义事件对象中公开它,我们必须从本机事件对象中检索它。

如果您不关心与旧IE版本(<8)的兼容性,您可以制作一个自定义jQuery插件,然后在溢出元素上调用它

这个解决方案比所提出的一个Šime Vidas有一个优势,因为它不会覆盖滚动行为——它只是在适当的时候阻止滚动

$.fn.isolatedScroll = function() {
    this.bind('mousewheel DOMMouseScroll', function (e) {
        var delta = e.wheelDelta || (e.originalEvent && e.originalEvent.wheelDelta) || -e.detail,
            bottomOverflow = this.scrollTop + $(this).outerHeight() - this.scrollHeight >= 0,
            topOverflow = this.scrollTop <= 0;

        if ((delta < 0 && bottomOverflow) || (delta > 0 && topOverflow)) {
            e.preventDefault();
        }
    });
    return this;
};

$('.scrollable').isolatedScroll();
$.fn.isolatedScroll=function(){
this.bind('mousewheel-DOMMouseScroll',函数(e){
var delta=e.wheelDelta | | | |(e.originalEvent和e.originalEvent.wheelDelta)| |-e.detail,
bottomOverflow=this.scrollTop+$(this.outerHeight()-this.scrollHeight>=0,
topOverflow=this.scrollTop(顶部0&&topOverflow)){
e、 预防默认值();
}
});
归还这个;
};
$('.scrollable').isolatedScroll();

我认为,一个不太老套的解决方案是,当鼠标移到可滚动的div上时,将溢出隐藏在正文上。这将防止正文滚动,但会出现不必要的“跳跃”效果。以下解决方案可以解决这一问题:

jQuery(".scrollable")
    .mouseenter(function(e) {
        // get body width now
        var body_width = jQuery("body").width();
        // set overflow hidden on body. this will prevent it scrolling
        jQuery("body").css("overflow", "hidden"); 
        // get new body width. no scrollbar now, so it will be bigger
        var new_body_width = jQuery("body").width();
        // set the difference between new width and old width as padding to prevent jumps                                     
        jQuery("body").css("padding-right", (new_body_width - body_width)+"px");
    })
    .mouseleave(function(e) {
        jQuery("body").css({
            overflow: "auto",
            padding-right: "0px"
        });
    })

如果需要,您可以使代码更智能。例如,您可以测试主体是否已经有填充,如果是,则向其添加新填充

我认为有时可以取消鼠标滚动事件:

$elem.on('wheel',函数(e){
var d=e.originalEvent.deltaY,
dir=d<0?'up':'down',
stop=(dir='up'&&this.scrollTop==0)|
(dir=='down'&&this.scrollTop==this.scrollHeight this.offsetHeight);
停止(&e.preventDefault();
});
在事件处理程序中,您需要知道:

  • 滚动方向
    d=e.originalEvent.deltaY,dir=d<0?“向上“:“向下”
    因为正数表示向下滚动
  • 滚动位置
    scrollTop
    用于顶部,
    scrollHeight-scrollTop-offsetHeight
    用于底部
如果你是

  • 向上滚动,并且
    top=0
    ,或者
  • 向下滚动,并且
    bottom=0
取消事件:
e.preventDefault()
(甚至可能
e.stopPropagation()

我认为最好不要忽略浏览器的滚动行为。仅在适用时取消


这可能不是完美的xbrowser,但不会很难。也许Mac的双滚动方向很棘手…

这是我在应用程序中使用的解决方案

我禁用了body溢出,并将整个网站html放在container div中。网站容器溢出,因此用户可以按预期滚动页面

然后我创建了一个具有更高z索引的兄弟div(#Prevent),它覆盖了整个网站。由于#Prevent具有更高的z索引,因此它与网站容器重叠。当“阻止”可见时,鼠标不再悬停在网站容器上,因此无法滚动

当然,您可以在标记中放置另一个div,例如modal,其z索引高于#Prevent。这允许您创建不会出现滚动问题的弹出窗口

此解决方案更好,因为它不会隐藏滚动条(跳跃效果)。它不需要事件监听器,而且易于实现。它在所有浏览器中都能工作,不过在IE7和IE8中,您必须进行操作(取决于您的特定代码)

html

jquery/js

function PreventScroll(A) { 
  switch (A) {
    case 'on': $('#Prevent').show(); break;
    case 'off': $('#Prevent').hide(); break;
  }
}
禁用/启用滚动

PreventScroll('on'); // prevent scrolling
PreventScroll('off'); // allow scrolling

Vidas答案的纯javascript版本,
el$
是您正在滚动的平面的DOM节点

function onlyScrollElement(event, el$) {
    var delta = event.wheelDelta || -event.detail;
    el$.scrollTop += (delta < 0 ? 1 : -1) * 10;
    event.preventDefault();
}

注意事项,如果每次附加函数之前都重新初始化该函数,则该函数需要有一个常量,即
var func=function(…)
removeEventListener将无法工作。

无需JavaScript即可完成此操作。您可以将两个div上的样式设置为
位置:fixed
overflow-y:auto
。您可能需要通过设置其
z-index
(如果它们重叠)使其中一个高于另一个


以下是。

在上面的解决方案中,关于Firefox有一个小错误。在Firefox中,“DOMMouseScroll”事件没有e.detail属性,要获得此属性,您应该编写以下“e.origina”
body { overflow: hidden; }

#YourModal {
 z-index:200;
 /* modal styles here */
}

#Prevent {
 z-index:100;
 position:absolute;
 left:0px;
 height:100%;
 width:100%;
 background:transparent;
}

#WebsiteContainer {
  z-index:50;
  overflow:auto;
  position: absolute;
  height:100%;
  width:100%;
}
#Website {
  position:relative;
}
function PreventScroll(A) { 
  switch (A) {
    case 'on': $('#Prevent').show(); break;
    case 'off': $('#Prevent').hide(); break;
  }
}
PreventScroll('on'); // prevent scrolling
PreventScroll('off'); // allow scrolling
function onlyScrollElement(event, el$) {
    var delta = event.wheelDelta || -event.detail;
    el$.scrollTop += (delta < 0 ? 1 : -1) * 10;
    event.preventDefault();
}
var ul$ = document.getElementById('yo-list');
// IE9, Chrome, Safari, Opera
ul$.removeEventListener('mousewheel', onlyScrollElement);
ul$.addEventListener('mousewheel', onlyScrollElement);
// Firefox
ul$.removeEventListener('DOMMouseScroll', onlyScrollElement);
ul$.addEventListener('DOMMouseScroll', onlyScrollElement);
$.fn.isolatedScroll = function() {
    this.on('mousewheel DOMMouseScroll', function (e) {
        var delta = e.wheelDelta || (e.originalEvent && e.originalEvent.wheelDelta) || -e.originalEvent.detail,
            bottomOverflow = (this.scrollTop + $(this).outerHeight() - this.scrollHeight) >= 0,
            topOverflow = this.scrollTop <= 0;

        if ((delta < 0 && bottomOverflow) || (delta > 0 && topOverflow)) {
            e.preventDefault();
        }
    });
    return this;
};
var scrollable = document.querySelector('.scrollable');

scrollable.addEventListener('wheel', function(event) {
    var deltaY = event.deltaY;
    var contentHeight = scrollable.scrollHeight;
    var visibleHeight = scrollable.offsetHeight;
    var scrollTop = scrollable.scrollTop;

    if (scrollTop === 0 && deltaY < 0)
        event.preventDefault();
    else if (visibleHeight + scrollTop === contentHeight && deltaY > 0)
        event.preventDefault();
});
$( '.scrollable' ).on( 'mousewheel DOMMouseScroll', function ( e ) {
    if($(this).prop('scrollHeight') > $(this).height())
    {
        var e0 = e.originalEvent, delta = e0.wheelDelta || -e0.detail;

        this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;
        e.preventDefault();
    }       
});
$('#target').scrollLock();
    <!-- HTML -->
<div data-scrollLock
     data-strict='true'
     data-selector='.child'
     data-animation='{"top":"top locked","bottom":"bottom locked"}'
     data-keyboard='{"tabindex":0}'
     data-unblock='.inner'>
     ...
</div>

<!-- JavaScript -->
<script type="text/javascript">
  $('[data-scrollLock]').scrollLock()
</script>
//listen mouse on and mouse off for the button
pxMenu.addEventListener("mouseover", toggleA1);
pxOptContainer.addEventListener("mouseout", toggleA2);
//show / hide the pixel option menu
function toggleA1(){
  pxOptContainer.style.display = "flex";
  body.style.overflow = "hidden";
}
function toggleA2(){
  pxOptContainer.style.display = "none";
  body.style.overflow = "hidden scroll";
}
e.preventDefault();