美文网首页
32-进阶:DOM事件

32-进阶:DOM事件

作者: 格林姆大师 | 来源:发表于2018-07-29 23:58 被阅读0次

上个图复习一下:


image.png

1. 点击别处关闭图层

html:

<body>
    <div id="wrapper" class="wrapper">
        <button id="clickMe" >点我</button>
        <div id="popover" class="popover">浮层</div>
    </div>
</body>

css:

.wrapper{
    border: 1px solid red;
    position: relative;
    display: inline-block;
  }
  .popover{
    border: 1px solid black;
    position: absolute;
    left: 100%;
    white-space: nowrap;
    top: 0;
    margin-left: 20px;
    padding: 10px;
  }
  .popover::before{
    content: '';
    border: 10px solid transparent;
    border-right-color: black;
    position: absolute;
    right: 100%;
    top: 0;
  }
  .popover::after{
    content: '';
    border: 10px solid transparent;
    border-right-color: white;
    position: absolute;
    right: 100%;
    top: 0;
    margin-left: 100px;  /* 问题1: 此句无任何效果??? */
    margin-right: -1px;
  }

js思路:


js版本1.0:

clickMe.addEventListener('click',function(){
  popover.style.display = 'block'
})
document.body.addEventListener('click',function(){
  popover.style.display = 'none'
  console.log(1)
})

document.body.addEventListener-将外部区域事件添加到body上。
问题:body的高度有内部文档流的高度总和决定,实际点击时有问题。


js版本1.1:

//将外部区域事件添加到document上
document.addEventListener('click',function(){
    popover.style.display = 'none'
    console.log(2)
})

//将外部区域事件添加到html上
document.documentElement.addEventListener('click',function(){
    popover.style.display = 'none'
    console.log(3)
})

将外部区域事件添加到document和html上能达到点击外部区域的要求;
问题:实际点击 clickMe 浮层并没有出现;
采用debugger调试法,如下:

clickMe.addEventListener('click',function(){
    popover.style.display = 'block'
    debugger
  })
document.addEventListener('click',function(){
    popover.style.display = 'none'
    console.log(2)
})

事件过程见下图:


image.png

js版本2.0---阻止事件冒泡:

clickMe.addEventListener('click',function(e){
    popover.style.display = 'block'
    e.stopPropagation()
  })

document.addEventListener('click',function(){
    popover.style.display = 'none'
    console.log(2)
})

event.stopPropagation()---阻止捕获和冒泡阶段中当前事件的进一步传播;
此版本在功能上基本达到要求;
问题:点击 浮层 元素时 浮层也会消失???
改进:

clickMe.addEventListener('click',function(e){
    popover.style.display = 'block'
})
wrapper.addEventListener('click',function(e){
    e.stopPropagation()
})

document.addEventListener('click',function(){
    popover.style.display = 'none'
    console.log(2)
})

将event.stopPropagation() 添加在 元素wrapper 上;
上述改进方案基本实现了要求,不过还有点问题‘
问题:document 上每添加一个事件,都要好用一点内存,如果document 上的事件很多,会严重耗费资源。。。。。。


js版本3.0---jQuery的方案:

<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="./style.css">
    <script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
</head>
<body>
    <div id="wrapper" class="wrapper">
        <button id="clickMe" >点我</button>
        <div id="popover" class="popover">
            <input type="checkbox">浮层
        </div>
    </div>
</body>
<script src="main.js"></script>
</html>
$(clickMe).on('click',function(){
    $(popover).show()
})

$(wrapper).on('click',false)
// 等价于---
// $(wrapper).on('click',function(e){
//     e.preventDefault()
//     e.stopPropagation()
// })

$(document).on('click',function(){
    $(popover).hide()
})

以上采用jQuery重新实现2.0版本,
$(wrapper).on('click',false)----既阻止默认事件,又阻止事件传播;
阻止默认事件 会引起一个问题---<input type="checkbox">无法被选中;因此,是使用阻止默认事件是得注意范围;
改为:

$(wrapper).on('click',function(e){
    e.stopPropagation()
})

js版本4.0---节省内存资源:

$(clickMe).on('click',function(){
    $(popover).show()
    $(document).one('click',function(){
        $(popover).hide()
    })
})

$(wrapper).on('click',function(e){
    e.stopPropagation()
})

$(document).one('click',function(){})----只监听一次;
以上只在点击 clickMe元素 后才开始监听一次 document 点击,完成一次监听后就清理了,这样就能少占用资源了;


js版本4.1---节省内存资源---优化尝试:

$(clickMe).on('click',function(){
    $(popover).show()
    $(document).one('click',function(){
        $(popover).hide()
    })
})

省去阻止冒泡事件后发现,点击 clickMe 浮层并没有出现????
测试:

$(clickMe).on('click',function(){
    $(popover).show()
    console.log('show')
    $(document).one('click',function(){
        console.log('我觉得点击clickMe时,这里应该不会执行')
        console.log('hide')
        $(popover).hide()
    })
})

测试结果:第一次点击 clickMe 时,$(popover).hide() 就已经执行了????
图解如下:

image.png
解决方法:1-添加阻止冒泡事件;2-设定一个定时器来延时(改变执行次序)
方法2如下:
$(clickMe).on('click',function(){
    $(popover).show()
    console.log('show')
    setTimeout(function(){
        $(document).one('click',function(){
            console.log('我觉得点击clickMe时,这里应该不会执行')
            console.log('hide')
            $(popover).hide()
        })
    },0)
})

注意上述 setTimeout 中的事件设定为0ms,但是,依然可以达到改变执行时序的效果,也就是说,setTimeout 会在当前的代码执行完后才开始计算延时时间;
测试:


结果:

//点击clickMe时
show
点击clickMe事件走到了document
添加 one click
点击clickMe事件走到了document

//点击document时
我觉得点击clickMe时,这里应该不会执行
hide

测试:

<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<div class="red">
  <div class="blue">
    <div class="green">
      <div class="yellow">
        <div class="orange">
          <div class="purple"></div>
        </div>
      </div>
    </div>
  </div>
</div>
</body>
</html>
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
div{
  padding: 20px;
  border: 1px solid black;
  /* border-radius: 50%; */
  transition: all 0.5s;
  display: flex;
  flex: 1;
}
.red{
  width: 100vw;
  height: 100vw;
}
.red.active{
  background-color: red;
}
.blue.active{
  background-color: blue;
}
.green.active{
  background-color: green;
}
.yellow.active{
  background-color: yellow;
}
.orange.active{
  background-color: orange;
}
.purple.active{
  background-color: purple;
}
var n=0
$('div').on('click',function(e){
  setTimeout(function(){
    $(e.currentTarget).addClass('active')
    console.log(n)
  },n*500)
  n=n+1
})

相关文章

  • 32-进阶:DOM事件

    上个图复习一下: 1. 点击别处关闭图层 html: css: js思路: js版本1.0: document.b...

  • 进阶篇:事件对象 (12-2)

    饥人谷学习进阶第 12 天 事件对象 在触发DOM上某个事件时会产生一个事件对象event,这个对象包含着所有与事...

  • 前端面试题(3)——DOM事件类

    基本概念:DOM事件的级别 DOM事件模型:事件冒泡事件捕获 DOM事件流 描述DOM事件捕获的具体流程 Even...

  • DOM事件

    DOM级别与DOM事件 DOM级别:DOM0级、DOM1级、DOM2级、DOM3级DOM事件:DOM0级事件处理、...

  • DOM事件

    DOM级别与DOM事件 DOM级别:DOM0级,DOM1级,DOM2级和DOM3级DOM事件:DOM0级事件处理,...

  • html5学习路线(粗略)

    ●HTML5+CSS3●常用浏览器兼容交互篇●JavaScript基础●DOM和BOM●动画特效●事件交互进阶篇●...

  • DOM0和DOM2级事件简单理解

    关于DOM0 和DOM1级事件可以简单理解为:事件分为DOM 0级事件和Dom 2级事件,DOM2级事件也叫做事件...

  • task33 进阶:DOM 事件

    上一次课程的dom events知识? 用实际例子学习dom事件模型——点击别处关闭浮层的效果搜 bootstra...

  • Dom事件

    基本概念 Dom事件级别 Dom事件模型 Dom事件流 描述Dom事件捕获的具体流程 Event对象的常见应用 自...

  • 3-6 DOM事件

    问题 DOM 事件的级别 DOM 事件模型(就是捕获和冒泡儿) DOM 事件流 描述DOM事件捕获的具体流程 Ev...

网友评论

      本文标题:32-进阶:DOM事件

      本文链接:https://www.haomeiwen.com/subject/fqlymftx.html