欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

弹窗查看内容时 内容滚动区域设置为body区

程序员文章站 2022-03-29 19:17:17
看到渣浪的查看文章或者查看大图有个效果:弹窗查看内容时,如果内容过长有滚动条,则滚动条会被放到body区滚动 什么意思呢? 看个图片,一般正常弹窗是有宽高限制的,如果内容过长则直接在弹窗中进行滚动 点我预览 将滚动位置放到整个body中,让弹窗中内容自适应高度 这么做的好处自然很明显,body区域有 ......

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

什么意思呢?

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

弹窗查看内容时 内容滚动区域设置为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设置

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

 

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