JavaScript事件

JavaScript事件

搬运自个人博客:JavaScript事件

注册事件(绑定事件)

给元素添加事件,称为注册事件或者绑定事件。

有传统方式和方法监听方式

传统方式

利用on开头的事件,如onclick, 同一个元素同一个事件只能设置一个处理函数,出现多个处理函数的话,后面的会覆盖前面的。

例子:

	<script>
        var btn = document.querySelector("button");
        btn.onclick = function () {
            console.log(1);
        };
        btn.onclick = function () {
            console.log(2);
        }
        //结果是2
    </script>


方法监听注册方式

addEventListener():

eventTarget.addEventListener(type, listener[, useCapture])

type: 事件类型字符串,如click、mouseover等,不带on

listener: 事件处理函数,事件发生会调用该监听函数

useCapture: 可选参数,是一个布尔值,默认是false。决定监听器的触发阶段是捕获阶段还是冒泡阶段详见

addEventListener() 是 W3C DOM 规范中提供的注册事件监听器的方法。

优点:

  1. 允许给一个事件注册多个监听器

例子:

addEventListener:

        const btn = document.getElementById("btn");

        btn.addEventListener("click", function () {
            console.log(1);
        });
        btn.addEventListener("click", function () {
            console.log(1);
        });

		//结果:1, 1

此处是个人见解:

当两个监听函数一样时,由上可发现会输出两次1,这个其实是因为上面两个匿名函数看似一样,实际它们所开辟的内存空间不一样。

把相同的方法抽出来后会发现,无法实现多个监听,就是因为两个方法变成完全一样了。

    const btn = document.getElementById("btn");

    btn.addEventListener("click", fn)
    btn.addEventListener("click", fn)
    
    function fn() {
      console.log(1);
    }

	//结果:1

  1. 可以控制监听器的触发阶段(可选捕获或冒泡)
  2. 对任何 DOM 元素都是有效的,而不仅仅只对 HTML 元素有效。(未找到合适案例)

参数是匿名函数和是箭头函数区别:

它们绑定不同的this对象。匿名函数和传统方式一样会创建独有的this对象(即触发事件的元素),而箭头函数是继承绑定它所在函数的this对象。

例子:

匿名函数:

	<div id="div">
        <button id="btn">点击</button>
    </div>

    <script>
        const div = document.getElementById("div");

        const btn = document.getElementById("btn");
        div.addEventListener("mouseenter", function () {
            console.log(this);
            btn.addEventListener("click", function () {
                console.log(this);
            })
        });
    </script>

结果:

箭头函数:

	<div id="div">
        <button id="btn">点击</button>
    </div>

    <script>
        const div = document.getElementById("div");

        const btn = document.getElementById("btn");
        div.addEventListener("mouseenter", function () {
            console.log(this);
            btn.addEventListener("click", () => {
                console.log(this);
            })
        });
    </script>

结果:

attachEvent():

eventTarget.attachEvent(eventNameWithOn, callback)

eventNameWithOn: 事件类型字符串。如onclick、onmouseover,要带on

callback: 事件处理函数,事件发生会调用该回调函数

IE9之前的IE不支持,对应有attachEvent(),用法和addEventListener 近似,不过事件需要变回传统方式的on系列。

attachEvent缺点:this的值会变成window对象的引用而不是触发事件的元素。

删除事件(解绑事件)

传统方式

eventTarget.onclick = null;

例子:

		const btn = document.getElementById("btn");
        btn.onclick = function () {
            console.log(1);
        };

        btn.onclick = null;

方法监听注册方式

对应addEventListener

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

移除完全匹配的监听,只有事件处理函数完全一样,包括开辟的内存空间。

完全匹配例子:

		const btn = document.getElementById("btn");
        btn.addEventListener("click", fn); //第二个参数只要函数名就可以,不需要调用
        btn.removeEventListener("click", fn);

        function fn() {
            console.log(1);
        }

不完全匹配例子(开辟的内存空间不一样):

		const btn = document.getElementById("btn");
        btn.addEventListener("click", function () {
            console.log(1);
        });
        btn.removeEventListener("click", function () {
            console.log(1);
        });

DOM事件流

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

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

例如给一个div注册了事件:

DOM事件流分为3个阶段:

  1. 捕获阶段
  2. 当前目标阶段
  3. 冒泡阶段

事件捕获:网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到绑定事件的元素接受的过程。

事件冒泡:IE最早提出,事件逐级向上传播到DOM最顶层节点的过程。

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

注意:

  1. JS代码只能执行捕获或者冒泡其中一个阶段
  2. onclick和attachEvent只能得到冒泡阶段
		const btn = document.getElementById("btn");
        btn.onclick = () => alert(1);
        document.body.onclick = () => alert(2);
        document.documentElement.onclick = () => alert(3);
        document.onclick = () => alert(4);
		//点击按钮后,弹出顺序1、2、3、4

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

为false:

		const btn = document.getElementById("btn");
        btn.addEventListener("click", () => alert(1), false);
        document.body.addEventListener("click", () => alert(2), false);
        document.documentElement.addEventListener("click", () => alert(3));
        document.addEventListener("click", () => alert(4));
		//点击按钮后,弹出顺序1、2、3、4

为true:

		const btn = document.getElementById("btn");
        btn.addEventListener("click", () => alert(1), true);
        document.body.addEventListener("click", () => alert(2), true);
        document.documentElement.addEventListener("click", () => alert(3), true);
        document.addEventListener("click", () => alert(4), true);
		//点击按钮后,弹出顺序4、3、2、1

  1. 有些事件是没有冒泡的,如blur, focus, mouseenter, onmouseleave

例如:

		const btn = document.getElementById("btn");
        btn.addEventListener("mouseleave", () => alert(1));
        document.body.addEventListener("mouseleave", () => alert(2));
        document.documentElement.addEventListener("mouseleave", () => alert(3));
        document.addEventListener("mouseleave", () => alert(4));
		//当鼠标放在按钮里后,离开按钮,只会弹出1

  1. 事件冒泡有时候会带来麻烦,可以通过 e.stopPropagation()方法阻止事件冒泡

事件对象

事件处理函数可以带参数,带的参数就是事件对象。

eventTarget.onclick = function(event) {}

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

如上式所示,event就是事件对象,,它代表事件的状态,如键盘按键的状态、鼠标的位置、鼠标按钮的状态等。事件发生后,跟事件相关的一系列信息的集合都在这个对象里面。

不需要传递实参

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

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

e = e || window.event;

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

e.target和this的区别:

this是事件绑定的元素(匿名函数形式),函数的调用者。

e.target是事件触发的元素。

例子:

		const ul = document.querySelector("ul");
        ul.addEventListener("click", function (e) {
            console.log(this);
            console.log(e.target);
        });
		//点击li里面的文字,依次打印出的是ul和li

阻止默认行为

e.preventDefault()

例子:

		const a = document.querySelector("a");
        a.addEventListener("click", (e) => e.preventDefault());

阻止事件冒泡

e.stopPropagation()

例子:

		const btn = document.getElementById("btn");
        btn.addEventListener("click", (e) => {
            alert(1);
            e.stopPropagation();  //只要在事件处理函数里使用就会执行完这个函数,才阻止冒泡。
								  //不过建议放在最后面,更有逻辑性的感觉
        });
        document.body.addEventListener("click", () => alert(2));
        document.documentElement.addEventListener("click", () => alert(3));
        document.addEventListener("click", () => alert(4));

没加e.stopPropagation()之前会依次弹出1、2、3、4,在按钮绑定的事件中,加上之后只会弹出1

事件委托

事件委托也被称为事件代理,在jQuery里面称为事件委派。

事件委托原理

不需要给每个子结点单独设置事件监听器,而是把事件监听器设置在其父节点上,然后利用冒泡原理去影响子节点。

例子:

		const ul = document.querySelector("ul");
        ul.addEventListener("click", (e) => e.target.style.color = "red");

上面例子:直接给li的父节点绑定监听器,然后利用e.target找到当前点击的li,点击li,事件会冒泡到ul上,而ul上有注册事件,就会触发事件监听器。

作用

只需要操作一次DOM,提高了程序性能。

常用的鼠标事件

ontextmenu:鼠标右键菜单,可用于取消默认的菜单

selectstart:开始选中,可用于禁止选中文字

常用鼠标事件对象属性

案例

跟随鼠标的天使

常用的键盘事件

onkeypress不识别功能键,如ctrl、shift等
执行顺序是: keydown-->keypress-->keyup

首先,keyup是弹起时才会触发的,所以顺序是最后的,所以只需要记得keydown优先级更高就行

		document.addEventListener("keyup", () => console.log("up"));
        document.addEventListener("keydown", () => console.log("down"));
        document.addEventListener("keypress", () => console.log("press"));
		//按非功能键,依次输出顺序down、press、up
		//按功能键,则依次输出down、up

常用键盘事件对象属性

keyCode:返回该键的ASCII值(数字)

onkeydown和onkeyup不区分字母大小写,onkeypress区分字母大小写

案例

模拟京东快递单号查询案例

参考链接:EventTarget.addEventListener()

pink老师前端入门

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值