JavaScript核心知识第二章---事件高级(含大量代码分析)

eventTarget.attachEvent()方法将指定的监听器注册到 eventTarget(目标对象) 上,当该对象触发指定的事件时,指定的回调函数就会被执行。

该方法接收两个参数:

  • eventNameWithOn:事件类型字符串,比如 onclick 、onmouseover ,这里要带 on;

  • callback:事件处理函数,当目标触发事件时回调函数被调用;

😆温馨提醒😆:IE8 及早期版本支持;

代码演示如下:


<body>

    <button>传统注册事件</button>

    <button>方法监听注册事件</button>

    <button>ie9 attachEvent</button>

    <script>

        var btns = document.querySelectorAll('button');

        // 1. 传统方式注册事件

        btns[0].onclick = function() {

            alert('hi');

        }

        btns[0].onclick = function() {

                alert('hi DJ');

            }

            // 2. 事件侦听注册事件 addEventListener 

            // (1) 里面的事件类型是字符串 必定加引号 而且不带on

            // (2) 同一个元素 同一个事件可以添加多个侦听器(事件处理程序)

        btns[1].addEventListener('click', function() {

            alert(24);

        })

        btns[1].addEventListener('click', function() {

                alert(30);

            })

            // 3. attachEvent ie9以前的版本支持

        btns[2].attachEvent('onclick', function() {

            alert(99);

        })

    </script>

</body>



1.4 注册事件兼容性解决方案

代码演示如下:


 function addEventListener(element, eventName, fn) {

      // 判断当前浏览器是否支持 addEventListener 方法

      if (element.addEventListener) {

        element.addEventListener(eventName, fn);  // 第三个参数 默认是false

      } else if (element.attachEvent) {

        element.attachEvent('on' + eventName, fn);

      } else {

        // 相当于 element.onclick = fn;

        element['on' + eventName] = fn;

 } 



😆兼容性处理的原则😆:首先照顾大多数浏览器,再处理特殊浏览器;


(2)删除事件(解绑事件)

2.1 删除事件的方式

1️⃣ 传统注册方式


eventTarget.onclick = null;



2️⃣ 方法监听注册方式


1. eventTarget.removeEventListener(type, listener[, useCapture]);

2. eventTarget.detachEvent(eventNameWithOn, callback);



完整代码演示如下:


<!DOCTYPE html>

<html lang="en">



<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>

    <style>

        div {

            width: 100px;

            height: 100px;

            background-color: pink;

        }

    </style>

</head>



<body>

    <div>1</div>

    <div>2</div>

    <div>3</div>

    <script>

        var divs = document.querySelectorAll('div');

        divs[0].onclick = function () {

            alert(11);

            // 1. 传统方式删除事件

            divs[0].onclick = null;

        }

        // 2. removeEventListener 删除事件

        divs[1].addEventListener('click', fn) // 里面的fn 不需要调用加小括号



        function fn() {

            alert(22);

            divs[1].removeEventListener('click', fn);

        }

        // 3. detachEvent

        divs[2].attachEvent('onclick', fn1);



        function fn1() {

            alert(33);

            divs[2].detachEvent('onclick', fn1);

        }

    </script>

</body>



</html>



2.2 删除事件兼容性解决方案

代码演示如下:


 function removeEventListener(element, eventName, fn) {

      // 判断当前浏览器是否支持 removeEventListener 方法

      if (element.removeEventListener) {

        element.removeEventListener(eventName, fn);  // 第三个参数 默认是false

      } else if (element.detachEvent) {

        element.detachEvent('on' + eventName, fn);

      } else {

        element['on' + eventName] = null;

 } 




(3)DOM 事件流

1️⃣ 事件流描述的是从页面中接收事件的顺序。

2️⃣ 事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即 DOM 事件流。

3️⃣ DOM 事件流分为3个阶段:

  1. 捕获阶段;

  2. 当前目标阶段;

  3. 冒泡阶段;

  • 事件冒泡: IE 最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点的过程;

  • 事件捕获: 网景最早提出,由 DOM 最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程;

完整代码演示如下:


<!DOCTYPE html>

<html lang="en">



<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>

    <style>

        .father {

            overflow: hidden;

            width: 300px;

            height: 300px;

            margin: 100px auto;

            background-color: pink;

            text-align: center;

        }

        

        .son {

            width: 200px;

            height: 200px;

            margin: 50px;

            background-color: purple;

            line-height: 200px;

            color: #fff;

        }

    </style>

</head>



<body>

    <div class="father">

        <div class="son">son盒子</div>

    </div>

    <script>

        // dom 事件流 三个阶段

        // 1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。

        // 2. onclick 和 attachEvent(ie) 只能得到冒泡阶段。

        // 3. 捕获阶段 如果addEventListener 第三个参数是 true 那么则处于捕获阶段  document -> html -> body -> father -> son

        // var son = document.querySelector('.son');

        // son.addEventListener('click', function() {

        //     alert('son');

        // }, true);

        // var father = document.querySelector('.father');

        // father.addEventListener('click', function() {

        //     alert('father');

        // }, true);

        // 4. 冒泡阶段 如果addEventListener 第三个参数是 false 或者 省略 那么则处于冒泡阶段  son -> father ->body -> html -> document

        var son = document.querySelector('.son');

        son.addEventListener('click', function() {

            alert('son');

        }, false);

        var father = document.querySelector('.father');

        father.addEventListener('click', function() {

            alert('father');

        }, false);

        document.addEventListener('click', function() {

            alert('document');

        })

    </script>

</body>



</html>



😆温馨提醒😆:

  1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。

  2. onclickattachEvent 只能得到冒泡阶段。

  3. addEventListener(type, listener[, useCapture])第三个参数如果是 true,表示在事件捕获阶段调用事件处理程序;如果是 false(不写默认就是false),表示在事件冒泡阶段调用事件处理程序。

  4. 实际开发中我们很少使用事件捕获,我们更关注事件冒泡。

  5. 有些事件是没有冒泡的,比如 onbluronfocusonmouseenteronmouseleave

  6. 事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件,我们后面讲解。


(4)事件对象

4.1 什么是事件对象

eventTarget.onclick = function(event) {} 

eventTarget.addEventListener('click', function(event) {})

// 这个 event 就是事件对象,我们还喜欢的写成 e 或者 evt 



1️⃣ 官方解释:event 对象代表事件的状态,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态。

2️⃣ 简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象 event,它有很多属性和方法。

比如:

  1. 谁绑定了这个事件。

  2. 鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置。

  3. 键盘触发事件的话,会得到键盘的相关信息,如按了哪个键。

4.2 事件对象的使用语法

eventTarget.onclick = function(event) {

	// 这个 event 就是事件对象,我们还喜欢的写成 e 或者 evt 

  } 

eventTarget.addEventListener('click', function(event) {

    // 这个 event 就是事件对象,我们还喜欢的写成 e 或者 evt 

  })



这个 event 是个形参,系统帮我们设定为事件对象,不需要传递实参过去。

当我们注册事件时, event 对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)。

4.3 事件对象的兼容性方案

事件对象本身的获取存在兼容问题:

  1. 标准浏览器中是浏览器给方法传递的参数,只需要定义形参 e 就可以获取到。

  2. 在 IE6~8 中,浏览器不会给方法传递参数,如果需要的话,需要到 window.event 中获取查找。

😆解决😆:e = e || window.event;

4.4 事件对象的常见属性和方法

| 事件对象属性方法 | 说明 |

| — | — |

| e.target | 返回触发事件的对象 标准 |

| e.srcElement | 返回触发事件的对象 非标准 ie6-8使用 |

| e.type | 返回事件的类型 比如 click mouseover,不带on |

| e.canselBubble | 该属性阻止冒泡 非标准 ie6-8使用 |

| e.returnValue | 该属性阻止默认事件(默认行为) 非标准 ie6-8使用,比如不让链接跳转 |

| e.prevenDefault() | 该方法阻止默认事件(默认行为) 标准,比如不让链接跳转 |

| e.stopPropagation() | 阻止冒泡 标准 |

完整代码演示如下:


<!DOCTYPE html>

<html lang="en">



<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>

</head>



<body>

    <div>123</div>

    <a href="http://www.baidu.com">百度</a>

    <form action="http://www.baidu.com">

        <input type="submit" value="提交" name="sub">

    </form>

    <script>

        // 常见事件对象的属性和方法

        // 1. 返回事件类型

        var div = document.querySelector('div');

        div.addEventListener('click', fn);

        div.addEventListener('mouseover', fn);

        div.addEventListener('mouseout', fn);



        function fn(e) {

            console.log(e.type);



        }

        // 2. 阻止默认行为(事件) 让链接不跳转 或者让提交按钮不提交

        var a = document.querySelector('a');

        a.addEventListener('click', function(e) {

                e.preventDefault(); //  dom 标准写法

            })

            // 3. 传统的注册方式

        a.onclick = function(e) {

            // 普通浏览器 e.preventDefault();  方法

            // e.preventDefault();

            // 低版本浏览器 ie678  returnValue  属性

            // e.returnValue;

            // 我们可以利用return false 也能阻止默认行为 没有兼容性问题 特点: return 后面的代码不执行了, 而且只限于传统的注册方式

            return false;

            alert(11);

        }

    </script>

</body>



</html>



😆e.targetthis 的区别😆:

  • this 是事件绑定的元素, 这个函数的调用者(绑定这个事件的元素);

  • e.target 是事件触发的元素;

完整代码演示如下:


<!DOCTYPE html>

<html lang="en">



<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>

    <style>

        div {

            width: 100px;

            height: 100px;

            background-color: pink;

        }

    </style>

</head>



<body>

    <div>123</div>

    <ul>

        <li>abc</li>

        <li>abc</li>

        <li>abc</li>

    </ul>

    <script>

        // 常见事件对象的属性和方法

        // 1. e.target 返回的是触发事件的对象(元素)  this 返回的是绑定事件的对象(元素)

        // 区别 : e.target 点击了那个元素,就返回那个元素 this 那个元素绑定了这个点击事件,那么就返回谁

        var div = document.querySelector('div');

        div.addEventListener('click', function (e) {

            console.log(e.target);

            console.log(this);



        })

        var ul = document.querySelector('ul');

        ul.addEventListener('click', function (e) {

            // 我们给ul 绑定了事件  那么this 就指向ul  

            console.log(this);

            console.log(e.currentTarget);



            // e.target 指向我们点击的那个对象 谁触发了这个事件 我们点击的是li e.target 指向的就是li

            console.log(e.target);



        })

        // 了解兼容性

        // div.onclick = function(e) {

        //     e = e || window.event;

        //     var target = e.target || e.srcElement;

        //     console.log(target);

        // }

        // 2. 了解 跟 this 有个非常相似的属性 currentTarget  ie678不认识

    </script>

</body>



</html>




(5)阻止事件冒泡

5.1 阻止事件冒泡的两种方式

事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点。

事件冒泡本身的特性,会带来的坏处,也会带来的好处,需要我们灵活掌握。

阻止事件冒泡:

  • 标准写法:利用事件对象里面的 stopPropagation()方法;

e.stopPropagation()



  • 非标准写法:IE 6-8 利用事件对象 cancelBubble 属性;

e.cancelBubble = true;



完整代码演示如下:


<!DOCTYPE html>

<html lang="en">



<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>

    <style>

        .father {

            overflow: hidden;

            width: 300px;

            height: 300px;

            margin: 100px auto;

            background-color: pink;

            text-align: center;

        }

        

        .son {

            width: 200px;

            height: 200px;

            margin: 50px;

            background-color: purple;

            line-height: 200px;

            color: #fff;

        }

    </style>

</head>



<body>

    <div class="father">

        <div class="son">son儿子</div>

    </div>

    <script>

        // 常见事件对象的属性和方法

        // 阻止冒泡  dom 推荐的标准 stopPropagation() 

        var son = document.querySelector('.son');

        son.addEventListener('click', function(e) {

            alert('son');

            e.stopPropagation(); // stop 停止  Propagation 传播

            e.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡

        }, false);



        var father = document.querySelector('.father');

        father.addEventListener('click', function() {

            alert('father');

        }, false);

        document.addEventListener('click', function() {

            alert('document');

        })

    </script>

</body>



</html>



5.2 阻止事件冒泡的兼容性解决方案

代码演示如下:


if(e && e.stopPropagation){

	e.stopPropagation();

}else{

    window.event.cancelBubble = true;

}




(6)事件委托(代理、委派)

1️⃣ 事件委托:事件委托也称为事件代理, 在 jQuery 里面称为事件委派。

2️⃣ 事件委托的原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点 ❗️ ❗️ ❗️

3️⃣ 事件委托的作用:只操作了一次 DOM,提高了程序的性能。

完整代码演示如下:


<!DOCTYPE html>

<html lang="en">



<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>

</head>



<body>

    <ul>

        <li>浮世三千,吾有三爱,日月与卿,日为朝,月为暮,卿为朝朝暮暮。 --飞鸟集</li>

        <li>浮世三千,吾有三爱,日月与卿,日为朝,月为暮,卿为朝朝暮暮。 --飞鸟集</li>

        <li>浮世三千,吾有三爱,日月与卿,日为朝,月为暮,卿为朝朝暮暮。 --飞鸟集</li>

        <li>浮世三千,吾有三爱,日月与卿,日为朝,月为暮,卿为朝朝暮暮。 --飞鸟集</li>

        <li>浮世三千,吾有三爱,日月与卿,日为朝,月为暮,卿为朝朝暮暮。 --飞鸟集</li>

    </ul>

    <script>

        // 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点

        var ul = document.querySelector('ul');

        ul.addEventListener('click', function(e) {

            // alert('知否知否,点我应有弹框在手!');

            // e.target 这个可以得到我们点击的对象

            e.target.style.backgroundColor = 'pink';

        })

    </script>

</body>



</html>




(7)常用的鼠标事件

7.1 常用的鼠标事件

| 鼠标事件 | 触发条件 |

| — | — |

| onclick | 鼠标点击左键触发 |

| onmouseover | 鼠标经过触发 |

| onmouseout | 鼠标离开触发 |

| onfocus | 获得鼠标焦点触发 |

| onblur | 失去鼠标焦点触发 |

| onmousemove | 鼠标移动触发 |

| onmouseup | 鼠标弹起触发 |

| onmousedown | 鼠标按下触发 |

1️⃣ 禁止鼠标右键菜单

contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单;


document.addEventListener('contextmenu', function(e) {

	e.preventDefault();

})



2️⃣ 禁止鼠标选中(selectstart 开始选中)


document.addEventListener('selectstart', function(e) {

	e.preventDefault();

})



7.2 鼠标事件对象

event对象代表事件的状态,跟事件相关的一系列信息的集合。

现阶段我们主要是用鼠标事件对象 MouseEvent 和键盘事件对象 KeyboardEvent

| 鼠标事件对象 | 说明 |

| — | — |

| e.clientX | 返回鼠标相对于浏览器窗口可视区的 X 坐标 |

| e.clientX | 返回鼠标相对于浏览器窗口可视区的 Y 坐标 |

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
up | 鼠标弹起触发 |

| onmousedown | 鼠标按下触发 |

1️⃣ 禁止鼠标右键菜单

contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单;


document.addEventListener('contextmenu', function(e) {

	e.preventDefault();

})



2️⃣ 禁止鼠标选中(selectstart 开始选中)


document.addEventListener('selectstart', function(e) {

	e.preventDefault();

})



7.2 鼠标事件对象

event对象代表事件的状态,跟事件相关的一系列信息的集合。

现阶段我们主要是用鼠标事件对象 MouseEvent 和键盘事件对象 KeyboardEvent

| 鼠标事件对象 | 说明 |

| — | — |

| e.clientX | 返回鼠标相对于浏览器窗口可视区的 X 坐标 |

| e.clientX | 返回鼠标相对于浏览器窗口可视区的 Y 坐标 |

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-jjjDnEQs-1715489137887)]

[外链图片转存中…(img-2CUbORG9-1715489137887)]

[外链图片转存中…(img-P4xQjwrs-1715489137887)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 26
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值