原生js實現自定義alert風格和實現

2018年6月29 最新更新javascript

添加函數節流,解決屢次點擊問題,添加單例模式,提升代碼性能。css

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5   <meta charset="UTF-8">
  6   <title>自定義alert</title>
  7   <style type="text/css">
  8   html,
  9   body {
 10     padding: 0;
 11     margin: 0;
 12   }
 13   /*     //防止鼠標雙擊選中文字
 14      */
 15 
 16   div {
 17 
 18     -khtml-user-select: none;
 19     /*早期瀏覽器*/
 20     user-select: none;
 21   }
 22   /*  //來自animated.css的樣式 */
 23 
 24   .animated {
 25     animation-duration: 1s;
 26     animation-fill-mode: both;
 27   }
 28 
 29   @keyframes bounceInDown {
 30     from,
 31     60%,
 32     75%,
 33     90%,
 34     to {
 35       animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
 36     }
 37 
 38     0% {
 39       opacity: 0;
 40       transform: translate3d(0, -3000px, 0);
 41     }
 42 
 43     60% {
 44       opacity: 1;
 45       transform: translate3d(0, 25px, 0);
 46     }
 47 
 48     75% {
 49       transform: translate3d(0, -10px, 0);
 50     }
 51 
 52     90% {
 53       transform: translate3d(0, 5px, 0);
 54     }
 55 
 56     to {
 57       transform: none;
 58       display: none;
 59     }
 60   }
 61 
 62   .bounceInDown {
 63     animation-name: bounceInDown;
 64   }
 65 
 66   </style>
 67 </head>
 68 
 69 <body>
 70   <button onclick="test" id="btn">點我測試</button>
 71   <script type="text/javascript">
 72   (function(win, doc) {
 73     var firstTime = true,
 74       startTime = 0;
 75 
 76     function alert(txt, autoTime, top) {
 77       //工具函數
 78       function $(dom) {
 79         return document.querySelector(dom);
 80       }
 81       //單利模式核心
 82       var getSingle = function(fn) {
 83         var result;
 84         return function() {
 85           return (result || (result = fn.apply(this, arguments)));
 86         }
 87       }
 88 
 89       //函數節流
 90       var throttle = function(fn, interval) {
 91         var __self = fn; // 保存須要被延遲執行的函數引用// 是不是第一次調用
 92         return function() {
 93           var args = arguments,
 94             __me = this;
 95           if (firstTime) { // 若是是第一次調用,不需延遲執行
 96             __self.apply(__me, args);
 97             return firstTime = false;
 98           }
 99 
100           var endTime = new Date() * 1; //時間大於3000秒下次執行
101           if (endTime - startTime > (autoTime || 3000)) {
102             __self.apply(__me, args);
103           }
104         };
105       };
106 
107 
108       //建立div代碼
109       var createDiv = function() {
110 
111         var div = doc.createElement("div");
112         div.style.backgroundColor = " #22b9ff";
113         div.style.color = " #fff";
114         div.style.position = " fixed";
115         div.style.zIndex = 9999999;
116         div.style.height = " 60px";
117         div.style.top = top || "10%";
118         div.style.left = "50%";
119         div.style.lineHeight = " 60px";
120         div.style.borderRadius = " 4px";
121         div.style.fontSize = " 20px";
122         div.style.textAlign = "center";
123         div.style.padding = "0 10px";
124         div.className = "animated  bounceInDown";
125         div.id = "alert";
126         div.innerHTML = txt || "不能爲空!";
127         return div;
128       }
129 
130       var createSingleDiv = getSingle(createDiv);
131 
132       return throttle(function() {
133 
134         var div = createSingleDiv(); //建立div
135         startTime = new Date() * 1; //初始位置
136         $("body").appendChild(div);
137         //動態調整位置
138         var alertWidth = win.getComputedStyle($("#alert"), null).width;
139         div.style.marginLeft = -parseInt(alertWidth) / 2 + "px";
140         setTimeout(function() {
141           $("body").removeChild(div);
142         }, autoTime || 3000);
143       }).apply(this, null);
144     }
145 
146     win.alert = alert; //導出
147 
148   })(window, document);
149 
150 
151   document.getElementById('btn').onclick = function() {
152     alert("手機號不能爲空!");
153   }
154 
155   </script>
156 </body>
157 
158 </html>
View Code

上篇文章介紹了自定義confirm的必要性,能夠說alert是比confirm更爲經常使用的瀏覽器自帶組件了。但更由於經常使用,而原生組件不管是樣式仍是體驗都不是很好,因此更加有必要自定義。html

此爲改造的背景。java

原本初版是自定義的初版是沒有防止提示期間,用戶進行其餘操做的透明層的;js代碼是這樣:web

 1  <script type="text/javascript">
 2     window.alert = function(text) {
 3      
 4         //實現alert
 5         var div = document.createElement("div");
 6         div.style.backgroundColor = " #22b9ff";
 7         div.style.color = " #fff";
 8         div.style.position = " fixed";
 9         div.style.zIndex = 9999999;
10         div.style.height = " 60px";
11         div.style.top = " 10%";
12         div.style.left = "50%";
13         div.style.lineHeight = " 60px";
14         div.style.borderRadius = " 4px";
15         div.style.fontSize = " 20px";
16         div.style.textAlign = "center";
17         div.style.padding = "0 10px";
18         div.className = "animated  bounceInDown";
19         div.id = "alert";
20         div.innerHTML = text;
21         document.getElementsByTagName("body")[0].appendChild(div);
22         var selfObj = document.getElementById("alert");
23         //動態調整位置
24         var alertWidth = window.getComputedStyle(selfObj, null).width;
25         div.style.marginLeft = -parseInt(alertWidth) / 2 + "px";
26         setTimeout(function() {
27             document.getElementsByTagName("body")[0].removeChild(div);
28         }, 30000);
29     }
30     alert("這是自定義的alert");
31     </script>

 

後來想到實際的alert效果,提示期間是沒法作其它操做的,因而改造爲這樣瀏覽器

 1 <script type="text/javascript">
 2     window.alert = function(text) {
 3         //透明遮罩層
 4         var mask = document.createElement("div");
 5         mask.style.position = " fixed";
 6         mask.style.zIndex = 1000000;
 7         mask.style.top = 0;
 8         mask.style.bottom = 0;
 9         mask.style.left = 0;
10         mask.style.right = 0;
11         //實現alert
12         var div = document.createElement("div");
13         div.style.backgroundColor = " #22b9ff";
14         div.style.color = " #fff";
15         div.style.position = " fixed";
16         div.style.zIndex = 9999999;
17         div.style.height = " 60px";
18         div.style.top = " 10%";
19         div.style.left = "50%";
20         div.style.lineHeight = " 60px";
21         div.style.borderRadius = " 4px";
22         div.style.fontSize = " 20px";
23         div.style.textAlign = "center";
24         div.style.padding = "0 10px";
25         div.className = "animated  bounceInDown";
26         div.id = "alert";
27         div.innerHTML = text;
28         document.getElementsByTagName("body")[0].appendChild(div);
29         document.getElementsByTagName("body")[0].appendChild(mask);
30         var selfObj = document.getElementById("alert");
31         //動態調整位置
32         var alertWidth = window.getComputedStyle(selfObj, null).width;
33         div.style.marginLeft = -parseInt(alertWidth) / 2 + "px";
34         setTimeout(function() {
35             document.getElementsByTagName("body")[0].removeChild(div);
36             document.getElementsByTagName("body")[0].removeChild(mask);
37         }, 3000);
38     }
39     alert("這是自定義的alert");
40     </script>
 

值得一提的是動態位置的調整哪塊,經過實時計算alert組件的寬度,保證組件始終處於中間位置,至於alert組件的顯示時間,就本身改源代碼時間吧。閉包

總體代碼以下app

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <title>自定義alert</title>
  7     <style type="text/css">
  8     html,
  9     body {
 10         padding: 0;
 11         margin: 0;
 12     }
 13     /*     //防止鼠標雙擊選中文字
 14      */
 15 
 16     div {
 17 
 18         -khtml-user-select: none;
 19         /*早期瀏覽器*/
 20         user-select: none;
 21     }
 22     /*  //來自animated.css的樣式 */
 23 
 24     .animated {
 25         animation-duration: 1s;
 26         animation-fill-mode: both;
 27     }
 28 
 29     @keyframes bounceInDown {
 30         from,
 31         60%,
 32         75%,
 33         90%,
 34         to {
 35             animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
 36         }
 37 
 38         0% {
 39             opacity: 0;
 40             transform: translate3d(0, -3000px, 0);
 41         }
 42 
 43         60% {
 44             opacity: 1;
 45             transform: translate3d(0, 25px, 0);
 46         }
 47 
 48         75% {
 49             transform: translate3d(0, -10px, 0);
 50         }
 51 
 52         90% {
 53             transform: translate3d(0, 5px, 0);
 54         }
 55 
 56         to {
 57             transform: none;
 58         }
 59     }
 60 
 61     .bounceInDown {
 62         animation-name: bounceInDown;
 63     }
 64 
 65     </style>
 66 </head>
 67 
 68 <body>
 69     <script type="text/javascript">
 70     (function(win,doc) {
 71         var alert = function(text, time, top) {
 72             text = text || "肯定刪除?",time = time || 3000,top = top || "10%";//增長默認值,加強健壯性
 73             var body=doc.getElementsByTagName("body")[0];//優化dom
 74             //實現alert
 75             var div = doc.createElement("div");
 76             div.style.backgroundColor = " #22b9ff";
 77             div.style.color = " #fff";
 78             div.style.position = " fixed";
 79             div.style.zIndex = 9999999;
 80             div.style.height = " 60px";
 81             div.style.top = top;
 82             div.style.left = "50%";
 83             div.style.lineHeight = " 60px";
 84             div.style.borderRadius = " 4px";
 85             div.style.fontSize = " 20px";
 86             div.style.textAlign = "center";
 87             div.style.padding = "0 10px";
 88             div.className = "animated  bounceInDown";
 89             div.id = "alert";
 90             div.innerHTML = text;
 91             body.appendChild(div);
 92             var selfObj = doc.getElementById("alert");
 93             //動態調整位置
 94             var alertWidth = win.getComputedStyle(selfObj, null).width;
 95             div.style.marginLeft = -parseInt(alertWidth) / 2 + "px";
 96             setTimeout(function() {
 97                 body.removeChild(div);
 98             }, time);
 99         }
100         win.alert=alert;//導出
101     })(window,document);
102     alert();
103     </script>
104 </body>
105 
106 </html>
View Code

2018年6月24日更新  增長參數的默認值,該少dom訪問慢的問題,使用閉包包裹,alert導出覆蓋windowdom

在總體代碼中,有一個用來防止雙擊選中文字的css樣式,值得關注一下。ide

樣式中的css動畫來自知名的動畫庫animation.css。所以,能夠根據實際業務須要更換動畫類。基本就是這樣。

仿京東註冊web移動端提示。

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <title>自定義alert</title>
  7     <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=no" name="viewport" />
  8     <style type="text/css">
  9     html,
 10     body {
 11         padding: 0;
 12         margin: 0;
 13     }
 14     /*     //防止鼠標雙擊選中文字
 15      */
 16 
 17     div {
 18 
 19         -khtml-user-select: none;
 20         /*早期瀏覽器*/
 21         user-select: none;
 22     }
 23     /*  //來自animated.css的樣式 */
 24 
 25     @-webkit-keyframes fadeIn {
 26         0% {
 27             opacity: .7
 28         }
 29         50% {
 30             opacity: 1
 31         }
 32         100% {
 33             opacity: .7
 34         }
 35     }
 36 
 37     .toast {
 38         -webkit-animation-name: fadeIn;
 39         -webkit-animation-duration: 3s;
 40         -webkit-animation-iteration-count: 1;
 41         -webkit-animation-delay: 0s;
 42         -webkit-transition: all .3s ease;
 43         -moz-transition: all .3s ease;
 44         transition: all .3s ease;
 45         max-width: 80%;
 46         color:#fff;
 47         background: #2B2B2B;
 48         padding: 8px 15px;
 49         display: inline-table;
 50         border-radius: 3px;
 51     }
 52 
 53     .toast-ui {
 54         position: fixed;
 55         top:20%;
 56         color:#fff;
 57         width: 100%;
 58         text-align: center;
 59     }
 60 
 61     .maskfadeout {
 62         display: block;
 63         -webkit-animation: fadeout 3s linear;
 64         animation: fadeout 3s linear;
 65         -webkit-animation-iteration-count: 1;
 66         animation-iteration-count: 1
 67     }
 68 
 69     @-webkit-keyframes fadeout {
 70         0%,
 71         80% {
 72             opacity: 1
 73         }
 74         100% {
 75             opacity: 0
 76         }
 77     }
 78 
 79     @keyframes fadeout {
 80         0%,
 81         80% {
 82             opacity: 1
 83         }
 84         100% {
 85             opacity: 0
 86         }
 87     }
 88     </style>
 89 </head>
 90 
 91 <body>
 92     <script type="text/javascript">
 93     (function(win, doc) {
 94         var alert = function(text, time, top) {
 95             text = text || "肯定刪除?", time = time || 3000, top = top || "10%"; //增長默認值,加強健壯性
 96             var body = doc.getElementsByTagName("body")[0]; //優化dom
 97             //實現alert
 98             var div = doc.createElement("div");
 99             div.className = "toast-ui maskfadeout";
100             div.id = "alert";
101             var span = doc.createElement("span");
102             span.innerHTML = text;
103             span.className = "toast";
104             div.appendChild(span);
105             body.appendChild(div);
106          
107             setTimeout(function() {
108                  div.style.display="none";
109             }, 3000);
110         }
111         win.alert = alert; //導出
112     })(window, document);
113     alert("是否刪除這條評論?");
114     </script>
115 </body>
116 
117 </html>
View Code

本文結束。

相關文章
相關標籤/搜索