2-3Web APIs 网页应用编程-DOM下

68 阅读4分钟

5.DOM事件详解

1.注册事件的方法

element.addEventListener() 方法

• 参数:

第一个参数:事件类型的字符串(直接书写”click”,不需要加 on)

第二个参数:事件函数

• 同一个元素可以多次绑定事件监听,同一个事件类型可以注册多个事件函数

• 兼容性问题:不支持 IE9 以下的浏览器

<body>
  <input type="button" value="点击" id="btn">
  <script>
    var btn = document.getElementById("btn");
    // DOM0 级事件
    // 绑定事件的方式
    // btn.onclick = function () {
    //   alert(1);
    // };
    // 绑定多次相同的事件
    // btn.onclick = function () {
    //   alert(2);
    // };

    // DOM 2 级事件绑定方式
    btn.addEventListener("click",function () {
      alert(1);
    });
    // 多次绑定相同的事件类型,事件会根据书写的顺序进行一个事件排队
    btn.addEventListener("click",clickEvent);
    function clickEvent() {
      alert(2);
    }
    // 方法不支持 IE 9 以下的浏览器
    </script>
</body>

element.attachEvent()方法。

• 参数:

第一个参数:事件类型的字符串(需要加 on)

第二个参数:事件函数

• 同一个元素可以多次绑定事件监听,同一个事件类型可以注册多个事件函数

• 兼容性问题:只支持 IE10 及以下的浏览器

<body>
  <input type="button" value="点击" id="btn">
  <script>
    var btn = document.getElementById("btn");    
    // DOM 2 级事件绑定方式
    // 兼容:IE 10 及以下浏览器
    // IE8 及以下的浏览器处理事件队列时,会出现顺序错乱
    btn.attachEvent("onclick",function () {
      alert(3);
    });
    btn.attachEvent("onclick",clickEvent);
    function clickEvent() {
      alert(4);
    }
    </script>
</body>

2.注册事件的兼容写法

• 自定义一个注册事件函数

• 参数:事件源,事件类型(不加 on),事件函数

• IE9 及以上的浏览器,使用 addEventListener 方法

• IE9 以下的浏览器,使用 attachEvent 方法

• 判断浏览器时,不需要判断它的版本,可以检测浏览器能力

• 浏览器能力检测:将某个方法的调用作为 if 语句的判断条件,如果浏览器认识该方法返回

true,否则返回 false。

<body>
  <input type="button" value="点击" id="btn">
  <script>
    var btn = document.getElementById("btn");  
    // 调用函数
    addEvent(btn,"click",function () {
      alert(1);
    }); 
    // DOM 2 级事件绑定方式
    // 自己制作一个兼容所有浏览器的绑定事件的函数
    // 参数:事件源,事件类型,事件函数
    function addEvent(ele,type,fn) {
      // IE 9 及以上的浏览器和其他浏览器,使用 addEventListener 方法
      // IE 9 以下的浏览器,使用 attachEvent 方法
      // 浏览器能力检测
      if (ele.addEventListener) {
        ele.addEventListener(type,fn);
      } else if (ele.attachEvent) {
        ele.attachEvent("on" + type,fn);
      }
    }
    </script>
</body>

3.移除事件的其他方法

element.removeEventListener() 方法。

• 参数:

第一个参数:事件类型的字符串(直接书写”click”,不需要加 on)

第二个参数:事件函数引用名

• 注意:没有办法移除一个匿名函数,所以在注册事件时需要单独声明一个有函数名的事件函数。

• 兼容性问题:不支持 IE9 以下的浏览器

element.detachEvent()方法。

• 参数:

第一个参数:事件类型的字符串(需要加 on)

第二个参数:事件函数

• 注意:没有办法移除一个匿名函数,所以在注册事件时需要单独声明一个有函数名的事件函数。

兼容性问题:只支持 IE10 及以下的浏览器

<body>
  <input type="button" value="点击" id="btn">
  <script>
    var btn = document.getElementById("btn");    
    // 绑定事件
    // btn.onclick = function () {
    //   alert(1);
    // };
    // 解除绑定方法
    // btn.onclick = null;
    // 绑定事件
    // btn.addEventListener("click",fun);
    // btn.addEventListener("click",fun2);
    // 解除绑定
    // btn.removeEventListener("click",fun);

    // 绑定事件
    btn.attachEvent("onclick",fun);
    // 解除绑定
    btn.detachEvent("onclick",fun);
    function fun() {
      alert(2);
    }
    function fun2() {
      alert(3);
    }
    </script>
</body>

4.移除事件的兼容写法

• 自定义一个移除事件函数

• 参数:事件源,事件类型(不加 on),事件函数

• IE9 及以上的浏览器,使用 removeEventListener 方法

• IE9 以下的浏览器,使用 detachEvent 方法

• 建议:将自己封装的一些常用函数和方法,放到一个单独的 .js 文件中。

<body>
  <input type="button" value="点击" id="btn">
  <script>
    var btn = document.getElementById("btn");  
    // 调用函数
    addEvent(btn,"click",fun); 
    // 移除事件
    removeEvent(btn,"click",fun);
    function fun() {
      alert(1);
    }
    // DOM 2 级事件绑定方式
    // 自己制作一个兼容所有浏览器的绑定事件的函数
    // 参数:事件源,事件类型,事件函数
    function addEvent(ele,type,fn) {
      // IE 9 及以上的浏览器和其他浏览器,使用 addEventListener 方法
      // IE 9 以下的浏览器,使用 attachEvent 方法
      // 浏览器能力检测
      if (ele.addEventListener) {
        ele.addEventListener(type,fn);
      } else if (ele.attachEvent) {
        ele.attachEvent("on" + type,fn);
      }
    }

    // 兼容所有浏览器的 解除绑定事件的函数
    // 参数:事件源,事件类型,事件函数
    function removeEvent(ele,type,fn) {
      // 浏览器能力检测
      if (ele.removeEventListener) {
        ele.removeEventListener(type,fn);
      } else if (ele.detachEvent) {
        ele.detachEvent("on" + type,fn);
      }
    }
    </script>
</body>

5.DOM 事件流

事件流的三个阶段

• 第一个阶段:事件捕获

• 第二个阶段:事件执行过程

• 第三个阶段:事件冒泡

• addEventListener() 第三个参数为 false 时,事件冒泡

• addEventListener() 第三个参数为 true 时,事件捕获

• onclick 类型:只能进行事件冒泡过程,没有捕获阶段

• attachEvent() 方法:只能进行事件冒泡过程,没有捕获阶段

    <style>
        #box1{
            width: 300px;
            height: 300px;
            background-color: yellowgreen;
        }
        #box2{
            width: 200px;
            height: 200px;
            background-color: pink;
        }
        #box3{
            width: 100px;
            height: 100px;
            background-color: skyblue;
        }
    </style>
</head>
<body>
    <div id="box1">
        <div id="box2">
            <div id="box3"></div>
        </div>
    </div>
    <script>
        // 获取元素
        var box1 = document.getElementById("box1");
        var box2 = document.getElementById("box2");
        var box3 = document.getElementById("box3");
        
        // 添加点击事件
        // addEventListener 有第三个参数,用来决定事件流的方向
        // 参数值是 布尔类型的值,false 表示事件冒泡过程,true 表示事件捕获过程
        // 参数默认值是 false
        // box1.addEventListener("click",function () {
        //     console.log(1);
        // },false);
        // box2.addEventListener("click",function () {
        //     console.log(2);
        // },false);
        // box3.addEventListener("click",function () {
        //     console.log(3);
        // },false);
        // box1.addEventListener("click",function () {
        //     console.log(this.id);
        // },true);
        // box2.addEventListener("click",function () {
        //     console.log(this.id);
        // },true);
        // box3.addEventListener("click",function () {
        //     console.log(this.id);
        // },true);
        
        
        // onclick 属性添加事件方法只有冒泡过程,没有捕获过程
        // attachEvent() 方法添加事件方法只有冒泡过程,没有捕获过程
        box1.onclick = function () {
            console.log(1);
        };
        box2.onclick = function () {
            console.log(2);
        };
        box3.onclick = function () {
            console.log(3);
        };
        
    </script>
</body>HTML

事件委托

• 利用事件冒泡,将子级的事件委托给父级加载

• 同时,需要利用事件函数的一个 e 参数,内部存储的是事件对象

批量给兄弟添加相同事件,用事件委托,减少外部循环优化代码

    <style>
        * {
            margin: 0;
            padding: 0;
        }
        ul {
            width: 300px;
            border: 1px dashed #f0f;
            margin: 50px auto;
            font-size: 24px;
            line-height: 48px;
            list-style: none;
        }
        li {
            padding-left: 20px;
            cursor: pointer;
        }

    </style>
</head>

<body>
    <ul id="list">
        <li>刘亦菲</li>
        <li>杨幂</li>
        <li>唐嫣</li>
        <li>赵丽颖</li>
        <li>刘诗诗</li>
    </ul>
    <script>
        // 让每个 li 被点击后,自己添加特殊的背景色,而其他兄弟不添加
        // 以前的思路:获取所有的 li 标签元素,批量添加事件
        // 事件委托:可以将一些子级的公共类型的事件委托给他们的父级添加,在父级内部想办法找到真正触发事件的最底层的事件源
        // 获取元素
        var list = document.getElementById("list");
        var lis = list.children;
        // 给 ul 添加点击事件
        list.onclick = function (e) {
            // 在内部要想办法找到真正触发事件的 li
            // 借用事件函数内部的一个参数 e,e 是事件对象
            // 只要触发事件,函数内部都可以得到一个事件对象,对象中存储了关于事件的一系列数据
            // e.target 属性记录的就是真正触发事件的事件源
            // 排除其他
            for (var i = 0 ; i < lis.length ; i++) {
                lis[i].style.backgroundColor = "";
            }
            e.target.style.backgroundColor = "pink";
        };
    </script>
</body>

事件对象

• 只要触发事件,就会有一个对象,内部存储了与事件相关的数据。

• e 在低版本浏览器中有兼容问题,低版本浏览器使用的是 window.event

• 事件对象常用的属性:

e.eventPhase查看事件触发时所处的阶段
e.target用于获取触发事件的元素
e.srcElement用于获取触发事件的元素,低版本浏览器使用
e.currentTarget用于获取绑定事件的事件源元素
e.type获取事件类型
e.clientX/e.clientY所有浏览器都支持,鼠标距离浏览器窗口左上角的距离
e.pageX/e.pageYIE8 以前不支持,鼠标距离整个HTML页面左上顶点的距离
    <style>
        #box1{
            width: 300px;
            height: 300px;
            background-color: yellowgreen;
        }
        #box2{
            width: 200px;
            height: 200px;
            background-color: pink;
        }
        #box3{
            width: 100px;
            height: 100px;
            background-color: skyblue;
        }
    </style>
</head>
<body>
    <div id="box1">
        <div id="box2">
            <div id="box3"></div>
        </div>
    </div>
    <script>
        // 获取元素
        var box1 = document.getElementById("box1");
        var box2 = document.getElementById("box2");
        var box3 = document.getElementById("box3");
        
        // 添加事件
        box1.onclick = function (e) {
            // e指的就是存储事件对象的参数,只要事件被触发,e就会自动接收数据
            // 兼容问题
            e = e || window.event;
            // e.eventPhase 判断出事件执行时处于哪个阶段
            // 1:捕获阶段
            // 2:目标阶段
            // 3:冒泡阶段
            // console.log(e.eventPhase);

            // 获取真正触发事件的元素
            var target = e.target || e.srcElement;
            // console.log(target);
            // 获取绑定事件的事件源元素
            console.log(e.currentTarget);
            // this 指向
            console.log(this);
        };
        
    </script>
</body>
    <style>
        #box1{
            width: 200px;
            height: 200px;
            background-color: yellowgreen;
        }
    </style>
</head>
<body>
    <div id="box1"></div>
    <script>
        // 获取元素
        var box1 = document.getElementById("box1");
        
        // e.type 属性获取事件类型
        // box1.onclick = function (e) {
        //     // 事件对象兼容
        //     e = e || window.event;
        //     // 触发的事件类型
        //     console.log(e.type);
        // };

        // 更多时候可能给同一个元素对象添加不同的事件类型,对应执行的事件函数内部的代码 不同
        // box1.onmouseover = function () {
        //     box1.style.backgroundColor = "skyblue";
        // };
        // box1.onmouseout = function () {
        //     box1.style.backgroundColor = "yellowgreen";
        // };
        // 可以将 所有给一个元素绑定的事件的事件函数写在一个 函数内,通过函数内部的 e.type 判断走不同的分支
        box1.onmouseover = fn;
        box1.onmouseout = fn;
        // 避免添加多个函数,占用更多的内存
        function fn(e) {
            e = e || window.event;
            // 根据事件类型,执行不同的代码
            switch (e.type) {
                case "mouseover":
                    box1.style.backgroundColor = "pink";
                    break; 
                case "mouseout":
                    box1.style.backgroundColor = "yellowgreen";  
                    break;                   
            }
        }
    </script>
</body>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        body {
            height: 1000px;
        }
        #box1{
            width: 200px;
            height: 200px;
            margin: 100px;
            margin-top: 500px;
            background-color: pink;
        }
    </style>
</head>
<body>
    <div id="box1"></div>
    <script>
        // 获取元素
        var box1 = document.getElementById("box1");
        
        // 事件对象中有一些获取尺寸的属性
        box1.onclick = function (e) {
            // client系列: 客户端尺寸,点击的点参考浏览器窗口左上角的距离
            console.log(e.clientX);
            console.log(e.clientY);
            // page 系列:html 页面尺寸,点击的点参考html文档左上角的距离
            console.log(e.pageX);
            console.log(e.pageY);
        };
        
    </script>
</body>

案例

图片跟随鼠标移动效果

    <style>
      * {
        margin: 0;
        padding: 0;
      }
      #pic {
        position: fixed;
      }
    </style>
</head>
<body>
    <img src="images/tianshi.gif" alt="" id="pic">
    <script>
        // 通过 鼠标移动事件给 图片添加 left 和 top 的值
        // 获取元素
        var pic = document.getElementById("pic");
        // 给整个文档添加鼠标移动事件
        document.onmousemove = function (e) {
          e = e || window.event;
          // 给元素的css 属性赋值
          pic.style.left = e.clientX + "px";
          pic.style.top = e.clientY + "px";
        };
    </script>
</body>

取消默认行为和阻止事件传播的方式

e.preventDefault()取消默认行为
e.returnValue取消默认行为,低版本浏览器使用
e.stopPropagation();阻止冒泡,标准方式
e.cancelBubble = true;阻止冒泡,IE 低版本,标准中已废弃
<body>
  <a id="link" href="52_图片跟随鼠标移动效果.html">点击</a>
  <script>
    var link = document.getElementById('link');
    link.onclick = function (e) {
      e = e || window.event;
      alert('hello');
      // 普通的方式阻止默认行为 既阻止点击a链接进行跳转网页
      // return false;
      // DOM 的方法
      // e.preventDefault();
      // 低版本浏览器需要使用一个对象的属性
      e.returnValue = false;
    }
  </script>
</body>
  <style>
    #box1 {
      width: 300px;
      height: 300px;
      background-color: red;
    }

    #box2 {
      width: 200px;
      height: 200px;
      background-color: green;
    }

    #box3 {
      width: 100px;
      height: 100px;
      background-color: blue;
    }
  </style>
</head>
<body>
  <div id="box1">
    <div id="box2">
      <div id="box3">
      </div>
    </div>
  </div>
  <script>
    // 事件冒泡
    var box1 = document.getElementById('box1');
    var box2 = document.getElementById('box2');
    var box3 = document.getElementById('box3');

    var array = [box1, box2, box3];

    for (var i = 0; i < array.length; i++) {
      var box = array[i];
      box.onclick = function (e) {
        e = e || window.event;
        console.log(this.id);
        // 阻止事件冒泡
        // e.stopPropagation();
        // 低版本浏览器使用 属性
        e.cancelBubble = true;
      }
    }
   

  </script> 
</body>

6.DOM特效

1.偏移量属性

offsetParent偏移参考父级,距离自己最近的有定位的父级,如果都没有定位参考body(html)
offsetLeft/offsetTop偏移位置
offsetWidth/offsetHeight偏移大小
  <style>
    body {
      margin: 0;
    }
    #box {
      /* position: relative; */
      width: 300px;
      height: 300px;
      border: 10px solid yellowgreen;
      background-color: skyblue;
      overflow: hidden;
      margin: 50px;
    }
    #child {
      width: 100px;
      height: 100px;
      background-color: pink;
      margin: 50px;
      border: 10px solid yellow;
      padding: 10px;
    }
  </style>
</head>
<body>
  <div id="box">
    <div id="child">      
    </div>
  </div>
  <script>
    // 获取元素
    var child = document.getElementById("child");
    // 元素天生就认识自己的偏移参考父级
    // console.log(child.offsetParent);

    // 偏移位置
    // console.log(child.offsetLeft);
    // console.log(child.offsetTop);

    // 偏移大小
    console.log(child.offsetWidth);
    console.log(child.offsetHeight);
  </script>
</body>

2.客户端大小

client系列没有参考父级元素。
clientLeft/clientTop边框区域尺寸,不常用
• clientWidth/clientHeight边框内部大小
  <style>
    body {
      margin: 0;
    }

    #box {
      width: 100px;
      height: 100px;
      margin: 50px;
      border: 40px solid red;
      padding: 10px;
      background-color: green;
    }
  </style>
</head>
<body>
  <div id="box">
    
  </div>
  <script>
      var box = document.getElementById("box");

      // client 客户端大小
      console.log(box.clientLeft); // 40 边框大小
      console.log(box.clientTop); // 40
      console.log(box.clientWidth); // 120
      console.log(box.clientHeight); //120

  </script>
</body>

3.滚动偏移属性

scrollLeft/scrollTop盒子内部滚动出去的尺寸
scrollWidth/scrollHeight盒子内容的宽度和高度
  <style>
    *{
      padding: 0;
      margin: 0;
    }
    body {
      margin: 0;
    }

    #box {
      width: 200px;
      height: 200px;
      margin: 50px;
      border: 30px solid red;
      padding: 50px;
      background-color: green;
      overflow: auto;
    }
    #box p{
      width: 300px;
      height: 300px;
      background-color: pink;
    }
  </style>
</head>
<body>
  <div id="box">
    <p></p> 
  </div>
  <script>
      var box = document.getElementById("box");
      // 滚动偏移位置和大小
      // 滚动条滚动事件
      box.onscroll = function () {
        console.log(box.scrollLeft);
        console.log(box.scrollTop);
      };

      // console.log(box.scrollLeft);
      // console.log(box.scrollTop);
      // console.log(box.scrollWidth);
      // console.log(box.scrollHeight);

      // console.log(box.clientWidth);
      // console.log(box.offsetWidth);

  </script>
</body>

案例

• 拖拽案例

• 弹出登录窗口

    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .nav {
            height: 30px;
            background: #036663;
            border-bottom: 1px solid #369;
            line-height: 30px;
            padding-left: 30px;
        }

        .nav a {
            color: #fff;
            text-align: center;
            font-size: 14px;
            text-decoration: none;

        }

        .d-box {
            width: 400px;
            height: 300px;
            border: 5px solid #eee;
            box-shadow: 2px 2px 2px 2px #666;
            position: absolute;
            top: 40%;
            left: 40%;
            background-color: white;

            /* 不让文字被选中 */
            -webkit-user-select:none;
            -moz-user-select:none;
            -ms-user-select:none;
            user-select:none;
        }

        .hd {
            width: 100%;
            height: 25px;
            background-color: #7c9299;
            border-bottom: 1px solid #369;
            line-height: 25px;
            color: white;
            cursor: move;
        }

        #box_close {
            float: right;
            cursor: pointer;
        }
    </style>
</head>
<body>
<div class="nav">
    <a href="javascript:;" id="register">注册信息</a>
</div>
<div class="d-box" id="d_box">
    <div class="hd" id="drop">注册信息 (可以拖拽)
        <span id="box_close">【关闭】</span>
    </div>
    <div class="bd"></div>
</div>
<script src="common.js"></script>
<script>
    // 获取元素
    var box = document.getElementById("d_box");
    var drop = document.getElementById("drop");
    var close = document.getElementById("box_close");

    // 给 drop 添加鼠标按下事件,在内部继续绑定一个鼠标移动事件
    drop.onmousedown = function (e) {
        e = e || window.event;
        // 记忆鼠标按下时,鼠标在父盒子内部的间距
        var l = e.pageX - box.offsetLeft;
        var t = e.pageY - box.offsetTop;
        // 鼠标移动事件
        drop.onmousemove = function (e) {
            e = e || window.event;
            // 鼠标移动过程中,可以计算 box 的 left 和 top
            var nowleft = e.pageX - l;
            var nowtop = e.pageY - t;
            // 赋值给 box 的样式属性
            box.style.left = nowleft + "px";
            box.style.top = nowtop + "px";
        };
    };

    // 鼠标弹起事件
    drop.onmouseup = function () {
        drop.onmousemove = null;
    };

    // 点击 关闭 box
    close.onclick = function () {
        box.style.display = "none";
    };
</script>
</body>
    <style>
        .login-header {
            width: 100%;
            text-align: center;
            height: 30px;
            font-size: 24px;
            line-height: 30px;
        }
        ul, li, ol, dl, dt, dd, div, p, span, h1, h2, h3, h4, h5, h6, a {
            padding: 0px;
            margin: 0px;
        }
        .login {
            width: 512px;
            position: absolute;
            border: #ebebeb solid 1px;
            height: 280px;
            left: 50%;
            right: 50%;
            background: #ffffff;
            box-shadow: 0px 0px 20px #ddd;
            z-index: 9999;
            margin-left: -256px;
            margin-top: 140px;
            display: none;
        }
        .login-title {
            width: 100%;
            margin: 10px 0px 0px 0px;
            text-align: center;
            line-height: 40px;
            height: 40px;
            font-size: 18px;
            position: relative;
            cursor: move;
            -moz-user-select:none;/*火狐*/
            -webkit-user-select:none;/*webkit浏览器*/
            -ms-user-select:none;/*IE10*/
            -khtml-user-select:none;/*早期浏览器*/
            user-select:none;
        }
        .login-input-content {
            margin-top: 20px;
        }
        .login-button {
            width: 50%;
            margin: 30px auto 0px auto;
            line-height: 40px;
            font-size: 14px;
            border: #ebebeb 1px solid;
            text-align: center;
        }
        .login-bg {
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0px;
            left: 0px;
            background: #000000;
            filter: alpha(opacity=30);
            -moz-opacity: 0.3;
            -khtml-opacity: 0.3;
            opacity: 0.3;
            display: none;
        }
        a {
            text-decoration: none;
            color: #000000;
        }
        .login-button a {
            display: block;
        }
        .login-input input.list-input {
            float: left;
            line-height: 35px;
            height: 35px;
            width: 350px;
            border: #ebebeb 1px solid;
            text-indent: 5px;
        }
        .login-input {
            overflow: hidden;
            margin: 0px 0px 20px 0px;
        }
        .login-input label {
            float: left;
            width: 90px;
            padding-right: 10px;
            text-align: right;
            line-height: 35px;
            height: 35px;
            font-size: 14px;
        }
        .login-title span {
            position: absolute;
            font-size: 12px;
            right: -20px;
            top: -30px;
            background: #ffffff;
            border: #ebebeb solid 1px;
            width: 40px;
            height: 40px;
            border-radius: 20px;
        }
    </style>
</head> 
<body>
<div class="login-header"><a id="link" href="javascript:void(0);">点击,弹出登录框</a></div>
<div id="login" class="login" >
    <div id="title" class="login-title">登录会员
        <span><a id="closeBtn" href="javascript:void(0);" class="close-login">关闭</a></span>
    </div>
    <div class="login-input-content">
        <div class="login-input">
            <label>用户名:</label>
            <input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input">
        </div>
        <div class="login-input">
            <label>登录密码:</label>
            <input type="password" placeholder="请输入登录密码" name="info[password]" id="password" class="list-input">
        </div>
    </div>
    <div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录会员</a></div>
</div>
<!-- 遮盖层 -->
<div id="bg" class="login-bg" ></div> 
<script>
    // 获取元素
    var link = document.getElementById("link");
    var login = document.getElementById("login");
    var bg = document.getElementById("bg");
    var closeBtn = document.getElementById("closeBtn");

    // 添加 link 的点击事件,让登录窗口和遮盖层显示
    link.onclick = function () {
        login.style.display = "block";
        bg.style.display = "block";
    };

    // 添加 btn 的点击事件,让登录窗口和遮盖层隐藏
    closeBtn.onclick = function () {
        login.style.display = "none";
        bg.style.display = "none";
    };
</script>
</body>