看到渣浪的查看文章或者查看大圖有個效果:彈窗查看內容時,如果內容過長有滾動條,則滾動條會被放到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">×</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; } }
最後,記得在彈窗關閉的時候,還原相關的更改即可