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


最近自學了bootstrap覺得里面模板樣式挺好的,就想自己實現實現,不多說了,開始進入正題了

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

首先很簡單 實現一個類似於panel的modal

 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>

然后完成他的css

<style type="text/css">
    /*注釋部分為后面動畫實現,現在只是完成基本樣式*/
    /*.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;
        }
View Code

好了不多說開始重點部分,先看看bootstrap的源代碼,點擊button后

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

我把myModal的類全部刪除后(剔除css樣式)發現蒙層還在,從而更加確信了我的猜測,然后用chrome去獲取蒙層 發現 這個蒙層在整個html最下面。

    

那為什么一開始沒有索取到這個元素能,因為z-index的效果 這個蒙層div(z-index:1040;)在modal類的下面(z-index:1050;)退出后,這個蒙層div就沒有了,說明通過js添加

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

 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;background-color: red;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

 

 

解決了以上問題后就能做到類似的彈出效果啦是不是很炫~~~~~上面需要引用bootstrap.css

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM