zoukankan      html  css  js  c++  java
  • 原生js实现自定义alert风格和实现

    2018年6月29 最新更新

    添加函数节流,解决多次点击问题,添加单例模式,提高代码性能。

      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更为常用的浏览器自带组件了。但更因为常用,而原生组件无论是样式还是体验都不是很好,所以更加有必要自定义。

    此为改造的背景。

    本来第一版是自定义的第一版是没有防止提示期间,用户进行其他操作的透明层的;js代码是这样:

     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组件的显示时间,就自己改源代码时间吧。

    整体代码如下

      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导出覆盖window

    在整体代码中,有一个用来防止双击选中文字的css样式,值得关注一下。

    样式中的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- 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          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

    本文结束。

  • 相关阅读:
    c++ 反汇编 堆变量
    glibc源码逆向——fread函数
    glibc源码逆向——fopen
    buu查漏补缺刷题(3)
    gyctf_2020_borrowstack
    实现用句柄表反调试
    pwnable_orw 学习shellcraft新花样
    buu查漏补缺刷题(2)
    gdb调试源码
    buu查漏补缺刷题(1)
  • 原文地址:https://www.cnblogs.com/zhensg123/p/8643410.html
Copyright © 2011-2022 走看看