2015-06-17 86 views
8

我想打开一个超过身体滚动的模态图层。为了做到这一点,当显示图层时,我将身体溢出设置为隐藏状态,并将溢出设置为在模式图层上滚动。从视觉上看,一个滚动条取代了另一个。隐藏物体溢出时带固定位置的元素

在后台我有一个固定位置和100%宽的顶部酒吧。发生的情况是,当主体溢出被设置为隐藏时,100%宽度div(顶部栏)接受滚动条空间并且其元素向右移动。

如何防止这些元素移动?

我试着计算(javascript)滚动条的宽度,当设置正文溢出时:隐藏,给一个页边距右边:“滚动条宽度”到顶部栏。这没有用。

此外,还试图在顶部栏右端的一个虚拟div与溢出设置为滚动,并强制它显示滚动条时打开图层。这个想法是将丢失的滚动条的空间与另一个滚动条放在一起,只在顶部的容器上。这几乎奏效,但创建了1或2px闪烁。还不够好。

jsFiddle here with the basic problem

var body = $('body'), 
main = $('.main'), 
open_modal = $('.open-modal'), 
close_modal = $('.close-modal'), 
modal_container = $('.modal-container'), 
toggleModal = function() { 
    body.toggleClass('body-locked'); 
    modal_container.toggleClass('dp-block'); 
}; 

open_modal.on('click', toggleModal); 
close_modal.on('click', toggleModal); 

回答

7

基本上...

  • 当模式被打开,设置菜单宽度是当前的宽度和设置window.onresize事件,其将调整菜单身体的宽度。

  • 当模态关闭时,删除固定宽度和window.onresize处理程序并将菜单返回到它的初始状态。


less === more精神,我认为是尽我所能简化代码的自由。

var body = $('body'); 
 
var menu = $('#topBarFixed'); 
 

 
function toggleModal() { 
 
    menu.css('width', body.hasClass('locked') ? '' : menu.width()); 
 
    window.onresize = body.hasClass('locked') ? '' : function() { 
 
     menu.css('width', body.width()); 
 
    } 
 
    body.toggleClass('locked'); 
 
} 
 

 
body.on('click', '.open-modal, .close-modal', toggleModal);
body { 
 
    padding-top: 40px; 
 
    height: 1000px; 
 
    background: lightblue; 
 
} 
 

 
body.locked { 
 
    height: 100%; 
 
    overflow: hidden; 
 
} 
 

 
.modal-container { 
 
    display: none; 
 
    overflow-y: scroll; 
 
    position: fixed; 
 
    top: 0; right: 0; 
 
    height: 100%; width: 100%; 
 
    background-color: rgba(255, 255, 255, 0.3); 
 
    z-index: 400; 
 
} 
 

 
body.locked .modal-container { 
 
    display: block !important; 
 
} 
 

 
.modal { 
 
    height: 600px; 
 
    width: 200px; 
 
    margin: 50px auto; 
 
    background: indianred; 
 
} 
 

 
#topBarFixed { 
 
    width: 100%; 
 
    background-color: lightgray; 
 
    position: fixed; 
 
    top: 0; 
 
    left: 0; 
 
    text-align:center; 
 
    display: inline-block; 
 
    z-index: 200; 
 
} 
 

 
.topBarContent { 
 
    display: inline-flex; 
 
    flex-direction: row; 
 
    flex-wrap: nowrap; 
 
    justify-content: space-between; 
 
    align-items: center; 
 
} 
 

 
.inner1 { 
 
    width:30px; 
 
    line-height: 40px; 
 
} 
 

 
.open-modal { 
 
    position: relative; 
 
    top: 400px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 

 
<div id="topBarFixed"> 
 
    <div class="topBarContent"> 
 
     <div id="inner" class="inner1">div</div> 
 
     <div id="inner" class="inner1">div</div> 
 
     <div id="inner" class="inner1">div</div> 
 
     <div id="inner" class="inner1">div</div> 
 
     <div id="inner" class="inner1">div</div> 
 
    </div> 
 
</div> 
 

 

 
<p>Scroll down to open layer</p> 
 
<button class="open-modal">Open layer</button> 
 

 

 
<div class="modal-container"> 
 
    <div class="modal"> 
 
     <button class="close-modal">Close layer</button> 
 
    </div> 
 
</div>

+0

它的工作原理。非常感谢! – ca2s7l

4

这里你的问题是,topBarFixed100%宽度。如果这个宽度是固定的,你不会有这个问题。下面进行了测试Chrome和Firefox:

此行添加到您的toggleModal函数的第一行:

$(".topBarFixed").width($(".topBarFixed").width());

这将设置栏的宽度与实际宽度(以像素为单位)在那一点。然后,当你关闭图层时,将其设置回100%

close_modal.on('click', function() { toggleModal(); $(".topBarFixed").width("100%"); }); 

整个代码如下所示:

var body = $('body'), 
    main = $('.main'), 
    open_modal = $('.open-modal'), 
    close_modal = $('.close-modal'), 
    modal_container = $('.modal-container'), 
    toggleModal = function() { 
     $(".topBarFixed").width($(".topBarFixed").width()); 
     body.toggleClass('body-locked'); 
     modal_container.toggleClass('dp-block'); 
    }; 

open_modal.on('click', toggleModal); 
close_modal.on('click', function() { toggleModal(); $(".topBarFixed").width("100%"); }); 

这里是的jsfiddle:http://jsfiddle.net/wmk05t0b/5/

编辑

或者,你可以只拿出一个固定的宽度,这将做到这一点:

.topBarFixed 
{ 
    width:715px; /*changed from 100%*/ 
    height: 40px; 
    background-color: lightgray; 
    position: fixed; 
    top: 0; 
    left: 0; 
    text-align:center; 
    display: inline-block; 
    z-index: 200; 
} 
+0

谢谢,第一个解决方案是正是我需要的。我只是改变了我的实际代码,它完美地工作。 – ca2s7l

-1

你的代码中的一些错误:id只有一个。如果您想将相同样式应用于更多元素,请使用类。

<div class="topBarContent"> 
    <div class="inner1">div</div> 
    <div class="inner1">div</div> 
    <div class="inner1">div</div> 
    <div class="inner1">div</div> 
    <div class="inner1">div</div> 
</div> 

不管怎样,这不是什么导致你的问题。首先,你的身体溢出应该足够了:除非你想防止背景页面在模态打开的时候滚动,否则不要将overflowY添加到.modal-container。其次,修正模式本身,并使用居中的CSS技巧(左:50%,margin-left:-half-of-your-width)居中。 CSS: 。身体锁定{overflow:scroll; }

.modal-container { 
    overflow:hidden; 
    position:fixed; 
    display: none; 
    top: 0; right: 0; 
    height: 100%; width: 100%; 
    background-color: rgba(255, 255, 255, 0.3); 
    z-index: 400; 
} 

.modal { 
    position: fixed; 
    height: 600px; 
    width: 200px; 
    margin: 50px auto 50px -100px; 
    background: indianred; 
    left:50%; 
} 
/*Reset your body, you never know*/ 
body { 
    margin:0; 
    padding:0 
} 

希望它有帮助。