js: 事件基础

本文深入讲解JavaScript中的事件处理机制,包括事件注册的不同方法、事件函数的特性、如何阻止事件的默认行为以及事件流的概念。同时,探讨了事件代理的原理和应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是事件:
js -> 交互 人可以去操作页面
js -> 事件驱动的方式

用户 -> 操作html元素 -> 产生一个事件 -> 事件主动调用 -> 设定的方法或函数

主要包括了四部分:
事件源: 产生事件的地方
事件的类型: 点击 键盘
事件对象: 记录当时发生事件的所有信息
事件的处理程序: 函数

注册

方法一:

把事件类型和方法注册到html元素上,如<div οnclick="fn()"></div>;

        <div id="div1" onclick="fn()">点击我调用方法</div>
<script>
    function fn() {
        alert('事件函数被调用')
    }
</script>
      

和在js中获取元素后注册,如果div1.onclick,在js中方法后不需要加()。

        <div id="div1">点击我调用方法</div>
<script>
    function fn() {
        alert('事件函数被调用')
    }

    var div1 = document.getElementById('div1');
    div1.onclick = fn;
</script>
      

方法二:

通过调用 系统提供的方法 可以绑定多个事件

addEventListener(事件类型click, 函数fn, 事件处理方式默认冒泡false)

        <div id="div1">点击我调用方法</div>
<script>
    function fn() {
        alert('事件函数被调用')
    }

    div1.addEventListener('click', fn);
    // div1.removeEventListener('click', fn);  // 移出事件方法,参数必须和addEventListener一致
</script>
      

ie8不支持addEventListener方法,使用attachEvent()和detachEvent()方法兼容。

v2-f58d6a4c3d5a19d1111a5b56f808b245_b.gif

事件函数

事件函数比其他普通函数多了一个event参数,这个参数提供了事件的详细信息,如:具体发生的事件元素,鼠标事件:鼠标的位置,点击的状态,键盘事件:键盘的按键等。

        <div id="div1">点击我调用方法</div>
<script>
    function fn(event) {
        console.log(event);
    }
    var div1 = document.getElementById('div1');
    var input1 = document.getElementById('input1');
    div1.addEventListener('click', fn);
    input1.addEventListener('keydown', fn)
</script>
      

v2-c9137757a08c84a91b7b60a769d873f3_b.jpg

v2-201a8c4115c2f58b92a16f53076c5da1_b.jpg

screenX: 741, screenY: 146, (表示屏幕左上角到点击的坐标位置)

clientX: 91, clientY: 2(表示浏览器左上角到点击的坐标位置)

v2-c425db19bedb5f891525683cc0485583_b.jpg

事件默认行为:

如果点击了a标签,但是不想让它跳转,可以使用event.preventDefault()取消默认操作。

ie8中没有event,只有window.event对象,所有要写兼容。

var e = event || window.event

        <a id="a1" href="https://www.baidu.com" target="_blank">百度一下,你就知道</a>
<script>
    function fn(event) {
        event.preventDefault();     // 取消默认操作
        console.log(event);
    }
 
    var a1 = document.getElementById('a1');
    a1.addEventListener('click', fn);
</script>
      

如果是addEventListener注册的事件函数,只能使用event.preventDefault()这种取消默认事件的方式;如果是使用a1.onclick注册的,可以使用event.preventDefault()和return false皆可。

如果是ie8,使用event.returnValue = false(默认true) 来取消默认行为。


事件流

事件的传播:在默认的情况下,处在传播路径上的标签都会监听到对应的事件。

传播路径:

v2-87484518a26bf32655c65603359640a5_b.jpg
        <!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>事件基础</title>
    <style>
 #div1 {
 width: 200px;
 height: 200px;
 background: #faff72;
 text-align: center;
 border-radius: 10%;
        }
 #div2 {
 width: 100px;
 height: 100px;
 background: #3eede7;
 text-align: center;
 margin-left: 50px;
 border-radius: 10%;
        }
    </style>
</head>
<body>
    <div id="div1">
        我是div1
        <div id="div2">
            我是div2
        </div>
    </div>
    <script>
 var div1 = document.getElementById('div1');
 var div2 = document.getElementById('div2');

 div1.addEventListener('click', div1Click);
 div2.addEventListener('click', div2Click);

 function div1Click() {
 console.log('我是div1的事件函数')
        }
 function div2Click() {
 console.log('我是div2的事件函数')
        }
    </script>
</body>
</html>
      

v2-e3fd0ef4d875fad08a7fa13dde80827e_b.gif

事件流: 对应标签接收到事件的顺序。

两大阶段:

捕获阶段: 从起始点(document) -> 目标位置

冒泡阶段: 目标位置 -> 起始点

v2-ec76cec92efed832656d6e9f46574a41_b.jpg

addEventListener('click', div1Click, false); 在冒泡阶段执行

addEventListener('click', div1Click, true); 在捕获阶段执行

两个阶段一起执行的样子: 先执行捕获,再执行冒泡。

        var div1 = document.getElementById('div1');
 var div2 = document.getElementById('div2');

 // 捕获阶段
 div1.addEventListener('click', div1Clicktrue, true);
 div2.addEventListener('click', div2Clicktrue, true);
 function div1Clicktrue() {
 console.log('我是div1 捕获阶段')
        }
 function div2Clicktrue() {
 console.log('我是div2 捕获阶段')
        }

 // 冒泡阶段
 div1.addEventListener('click', div1Clickfalse, false);
 div2.addEventListener('click', div2Clickfalse, false);
 function div1Clickfalse() {
 console.log('我是div1 冒泡阶段')
        }
 function div2Clickfalse() {
 console.log('我是div2 冒泡阶段')
        }

      

v2-c0a371642d17f681740fb5dc1916a8c9_b.gif

终止冒泡事件:

        function div2Clickfalse(e) {
    e.stopPropagation();            // 使用这个方法终止冒泡事件
    console.log('我是div2 冒泡阶段')
}

      

v2-382b530f3803521854dd42e1bff27cdd_b.gif


事件代理:

假设有一个ul, 它地下有一些li(动态),每个li都要绑定事件。

因为li的父级是ul,所有可以利用冒泡找target目标来实现。

        <ul id="ul1">
    <li>li1</li>
    <li>li2</li>
    <li>li3</li>
    <li>li4</li>
    <li>li5</li>
</ul>
<script>
    var ul1 = document.getElementById('ul1');
    ul1.addEventListener('click', ulClick, false)
    function ulClick(e) {
        console.log(e)
        console.log(e.target)
        e.target.style.color = "red";
    }
</script>
      

v2-68350f86104577b2d6ac024daa4fcae8_b.gif

再来一段:

        <div id="div1">
    <div>我是div2</div>
    <div>我是div3</div>
    <div>我是div4</div>
</div>
<script>
    var div1 = document.getElementById('div1');

    // 冒泡阶段
    div1.addEventListener('click', div1Clickfalse, false);
    function div1Clickfalse(e) {
        console.log(e.target)
        console.log('我是div1 冒泡阶段')
    }
</script>
      

v2-5e2cb04fc26b52898ff62e41d0d01b1c_b.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值