英特网校

弹出层弹出时弹出层的内容滚动,同时禁止body内容滚动

一、子元素scroll父元素容器不跟随滚动【子元素没有滚动条时】

子元素scroll父元素容器不跟随滚动原理:滚动到边缘通过preventDefault()阻止浏览器的默认行为达到我们想要的效果。此方法可以解决pc端和移动端,但是当子元素出现滚动效果时不支持!

 1、添加html

<body>
		<button class="show">按钮</button>
		1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
		1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
		1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
		1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
		1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
		1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
		1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
		1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
		1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
		<div class="dialog">
			
		</div>
	</body>

2、点击按钮时显示dialog的弹窗,并将html和body的 overflow: hidden;

$(".show").click(function(){
	$(".dialog").show()
	$('html,body').css('overflow','hidden');
})

设置好后,在pc端和pc端手机模拟器中测试正常,但是在ios的Safari等浏览器下会失效,解决方法我们可以在浮层touchmove的时候,阻止默认事件达到避免滚动的问题,例如:

$('.dialog').on('touchmove', function(event) {
    event.preventDefault();
});

这样就可以解决子元素scroll父元素容器不跟随滚动【子元素没有滚动条时】

二、子元素scroll父元素容器不跟随滚动【子元素有滚动条时】

这里利用张鑫旭提供的方法来处理:

https://www.zhangxinxu.com/wordpress/2016/12/web-mobile-scroll-prevent-window-js-css/转载

1、添加html内容

<button class="show">按钮</button>
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
<div class="dialogBox">
<div class="dialog">
<ul>
	<li>111</li><li>111</li><li>111</li><li>111</li><li>111</li>
	<li>111</li><li>111</li><li>111</li><li>111</li><li>111</li>
	<li>111</li><li>111</li><li>111</li><li>111</li><li>111</li>
	<li>111</li><li>111</li><li>111</li><li>111</li><li>111</li>
	<li>111</li><li>111</li><li>111</li><li>111</li><li>111</li>
	<li>111</li><li>111</li><li>111</li><li>111</li><li>111</li>
	<li>111</li><li>111</li><li>111</li><li>111</li><li>111</li>
	<li>111</li><li>111</li><li>111</li><li>111</li><li>111</li>
	<li>111</li><li>111</li><li>111</li><li>111</li><li>111</li>
</ul>
</div>
</div>

2、添加css样式

.dialog{position: fixed;width: 300px;height: 300px;background: red;top:50%;margin-top:-150px;
left:50%;margin-left:-150px;overflow: auto;
-webkit-overflow-scrolling: touch;z-index: 999;
}
.dialogBox{position: fixed;top:0;right:0;bottom:0;left:0;background: rgba(0,0,0,0.5);
display: none;
}
.dialogBox.active {display: block;}
.noscroll,.noscroll body {overflow: hidden;}
.noscroll body {position: relative;}

注意点:dialogBox为弹窗的父级窗口,窗口的大小和屏幕大小一致,同时设置他的透明背景

3、引入js代码,此代码中的var events = event.touches[0] || event(有两处)都需要替换成var events=event.originalEvent.targetTouches[0] || event;因为我们如果有jquery时会报取不到0的下标,如果引用的是zepto.js则可以正常使用。

 $.smartScroll = function(container, selectorScrollable) {
    // 如果没有滚动容器选择器,或者已经绑定了滚动时间,忽略
    if (!selectorScrollable || container.data('isBindScroll')) {
        return;
    }

    // 是否是搓浏览器
    // 自己在这里添加判断和筛选
    var isSBBrowser;

    var data = {
        posY: 0,
        maxscroll: 0
    };

    // 事件处理
    container.on({
        touchstart: function (event) {
//          var events = event.touches[0] || event;
            var events=event.originalEvent.targetTouches[0] || event;

            // 先求得是不是滚动元素或者滚动元素的子元素
            var elTarget = $(event.target);

            if (!elTarget.length) {
                return;
            }

            var elScroll;

            // 获取标记的滚动元素,自身或子元素皆可
            if (elTarget.is(selectorScrollable)) {
                elScroll = elTarget;
            } else if ((elScroll = elTarget.parents(selectorScrollable)).length == 0) {
                elScroll = null;
            }

            if (!elScroll) {
                return;
            }

            // 当前滚动元素标记
            data.elScroll = elScroll;

            // 垂直位置标记
            data.posY = events.pageY;
            data.scrollY = elScroll.scrollTop();
            // 是否可以滚动
            data.maxscroll = elScroll[0].scrollHeight - elScroll[0].clientHeight;
        },
        touchmove: function (event) {
            // 如果不足于滚动,则禁止触发整个窗体元素的滚动
            if (data.maxscroll <= 0 || isSBBrowser) {
                // 禁止滚动
                event.preventDefault();
            }
            // 滚动元素
            var elScroll = data.elScroll;
            // 当前的滚动高度
            var scrollTop = elScroll.scrollTop();

            // 现在移动的垂直位置,用来判断是往上移动还是往下
//          var events = event.touches[0] || event;
            var events=event.originalEvent.targetTouches[0] || event;
            // 移动距离
            var distanceY = events.pageY - data.posY;

            if (isSBBrowser) {
                elScroll.scrollTop(data.scrollY - distanceY);
                elScroll.trigger('scroll');
                return;
            }

            // 上下边缘检测
            if (distanceY > 0 && scrollTop == 0) {
                // 往上滑,并且到头
                // 禁止滚动的默认行为
                event.preventDefault();
                return;
            }

            // 下边缘检测
            if (distanceY < 0 && (scrollTop + 1 >= data.maxscroll)) {
                // 往下滑,并且到头
                // 禁止滚动的默认行为
                event.preventDefault();
                return;
            }
        },
        touchend: function () {
            data.maxscroll = 0;
        }
    });

    // 防止多次重复绑定
    container.data('isBindScroll', true);
};

4、添加按钮的点击事件

$(".show").click(function(){
    $(".dialogBox").show()
    $.smartScroll($('.dialogBox'), '.dialog');//调用smartScroll函数解决滚动问题
    $('html').addClass('noscroll');//添加noscroll样式,实际给html和body添加overflow: hidden;
})
$(".dialogBox").click(function(){//点击透明背景处理事件
    $(".dialogBox").hide()
    $('html').removeClass('noscroll');
})
$(".dialog li").click(function(event){	
//子元素里内容点击,添加return false防止点击触发dialogBox的点击事件			
    return false;
})
$.smartScroll(container, selectorScrollable);

container表示委托的浮层容器元素($包装器对象),或者页面其他比较祖先的元素,但是,非常不建议使用$(document)或者$(document.body)等对象作为委托容器

评论中心

登录后可评论,请 登录 注册