Bootstrap 有個 modal 懸浮窗

如果裡面內容過多,bootstrap 並不會把內容限縮在 modal-body 裡

為了美觀,所以需要 CSS 的 max-height 屬性套用至 modal-body 上

如此一來內容過長造成溢出時,modal-body 會顯示捲動欄

同時 modal-header 與 modal-footer 的內容亦會固定在視窗上

網站上可能會用到多個 modal ,一個一個設定的話要自己去抓數字,很麻煩

所幸 bootstrap modal 有 shown.bs.modal 這個 event 可以使用

所以寫了一段全部 modal 都適用的 code

$('.modal').on('shown.bs.modal', function(){
    var margin_vertical = parseInt( $(this).find('.modal-dialog').css('margin-top') ) + parseInt( $(this).find('.modal-dialog').css('margin-bottom') ) || 0;
    var height_header   = parseInt( $(this).find('.modal-header').css('height') ) || 0;
    var height_footer   = parseInt( $(this).find('.modal-footer').css('height') ) || 0;
    var height_body     = ( window.innerHeight - height_header - height_footer - margin_vertical - 10 ) + 'px';
    $(this).find('.modal-body').css('max-height', height_body).css('overflow', 'auto');
});

 

關於多扣 10px 的部分,因為有其他誤差值,造成 body 的捲動欄會出現

個人猜想可能是因為其他部分 box-model 的關係導致 (border-width 等 blahblah)

不過我也抓不到就是了QQ,所以就偷懶多扣 10px 混過去 XD

至於為什麼會用 shown.bs.modal 這個event,而不是 show.bs.modal

是因為 modal 顯示前的的 css height 是 0

show.bs.modal 觸發的時機是顯示前,而 shown.bs.modal 則是顯示後

因此要等modal顯示時,偵測到的css height才是正確的

而這裡又有一個小小的缺點

就是當你使用 fade-in & fade-out 效果時

在動畫結束前,body 的捲動欄會出現

直到動畫結束後觸發了 shown.bs.modal event

才會顯示成正常的樣子

小弟才疏學淺,這個問題還不知道要怎麼解決

或許加快 css animation speed 做為障眼法混過去勉強可行

不過因為這種情況只會在該 modal 第一次顯示時才會出現

之後只要 browser inner height 沒有變,都不會出現

所以就將就一下囉~

順帶一提,如果你想要能限制最大高度,又能固定佔滿版,只要將第六行的「max-height」改成「height」即可。如下所示

$(this).find('.modal-body').css('height', height_body).css('overflow', 'auto');

 

Update:
2017-05-10: 利用 || 0 預防取回高度值為 nan 的情況下出錯。

2 則迴響

  1. 你好,很高兴能看到这篇文章,你的方法确实很不错

    但是有以下两点美中不足:
    第一,这个页面显示的方式很奇怪,首先是会出现一个很长的modal,然后过零点几秒之后(肉眼能明显感觉出来)才变成不超过屏幕高度的modal。我感觉这样的用户体验并不是很好。效果可见:https://jsfiddle.net/hellozjf/jtwsfwcv/
    第二,这个页面必须要存在modal-footer才能生效。如果我没有写modal-footer,那么modal-body的高度是不会发生变化的。

    不知大神有没有更好的办法能处理以上两个问题?

    周靖峰
    1. 這個問題問得很好

      1. 會先出現很長的 Modal 原因是因為 event 是用 shown.bs.modal,這個 event function 會在 Modal 顯示後才會對 Modal 的高度做修正,而在 Modal 顯示前就作動的 event 是 show.bs.modal,但是 Modal 在顯示 (CSS display: none –> block) 前無法取得區塊的高度,因為這個區塊的屬性是不可見的,這問題還沒有找出解法。
      2. 找不到區塊時 parseInt()return nan,在變數結尾加上 || 0 即可

留言