zoukankan      html  css  js  c++  java
  • 深度理解DOM事件(实例)

    前言

    通过如下两个实例来理解DOM事件

    1. 实例1--点击别处关闭浮层
    2. onclick与addEventListener的区别

    3. 实例2--点击后颜色一层一个层出现的漂亮的彩虹圈

    1  实例1--点击别处关闭浮层

    • 代码效果演示:原生JSjQuery
    • HTML代码
        <div id="wrapper" class="wrapper">
          <button id="clickMe">点我</button>
          <div id="popover" class="popover">
            <input type="checkbox">浮层
          </div>
        </div>
    • CSS代码
      .wrapper{
        display:inline-block;
        position: relative;
      }
      
      .popover{
        display: none;
        border: 1px orange solid;
        top: 0px;
        /*宽度是上级元素的100%*/
        left: 130%;
        padding: 8px;
        border-radius: 4px;
        position: absolute;
        background: white;
        /*规定段落中的文本不进行换行*/
        white-space: nowrap;
        
      }
      /*画浮层左边的小指向箭头*/
      .popover::before{
        position: absolute;
        right: 100%;
        top: 4px;
        border: 10px solid transparent;
        border-right-color: orange;
        content: '';
      }
      .popover::after{
        position: absolute;
        right: 100%;
        top: 4px;
        border: 10px solid transparent;
        border-right-color: white;
        content: '';
        margin-right: -1px;
      }
    • JS代码-原生js 
      /*点击按钮触发浮层*/
      clickMe.addEventListener('click', function(){
        popover.style.display = 'block'
      })
      /*阻止默认事件*/
      wrapper.addEventListener('click', function(e){
         e.stopPropagation()
       })
      /*点击任意处关闭浮层*/
      document.addEventListener('click', function(){
        popover.style.display = 'none'
      })
    • JS代码-jQuery
      $(clickMe).on('click',function(){
        $(popover).show()
        /*如果不加定时器会同步执行show()和hide(),即看起来什么都没有发生*/
        setTimeout(function(){
           $(document).one('click', function() {
             $(popover).hide()
           })
        },0)
      })

    2  onclick与addEventListener的区别

    • 实例1使用的原生JS,为什么使用addEventListener(),而不使用onclick() --onclick()只能添加一个事件,多个事件时只会输出最后一个,而实例1中存在多个事件,不能用onclick()
    • onclick与addEventListener实际上可分为:Inline events与Event Listeners
    • Event Listeners (“addEventListener” and “IE's attachEvent”)
      • 两者相同点:都是时间监听器。
      • 两者不同点:
        • addEventListener:很多浏览器支持addEventListener(IE9、IE10、IE11、chrome、firefox、opera、safari支持),使用方式如下:
          //addEventListener接受三个参数,最后一个参数默认是false。(false表示事件处理将在冒泡阶段执行,true表示事件处理将在捕获阶段执行)
          //addEventListener(type,listener,options) 
          var target = document.getElementById("test");
          target.addEventListener('click',function test(){
                  console.log("Hi");
          },false)
        • attachEvent:IE中提供的类似addEventListener的事件监听器,使用方式如下:
          //qqq
          var target = document.getElementById("test");
          target.attachEvent('onclick',test);
          function test(){
               console.log("Hi");
          }
        • 理论上,Event Listeners (addEventListener and IE's attachEvent)可以无限增加事件监听给某个一元素。实际应用的约束就是客户端内存的限制,这一点因每个浏览器而异
          var target = document.getElementById("test");
          target.addEventListener('click',function test(){
                  console.log("Hi");
          },false)
          target.addEventListener('click',function test(){
                  console.log("Hello");
          },false)
          //Hi
          //Hello
    •  Inline events (“HTML onclick="" property” and “element.onclick”)
      • 使用方式:
        • onclick=""    
          <a id="test" href="#" onclick="function()">clickMe</a>
        • element.onclick      
          <a id="test" href="#">clickMe</a>
           
          var target = document.getElementById('test')
          target.onclick = function(){
              console.log('Hi');
          }
        • Inline events只能添加一个事件,如果同时有多个,只会输出最后一个的结果   
          var target = document.getElementById('tttt')
          target.onclick = function(){
              console.log('Hi');
          }
          target.onclick = function(){
              console.log('Hello');
          }
          //Hello

           

    • Inline events与Event Listeners的区别:Event Listeners可以添加无数个(理论上)事件,Inline events只能添加1个事件,且下面的会覆盖上面的。
     

    3  实例2--点击后颜色一层一个层出现的漂亮的彩虹圈

    • 代码效果:彩虹圈
    • HTML代码
      <div class="red">
        <div class="blue">
          <div class="green">
            <div class="yellow">
              <div class="orange">
                <div class="purple">
                  
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    • CSS代码
      *{margin:0;padding:0;box-sizing:border-box;}
      
      //设置背景颜色
      .red.active { background: red; }
      .blue.active { background: blue; }
      .green.active { background: green; }
      .yellow.active { background: yellow; }
      .orange.active { background: orange; }
      .purple.active { background: purple; }
      
      //设置一层一层圆圈以及动画过渡事件
      div {
        border: 1px solid black;
        padding: 10px;
        transition: all 0.5s;
        display: flex;
        flex:1;
        border-radius: 50%;
        background: white;
      }
      
      //设置最外圈的长宽
      .red{  100vw; height: 100vw; }
    • JS代码
      let divs = $('div').get()
      let n = 0
      
      for (let i = 0; i < divs.length; i++) {
         //addEventListener()最后一个参数为true
         //即执行捕获阶段--从外层到里层,即从爷爷到儿子
        divs[i].addEventListener('click', function() {
          setTimeout(function() {
            divs[i].classList.add('active')
          }, n * 500)
          n += 1
        }, true)
      }
      
      for (let i = 0; i < divs.length; i++) {
         //addEventListener()最后一个参数为false
         //即执行冒泡阶段--从里层到外层,即从儿子到爷爷
        divs[i].addEventListener('click', function() {
          setTimeout(function() {
            divs[i].classList.remove('active')
          }, n * 500)
          n += 1
        }, false)
      }
      
      //⚠️有一个特殊情况:即如果都是自己身上同时捕获(true)和冒泡(false),此时执行顺序和捕获(true)和冒泡(false)无关,谁在前面就先执行哪个
  • 相关阅读:
    设计模式——装饰器模式
    设计模式——适配器模式
    Java IO概述
    Java中的注解
    痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(3)- Serial Downloader模式(sdphost/MfgTool)
    痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(2)- Boot配置(BOOT Pin/eFUSE)
    痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(1)- Boot简介
    痞子衡嵌入式:ARM Cortex-M内核那些事(5)- 一表搜罗指令集
    痞子衡嵌入式:SEGGER J-Link仿真器硬件版本变迁
    痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU特性那些事(4)- RT105x选型
  • 原文地址:https://www.cnblogs.com/nolaaaaa/p/9123364.html
Copyright © 2011-2022 走看看