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>
上篇文章介紹了自定義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>
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>
本文結束。