• 页面出现滚动条时,body里面的内容不能自动居中?


    弹窗后允许页面滚动

    这种方式通常使用 position: absolute; ,可以看看我做的这个 Demo。主要用来应对弹窗内容很大很多的情况,超过了屏幕的宽高需要产生滚动条来方便浏览者查看。有一些图片弹窗插件使用这种方式,使用 JS 动态计算弹窗内容块的位置,这样即便是内容块很大,也不会造成信息缺失。

    但是居中往往需要 JS 配合或者进行位置、尺寸处理,会稍微麻烦一些。

    弹窗后不允许页面滚动

    你可以通过为内容块设置 position: fixed; 使其虽然滚动了,但内容块仍然居中显示,给人一种没有滚动的感觉,还是刚刚的 Demo 注释掉然后修改一下就可以看到。

    也可以为 html、body 标签设置 overflow-y: hidden; 属性,使其滚动条消失,无法滚动。

    通常来说,一般都要使用 hidden 来隐藏滚动条禁止滚动,然后使用 absolute 或者 fixed 就看你自己的需求来选择。但是,对 html 或 body 设置 overflow-y: hidden; 之后,由于滚动条没有了,宽度变宽,页面内容会整体偏移一点,虽然只是一点,但是很明显。这简直太影响用户体验了!!

    去掉滚动条但是避免页面内容偏移

    知乎上前段时间也提到了这个问题:如何禁止浏览器滚动条滚动,但是又不让它消失?。其中比较简单方便的就是 TQ 学长的回答,但是实际测试并不完美,因为 chrome 浏览器的滚动条是 15px 像素宽,而 firefox 浏览器是 17px 像素。如果统一设置成 17px 的话,chrome 等浏览器中显然还会偏移 2px ,虽然尽力完善了,但还是有点小偏移,受不了。

    既然不同浏览器里面滚动条宽度不同,那可否先用 JS 检测操作系统和浏览器,然后再根据判断的浏览器等设置不同的偏移量?大体思路是对的,但是方法是错的。检测操作系统和浏览器,要判断的情况太多,代码太过于复杂。于是这个问题就暂时放在这里了。

    偶然刷 twitter 的时候,触发弹窗效果的时候,偶然看到了他们也是采用这种方式隐藏滚动条并且保证不会偏移,经过测试各个浏览器中效果完美。于是分析了一下他们的代码,下面是他们的函数:

    function ScrollbarWidth() {
        this.calculateScrollbarWidth = function() {
            if ($("#scrollbar-width").length > 0) return;
            var a = $('<div class="modal-measure-scrollbar"/>').prependTo($("body")),
            b = $('<div class="inner"/>').appendTo(a),
            c = a.width() - b.width();
            a.remove(),
            $("head").append('<style id="scrollbar-width">        .compensate-for-scrollbar,        .modal-enabled,        .modal-enabled .global-nav-inner,        .profile-editing,        .profile-editing .global-nav-inner,        .overlay-enabled,        .overlay-enabled .global-nav-inner,        .grid-enabled,        .grid-enabled .global-nav-inner,        .gallery-enabled,        .gallery-enabled .global-nav-inner {          margin-right: ' + c + "px      }      </style>")
        }
    }
    

    精简一下主要代码就是

    var a = $('<div class="modal-measure-scrollbar"/>').prependTo($("body")),
    b = $('<div class="inner"/>').appendTo(a),
    c = a.width() - b.width();
    a.remove();
    $("head").append('<style id="scrollbar-width"> .compensate-for-scrollbar{ margin-right:' + c + 'px } </style>');
    

    大体意思就是新建了一个包裹的结构,然后两个宽度相减得到滚动条的宽度,然后输出到 head 中。当有弹窗发生之后,就为 html 标签赋予相应的类来 margin-right 一下,避免滚动条消失引起的内容偏移。

    Great!这才是正解,显然这两个结构需要赋予一定的 CSS,目的要使 .modal-measure-scrollbar 产生滚动条,而 .inner 是不包括滚动条的全宽,他们的差值正好就是滚动条的宽度!

    twitter 中对它们应用的样式如下:

    .modal-measure-scrollbar{
        position: absolute;
        height: 100px;
         100px;
        top: -300px;
        left: -300px;
        overflow: scroll;
        z-index: 1000;
        overflow-y: scroll;
    }
    .modal-measure-scrollbar .inner{
        height: 200px;
    }
    

    不需要解释了吧。

    后来又测试了 fancybox 插件,它的方法更加简单通用,具体代码如下:

    w1 = $(window).width();
    H.addClass('fancybox-lock-test');
    w2 = $(window).width();
    H.removeClass('fancybox-lock-test');
    $("<style type='text/css'>.fancybox-margin{margin-right:" + (w2 - w1) + "px;}</style>").appendTo("head");
    

    其中 H 变量是 $('html') ,大意就是先检测现有宽度,然后再为 html 增加一个类,再检测,然后复原去掉类得到滚动条宽度。大体想一下也可以知道 .fancybox-lock-test 类的代码是这样的:

    .fancybox-lock-test {
        overflow-y: hidden !important;
    }
    

    这种方法更加巧妙简单,不需要创建临时的 DOM 结构,所以强烈推荐在项目中使用这种方式判断。

    此外,还有第三种方法,是来自 QQ 空间的。QQ 空间的相册之类的,也是采用弹窗的,查看了一下他们的实现方式,就是使用的固定的 17px 的偏移值,在其他浏览器中也是 17px 像素。但是使用中很难看到内容的偏移,原因是背景遮罩层太黑了,透明度不高,所以很多细节就忽略掉了。如果你的背景遮罩不是很透明,显然也就不需要处理这了~

    转载:http://yujiangshui.com/review-how-to-make-popup-mask-effect/

  • 相关阅读:
    nginx教程2:日志
    3.1.1 基于监听的事件处理机制
    示例(1)按键和文本框监听
    2.3.3 Button(按钮)与ImageButton(图像按钮)
    2.3.2 EditText(输入框)详解
    2.3.1 TextView(文本框)详解
    2.2.3 TableLayout(表格布局)
    2.2.2 RelativeLayout(相对布局)
    2.2.1 LinearLayout(线性布局)
    2.1 View与ViewGroup的概念
  • 原文地址:https://www.cnblogs.com/xuniannian/p/8404436.html
Copyright © 2020-2023  润新知