JS Dom事件流

94 阅读1分钟

事件:系统内发生的动作或事情

  • 用户触发:鼠标点击、滚动、拖拽、键盘按下
  • 系统生成:文档或图片加载完成、动画结束、视频播放暂停
  • JS出发:例如调用HTMLElemeng.click()
  • 创建自定义事件,并触发EventTarget.dispatchEvent()

1)设置事件监听函数;2)事件触发被监听函数响应

示例:

    <div class="box"></div>
    <style>
        .box{
            width: 120px;
            height: 120px;
            background-color: rgba(165, 42, 2);
            cursor: pointer;
        }
    </style>
    <script>
        function rand(num){
            return Math.floor(Math.random()*num)
        }
        document.querySelector('.box').addEventListener('click', function(){		//两个参数,要监听的事件类型和一个函数;函数可以单独声明,在里面写函数名不写(),如果函数后跟()则该函数会立即执行
            this.style.backgroundColor = `rgb(${rand(256)},${rand(256)},${rand(256)})`			//this代表querySelector选中的对象
        })
    </script>

事件绑定

  • 方法
  1. node.onclick = fun() { ... }
  2. node.addEventListener('click', fun() { ... })
  • 区别
  1. onclick绑定是赋值,多次相同赋值会覆盖,只有最后一次生效
  2. addEventListener 是函数执行,可执行/绑定多次,且功能更强大
        let obj = {}
        obj.onclick = function(num){
            console.log(num);
        }
        obj.onclick = function(str){
            console.log(str);
        }
        console.log(obj.onClick);					//打印出第二个函数,因为第二个赋值覆盖掉第一个赋值,只有最后一次生效

this与事件对象

事件传递的函数会有一个形参

        <div class="box"></div>
				let $box = document.querySelector('.box')
        $box.onclick = function(event){
            console.log(event);					//event是事件对象
            console.log(this);					//this代表$box
        }
  • 事件对象包括clientX: 14, clientY: 54, (事件的位置、事件的来源、按了哪个键等这些信息
  • 事件绑定时
  1. 普通函数里面的this代表事件绑定的对象
  2. 箭头函数里面的this代表外面的this 即window 因为箭头函数没有自己的this
  3. 在非严格模式下,this是undefined
        $box.onclick = (evt) => {
            console.log(this);						//打印出该页面(Window
        }

事件流

  • 事件传播有三个阶段

1-3是事件捕获阶段

3-4是目标阶段

4-7是事件冒泡阶段

addEventListener 详细用法

target.addEventListener(type, listener, useCapture)

  • type 事件类型 如click等
  • listener 事件处理方法 通常为一个函数
  • useCapture 可选,默认false,true表示在捕获阶段调用listener,false表示冒泡阶段处理

target.addEventListener(type, listener(e), options)

  • options:可选 {capture:是否捕获阶段监听;once:是否只监听一次;passive:是否忽略preventDefault,用于提升移动端性能
  • once即只响应一次
  • e.target代表点击的对象

target.removeEventlistener 用于解除事件绑定

  • 如 target.removeEventListener('click', handler)

事件冒泡

  • stopPropagation 阻止事件继续往外传播 用法

target.onclick = (e) => { e.stopPropagation() } //阻止该事件往外传播

  • e.preventDefault() 阻止默认事件发生(如点击a链接跳转
        <a href="https://baidu.com" alt="百度">百度一下</a>
  	 	 	<a href="https://bilibili.com" alt="bilibili">bilibili</a>
				const $$ = s => document.querySelectorAll(s)
        $$('a').forEach($a => {
            $a.addEventListener('click', function(e){
                let href = this.getAttribute('href')
                if(href.includes('baidu.com')){
                    e.preventDefault()
                    if(confirm('要打开百度吗?')){
                        location.href = href
                    }
                }
            })
        })

事件代理/委托

  • 事件绑定代理给父元素,由父元素根据事件来源统一处理
  • 适用于可能会新增子元素的场景
  • 事件代理实际上是事件冒泡的应用

如,任何事件都会冒泡到document阶段,可以在document上绑定事件,通过e.target判断事件发生在哪个区域