事件对象+事件流

315 阅读4分钟

事件对象

介绍:

一个事件触发的瞬间所生成的信息的集合,比如鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息等。

如何获取事件对象

在事件绑定的回调函数的第一个参数就是事件对象,一般命名为event、ev、e;如

image-20220416203038768

调用事件对象

元素.addEventListener('click', function (ev) {

            // 调用事件对象
            console.log(ev.type)//click
        })

部分常用属性

1、type---获取当前的事件类型;

2、clientX/clientY---获取光标相对于浏览器可见窗口左上角的位置;

3、offsetX/offsetY---获取光标相对于当前DOM元素左上角的位置;

4、key---用户按下的键盘键的值。

使用方法:

<body>
    <button>点击</button>

    <script>
        // 获取dom元素button
        let button = document.querySelector('button')

        // 给button绑定点击事件
        button.addEventListener('click', function (ev) {

            // 获取事件类型,并输出
            console.log(ev.type)
        })
    </script>
</body>

效果:image-20220416203821748每点击一次就输出一次click。

事件流

介绍:

事件流指的是事件完整执行过程中的流动路径。

image-20220416210930147

特点:

给多个父子结构的标签绑定事件, 先点击了子元素, 产生事件流动,会让其父元素也触发事件。

事件流三个阶段

主要来说就两个阶段,目标阶段了解下就行。

1、捕获阶段

介绍:

从DOM的根元素开始去执行对应的事件 (从外到里);

事件流向:父节点流动到子节点。

代码体验:
<style>
        div {
            width: 300px;
            height: 300px;
            background-color: skyblue;
        }

        div div {
            width: 200px;
            height: 200px;
            background-color: pink;
        }

        div div div {
            width: 100px;
            height: 100px;
            background-color: aqua;
        }
    </style>
</head>

<body>
    <div class="yeye">爷爷
        <div class="fuqin">父亲
            <div class="sunzi">孙子</div>
        </div>
    </div>

    <script>

        let yeye = document.querySelector('.yeye')
        let fuqin = document.querySelector('.fuqin')
        let sunzi = document.querySelector('.sunzi')

        yeye.addEventListener('click', function () {
            console.log('爷爷')
        }, true)

        fuqin.addEventListener('click', function () {
            console.log('父亲')
        }, true)

        sunzi.addEventListener('click', function () {
            console.log('孙子')
        }, true)


    </script>
</body>

效果:

1、点击孙元素image-20220416214332228

2、点击父元素image-20220416214346408

3、点击爷元素image-20220416213625115

注意:

要想设置事件流向为捕获阶段,需要在注册事件时,加入第三个参数’true‘;默认为false,false代表冒泡阶段。

image-20220416214628732

2、目标阶段

介绍:

点击的最底层的子元素就处于目标阶段,

3、冒泡阶段

介绍:

当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡;

简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件,事件流向:子节点流动到父节点;

默认事件流向。

代码体验:
 <style>
        div {
            width: 300px;
            height: 300px;
            background-color: skyblue;
        }

        div div {
            width: 200px;
            height: 200px;
            background-color: pink;
        }

        div div div {
            width: 100px;
            height: 100px;
            background-color: aqua;
        }
    </style>
</head>

<body>
    <div class="yeye">爷爷
        <div class="fuqin">父亲
            <div class="sunzi">孙子</div>
        </div>
    </div>

    <script>

        let yeye = document.querySelector('.yeye')
        let fuqin = document.querySelector('.fuqin')
        let sunzi = document.querySelector('.sunzi')

        yeye.addEventListener('click', function () {
            console.log('爷爷')
        })

        fuqin.addEventListener('click', function () {
            console.log('父亲')
        })

        sunzi.addEventListener('click', function () {
            console.log('孙子')
        })


    </script>
</body>

效果:

1、点击孙元素image-20220416213558105

2、点击父元素image-20220416213608521

3、点击爷元素image-20220416213625115

阻止事件流动

前言:

因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素;

若想把事件就限制在当前元素内,就需要阻止事件流动。

语法&作用:

事件对象.stopPropagation( );

阻止事件向下一个流动路径走,也就是不触发下一流动路径的事件。

使用方法:

image-20220416215508928

注意: 此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效

事件委托

介绍:

我们知道,根据事件流冒泡的特点,我们点击了子元素,然后程序也会触发父元素的点击事件,那么程序是不是也允许我们通过父元素反向查找到点击的子元素呢,答案是可以。

实现:

事件对象.target---可以获得真正触发事件的元素。

代码演示:

<style>
        div {
            width: 150px;
            height: 50px;
            background-color: aqua;
        }

        span {
            background-color: yellow;
        }
    </style>
</head>

<body>
    <div>父元素<br>
        <span>子元素</span>
    </div>

    <script>

        let div = document.querySelector('div')

        // 只给父元素设置点击事件
        div.addEventListener('click', function (ev) {

            // 输出反向查找的点击元素
            console.log(ev.target);
        })
    </script>
</body>

效果:点击子元素span,控制台输出image-20220416222451254

延申:

事件对象.target.nodeName---输出真正触发事件的元素的标签名 (大写)

代码演示:
<style>
        div {
            width: 150px;
            height: 50px;
            background-color: aqua;
        }

        span {
            background-color: yellow;
        }
    </style>
</head>

<body>
    <div>父元素<br>
        <span>子元素</span>
    </div>

    <script>

        let div = document.querySelector('div')

        // 只给父元素设置点击事件
        div.addEventListener('click', function (ev) {

            // 输出反向查找的点击元素
            console.log(ev.target);
            
            //获取点击元素的标签名
            console.log(ev.target.nodeName);
        })
    </script>
</body>

效果:点击子元素span,控制台输出image-20220416222842009

作用:

我们可以根据此代码,筛选需要的触发元素。

代码演示:

<style>
        div {
            width: 150px;
            height: 50px;
            background-color: aqua;
        }

        span {
            background-color: yellow;
        }
    </style>
</head>

<body>
    <div>父元素<br>
        <span>子元素</span>
    </div>

    <script>

        let div = document.querySelector('div')

        // 只给父元素设置点击事件
        div.addEventListener('click', function (ev) {

            //筛选点击元素
            if (ev.target.nodeName === 'SPAN') {
                console.log('满足')
            }
        })
    </script>
</body>

效果:只有点击了span标签,才会在控制台输出’满足‘。

拓展

阻止事件默认行为

介绍:

有些标签设置了某种事件,然后随着事件的触发,会有默认的功能;好比如:a标签设置了点击事件就会跳转;button标签设置了点击事件就会刷新网页。显然,有时候这些默认的功能我们是不需要的,那么我们就可以把它们给取消掉。

语法&作用:

事件对象.preventDefault( );

取消事件的默认效果。

代码演示:
<body>
    <a href="http://www.baidu.com">百度</a>

    <script>

        let a = document.querySelector('a')

        a.addEventListener('click', function (ev) {
            ev.preventDefault();
        })
    </script>
</body>

效果:页面上点击a标签,页面不跳转。

总结

我的思维导图jsAPI-day4