Bootstrap模態框原理分析及問題解決

最近自學了bootstrap以爲裏面模板樣式挺好的,就想本身實現實現,很少說了,開始進入正題了css

今天就來實現bootstrap裏面的模態框彈出效果html

首先很簡單 實現一個相似於panel的modaljquery

 1 <body>
 2 <button type="button" class="btn btn-default" style="display: block;margin: 20px auto;">Click me!</button>
 3 <div class="chw-dialog">
 4     <div class="chw-modal">
 5         <div class="chw-title">
 6             <button type="button" class="close">
 7                 <span>&times;</span>
 8             </button>
 9             <h4>chw-Modal title</h4>
10         </div>
11         <div class="chw-content">
12             <p>fantasy baby</p>
13         </div>
14         <div class="chw-footer">
15              <button class="btn btn-info">Save changes</button>
16             <button class="btn btn-default">Close</button>
17         </div>
18     </div>
19 </div>
20 <!-- <script src="js/jquery-1.11.1.js"></script>
21 <script src="js/bootstrap.min.js"></script> -->
22 </body>

而後完成他的csschrome

    .chw-dialog {
        display: none;
        position: fixed;
        top:0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 1100;
        opacity: 0;
        transition : opacity .15s linear;
        }
    .chw-modal{
        width: 600px;
        margin: 30px auto;
        box-shadow: 0 5px 10px rgba(0,0,0,.5);
        border-radius: 6px;
        border: 1px solid rgba(0,0,0,.5);
        z-index: 1200;
        background-color: white;
        transform: translate(0,-25%);
        transition: transform 0.3s ease-out;
        }
    .chw-panel{
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            z-index: 1024;
            background-color: black;
            opacity: 0;
            transition : opacity .15s linear;
        }
    .chw-title{
            padding:15px;
            border-bottom: 1px solid #dddddd;
        }
    .chw-title h4{
            line-height: 1.4;
            font-size: 23px;
            margin: 0;
        }
    .chw-content{
            padding:15px;
            border-bottom: 1px solid #dddddd;
        }
    .chw-footer{
            padding: 15px;
            clear: both;
            overflow: hidden;
        }
    .chw-footer button{
            float: right;
            margin-right: 10px;
        }
    </style>
View Code

 

好了很少說開始重點部分,先看看bootstrap的源代碼,點擊button後bootstrap

發現有一個後面有一個蒙層 看見myModa和其子元素都沒有background-color和opacity結合使用的,說明這個蒙層不是myModal生成的,那這個蒙層是怎麼生成的?瀏覽器

我把myModal的類所有刪除後(剔除css樣式)發現蒙層還在,從而更加確信了個人猜想,而後用chrome去獲取蒙層 發現 這個蒙層在整個html最下面。app

    

那爲何一開始沒有索取到這個元素能,由於z-index的效果 這個蒙層div(z-index:1040;)在modal類的下面(z-index:1050;)退出後,這個蒙層div就沒有了,說明經過js添加dom

好了在清楚大致css結構的時候咱們本身來寫一個相似的彈出功能 點擊按鈕,js生成蒙層 你的modal 點擊周圍或者退出按鈕時 蒙層刪除 modal隱藏。ide

 1 <script>
 2     $("body>button").on('click',function () {
 3         var temp = "<div class='chw-panel'></div>"; 4 $("body").append(temp); 5 $(".chw-dialog").css("display","block"); 6 setTimeout(function(){//後續會說明setTimeout 7 $(".chw-panel").css("opacity","0.5"); 8 $(".chw-dialog").css("opacity","1"); 9 $(".chw-modal").css( "transform","translate(0,0)"); 10 },1); 11  }); 12 $('.chw-dialog').on('click',function(){ 13 debugger; 14 $(".chw-panel").css("opacity","0"); 15 $(".chw-dialog").css("opacity","0"); 16 $(".chw-modal").css( "transform","translate(0,-25%)"); 17 setTimeout(function () { 18 $(".chw-dialog").hide(); 19 $(".chw-panel").remove(); 20 },1); 21  }); 22 $(".chw-modal").click(function (e) { 23 e.stopPropagation(); 24 return false; 25 }); 26 $(".close").click(function () { 27 $(".chw-panel").css("opacity","0"); 28 $(".chw-dialog").css("opacity","0"); 29 $(".chw-modal").css( "transform","translate(0,-25%)"); 30 setTimeout(function () { 31 $(".chw-dialog").hide(); 32 $(".chw-panel").remove(); 33 },1); 34 35  }); 36 </script>

首先我是先完成大概功能即點擊按鈕顯示而後退出沒有考慮動畫,在實現的時候發現了幾個問題:函數

1.點擊按鈕後生成蒙層沒有問題,可是點擊modal之外部分沒有退出,沒有任何反應。(這個問題是由於在實現蒙層的點擊生成退出的時候發現的,但其實是點擊chw-dialog來關閉的由於他的     z-index高於那個蒙層div的z-index)

 解決方法:使用$.on(),jquery版本1.7+

 由於我原來寫的函數是$('.chw-panel').click(function(){})不管怎麼點擊那個蒙層也不會觸發函數,查閱資料後發現,咱們在給動態添加的標籤綁定事件的時候(給經過append添加過來的標籤<span class=」test」></span>,不能直接寫$(‘.test’).click(function(){});是由於jquery他的事件機制是當頁面徹底加載成功後,會根據全部目前頁面上符合要求的dom添加事件標示,這樣當你觸發事件的時候,擁有該事件標示的DOM就會給予響應。但append極可能是頁面加載完成後,再觸發的事件,這樣的話,初始化的時候就沒有成功加上,因此你不能簡單的使用click須要用on,$(「body」).on(‘click’,’.test’,function(){});因爲事件的冒泡機制(若是子事件沒有完成(沒有定義子事件的處理函數)或者事件返回true,那麼這個事件會向這個對象的父級對象傳播,從裏到外,直至它被處理(父級對象全部同類事件都將被激活),或者它到達了對象層次的最頂層,即document對象(有些瀏覽器是window)舉個例子我有個子事件沒有被處理,那麼他會傳遞到他的父級看看父級是否能解決,若是不能繼續向上級傳遞直到解決爲止)$(「body」).on(‘click’,’.test’,function(){});這個代表是body這個對象綁定事件,若是body的子元素.testdiv觸發了點擊事件,由於.test沒有綁定事件(經過append添加的div),那麼他要向上傳遞,當傳遞到body的時候,body經過jquery知道是哪一個子元素觸發了函數,若是這個子元素恰好和本身選擇的元素一致的話就執行函數。若是這樣寫$(「body」).on(‘click’,function(){});代表只要他的子元素觸發事件都會執行函數,就像點擊了body觸發函數同樣,然而實際是子元素觸發事件傳遞到body執行函數

2.不管點擊哪一個地方都會退出

  解決方法:使用stopPropagation()

  若是我沒有加紅色的那段代碼時,發現點擊按鈕後,不管我點擊哪一個地方都會退出,這和咱們的預期不同啊,他應該是點擊modal之外的部分退出。怎麼會出現這樣的狀況呢?由於個人.chw-modal是.chw-dialog的子元素,在定義事件觸發函數的時候是這樣寫的$('.chw-dialog').on('click',function(){});因爲事件的冒泡機制,不管你點擊.chw-dialog的任何子元素,在這些子元素沒有綁定函數的前提下,你的子元素都會執行.chw-dialog綁定的函數

 在實現彈出退出後,添加延遲來實現動畫過分

 1 .chw-dialog {
 2  display: none; 3  position: fixed; 4 top:0; 5 right: 0; 6 bottom: 0; 7 left: 0; 8 z-index: 1100; 9 opacity: 0; 10  transition : opacity .15s linear; 11 } 12 .chw-modal 13 { 14  width: 600px; 15  margin: 30px auto; 16 box-shadow: 0 5px 10px rgba(0,0,0,.5); 17 border-radius: 6px; 18 border: 1px solid rgba(0,0,0,.5); 19 z-index: 1200; 20 background-color: white; 21 transform: translate(0,-25%);//初始div位置 22 transition: transform 0.3s ease-out; 23 } 24 .chw-panel 25 { 26  position: fixed; 27 top: 0; 28 left: 0; 29 right: 0; 30 bottom: 0; 31 z-index: 1024; 32 background-color: black; 33 opacity: 0; 34  transition : opacity .15s linear; 35 }

在初始化位置和定義相應的transition後,接下來就是經過js添加css來觸發動畫,改變css的時候發現了一個問題,改變css後可是動畫沒有出現失效了,這是爲何呢?通過本身測試

<div class="test" style="width: 200px;height: 200px;opacity: 0.2;transition:opacity 0.5s linear; "></div>  $("button").click(function(){$(".test").css("opacity","1");}); 

發現能夠實現動畫效果,那爲何myModal的動畫效果沒有出來呢,通過查閱資料發現,若是在css中先執行了讓display:none;變成block的操做的時候動畫不會出現,緣由是由於在js中語句幾乎是同時執行,因此要想他們之間有個先後運行的效果 有兩種辦法

1.使用setTimeout來控制css屬性值變化

2.使用animate在回調函數裏面設置display(不能和transition同時使用)

 

 

解決了以上問題後就能作到相似的彈出效果啦是否是很炫~~~~~上面須要引用bootstrap.css

相關文章
相關標籤/搜索