zoukankan      html  css  js  c++  java
  • 弹窗查看内容时 内容滚动区域设置为body区

    看到渣浪的查看文章或者查看大图有个效果:弹窗查看内容时,如果内容过长有滚动条,则滚动条会被放到body区滚动

    什么意思呢?

    看个图片,一般正常弹窗是有宽高限制的,如果内容过长则直接在弹窗中进行滚动

    点我预览

    将滚动位置放到整个body中,让弹窗中内容自适应高度

    这么做的好处自然很明显,body区域有更大的可视区域,来看看最后的效果

    点我预览

    那具体是怎么实现呢

    其实不算很难,各位看官可以先想一想能怎么搞

    首先,得先弄一个基本的弹窗逻辑,为了简单,就直接操作了。可以自行封装

    写个HTML结构

    <button class="show-big-img" data-h="300">查看大图 h300</button>
    <button class="show-big-img" data-h="3000">查看大图 h3000</button>
    
    
    <div class="layer-shade"></div>
    <div class="layer-wrap">
        <a href="javascript:;" class="layer-close">&times;</a>
        <div class="layer-content">
            <p class="show-origin-img">
                <a href="javascript:;">查看原图</a>
            </p>
            <div class="big-img">
                <div class="big-img__item">我是图片</div>
            </div>
        </div>
    </div>

    将 layer-shade 看作遮罩,将 layer-wrap看作弹窗,将 layer-content 看作弹窗内容区,将 big-img__item 看作这里的长图片(长内容)

    把样式写好

      1 body {
      2     &.layer-scroll-in-body {
      3         overflow: hidden;
      4     }
      5 }
      6 
      7 .layer-shade {
      8     display: none;
      9     position: fixed;
     10     width: 100%;
     11     height: 100%;
     12     top: 0;
     13     left: 0;
     14     background-color: #000;
     15     opacity: .15;
     16     
     17     &.visible {
     18         display: block;
     19     }
     20 }
     21 
     22 @keyframes bounceIn {
     23     to {
     24         opacity: 1;
     25         transform: scale(1);
     26     }
     27 }
     28 
     29 .layer-wrap {
     30     display: none;
     31     z-index: 1;
     32     position: fixed;    
     33     width: 70%;
     34     height: 50%;
     35     top: 100px;
     36     left: 100px;
     37     background-color: #000;
     38     border-radius: 3px;
     39     
     40     opacity: 0;
     41     transform: scale(.3);
     42     
     43     &.visible {
     44         display: block; 
     45         animation: bounceIn .5s;
     46         animation-fill-mode: both;
     47     }
     48     
     49     &.layer-scroll-in-body {
     50         position: absolute;
     51         height: auto;
     52     }
     53     
     54     &__wrapper {
     55         overflow: auto;
     56         position: fixed;
     57         top: 0;
     58         right: 0;
     59         width: 100%;
     60         height: 100%;
     61     }
     62 }
     63 
     64 .layer-close {
     65     position: absolute;
     66     top: -16px;
     67     right: -12px;
     68     width: 24px;
     69     height: 24px;
     70     text-decoration: none;
     71     color: #fff;
     72     background: #999;
     73     border-radius: 50%;
     74     border: 3px solid #fff;
     75     text-align: center;
     76     line-height: 22px;
     77     font-size: 22px;
     78     
     79     &:hover {
     80         background-color: #358eea;
     81     }
     82 }
     83 
     84 .layer-content {
     85     height: 100%;
     86     overflow: auto;
     87 }
     88 
     89 .show-origin-img {
     90     position: absolute;
     91     top: 5px;
     92     right: 20px;
     93     font-size: 12px;
     94     
     95     a {
     96         color: #fff;
     97         text-decoration: none;
     98         
     99         &:hover {
    100             text-decoration: underline;
    101         }
    102     }
    103     
    104 }
    105 
    106 .big-img {
    107     display: flex;
    108     justify-content: center;
    109     box-sizing: border-box;
    110     padding: 20px;
    111     
    112     &__item {
    113         display: flex;
    114         justify-content: center;
    115         align-items: center;
    116         max-width: 100%;
    117         width: 300px;
    118         height: 3000px;
    119         background-color: #c7bdb3;
    120     }
    121 }

    最后加上JS操作逻辑

    // 显示弹窗
    function showLayer(onShow, onClose) {
        var $body = $('body'),
            $layerShade = $('.layer-shade'),
            $layerWrap = $('.layer-wrap');
        
        // 查看大图
        $('.show-big-img').click(function() {
            $layerWrap.find('.big-img__item').css('height', $(this).attr('data-h'));
            
            // 显示前处理
            if (onShow && typeof onShow === 'function') {
                onShow($body, $layerWrap);
            }
           
            $layerShade.addClass('visible');
            $layerWrap.addClass('visible');
        });
    
        $('.layer-close').click(function() {
            // 关闭前处理
            if (onClose && typeof onClose === 'function') {
                onClose($body, $layerWrap);
            }
            
            $layerShade.removeClass('visible');    
            $layerWrap.removeClass('visible');
        });
    }
    
    // 显示弹窗,并设置弹窗内容滚动区为body区
    function showLayerScrollInBody(setPageScroll) {
        // 模拟:确保显示弹窗前页面由垂直方向滚动条
        setPageScroll && $('.show-big-img').css('margin-bottom', 2000);
        
        showLayer(function($body, $layer) {
            // body设置 overflow: hidden
            $body.addClass('layer-scroll-in-body');
            
            $layer
                .addClass('layer-scroll-in-body')
                // 弹出层增加一层父级
                .wrap('<div class="layer-wrap__wrapper">');
        }, function($body, $layer) {
            // 关闭弹窗,则恢复
            $body.removeClass('layer-scroll-in-body');
            
            $layer
                .removeClass('layer-scroll-in-body')
                .unwrap();
        });
    }
    
    
    showLayer();
    
    /* showLayerScrollInBody(); */
    
    /* showLayerScrollInBody(true); */

    代码不算太复杂,如果到这里为止已经看懂的话,应该不需要再往下看了

    一般的弹窗实现,需要设置遮罩层和弹窗的position为fixed,才能更好地保证页面有滚动条的时候位置不会出错。

    fixed之后,弹窗的最大高度为视窗高度,若要使得弹窗的内容区直接显示出来,就必须设置为非fixed值,而弹窗不能少了定位,那就只能使用 absolute值了

    但设置了absolute就无法计算页面有滚动条的时候的位置,所以需要给弹窗包裹一层父级,设置为fixed,则弹窗基于此父级来定位,相应的 top 和 left 值无需改变

    $layer.wrap('<div class="layer-wrap__wrapper">');
    &__wrapper {
            overflow: auto;
            position: fixed;
            top: 0;
            right: 0;
            width: 100%;
            height: 100%;
        }

    原先弹窗是设置了高度的,所以需要进行重置。推荐使用css类名来切换,方便维护

    $layer.addClass('layer-scroll-in-body')
    &.layer-scroll-in-body {
            position: absolute;
            height: auto;
        }

    在页面有滚动条的时候,还要注意页面的滚动条会不会和弹窗中的滚动条产生冲突,如

    所以需要给body设置

    $body.addClass('layer-scroll-in-body');
    body {
        &.layer-scroll-in-body {
            overflow: hidden;
        }
    }

    最后,记得在弹窗关闭的时候,还原相关的更改即可

  • 相关阅读:
    VS编译cmake工程提示 “无法识别的标记”错误解决方法
    Markdown
    latex公式
    ros:time::now()详解
    c++中PROTOBUF遍历所有属性及值
    ORB-SLAM3相关博文
    WSL2安装及GUI图形界面配置踩坑指南
    ROS与PCL数据转换
    手眼标定中AX=XB求解方法及MATLAB、C++代码
    正则表达式用于数据清洗
  • 原文地址:https://www.cnblogs.com/imwtr/p/10050634.html
Copyright © 2011-2022 走看看