从零开始学 Web 之 DOM(七)事件冒泡

大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新......
+------------------------------------------------------------
github:https://github.com/Daotin/Web
微信公众号:Web前端之巅
博客园:http://www.cnblogs.com/lvonve/
CSDN:https://blog.csdn.net/lvonve/
+-----------------------------------------------------------
在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目。现在就让我们一起进入 Web 前端学习的冒险之旅吧!

一、事件冒泡

1、什么是事件冒泡?

事件冒泡:当有多个元素嵌套,并且这些元素绑定了相同的事件,这时候如果里面的元素事件触发了,那么外面的事件会自动触发。

示例:

<body>
    <div id="dv1">
        <div id="dv2">
            <div id="dv3"></div>
        </div>
    </div>

    <script src="common.js"></script>
    <script>
        my$("dv1").onclick = function() {
            console.log(this.id);
        }
        my$("dv2").onclick = function() {
            console.log(this.id);
        }
        my$("dv3").onclick = function() {
            console.log(this.id);
        }
    </script>
</body>

2、阻止事件冒泡

2.1、方式一

window.event.cancelBubble = true;

注意: Chrome,IE8 支持,firefox 不支持

2.2、方式二

在事件处理函数中传一个参数 e,然后调用 e.stopPropagation();

注意:Chrome,firefox 支持, IE8 不支持。

window.event 和 e 都是事件处理参数对象,一个是 IE 标准,一个是 firefox 标准。

<body>
    <div id="dv1">
        <div id="dv2">
            <div id="dv3"></div>
        </div>
    </div>

    <script src="common.js"></script>
    <script>
        my$("dv1").onclick = function() {
            console.log(this.id);
        }
        my$("dv2").onclick = function() {
            console.log(this.id);
            window.event.cancelBubble = true;
        }
        my$("dv3").onclick = function(e) {
            console.log(this.id);
            e.stopPropagation();
        }
    </script>
</body>

这时候可以写兼容代码的,由于用到 window ,但是没学到 BOM,所以先不写。

3、事件的三个阶段

  1. 事件捕获阶段(从外向内) ===> 阶段 1
  2. 事件目标阶段(最开始触发事件的目标)===> 阶段 2
  3. 事件冒泡阶段(从里向外) ===> 阶段 3
  • 通过事件处理参数对象 e.eventPhase 属性可以查看当前事件所处的阶段。

若为1:捕获阶段

若为2:目标阶段

若为3:冒泡阶段

  • addEventListener 绑定事件处理方法中第三个参数:控制事件的阶段

true: 控制事件为捕获阶段

false: 控制事件为冒泡阶段

  • 一般默认使用冒泡阶段,很少使用捕获阶段。
<body>
    <div id="dv1">
        <div id="dv2">
            <div id="dv3"></div>
        </div>
    </div>

    <script src="common.js"></script>
    <script>
        my$("dv1").addEventListener("click", function(e) {
            console.log(this.id +" --- "+ e.eventPhase);
        }, false);
        my$("dv2").addEventListener("click", function(e) {
            console.log(this.id +" --- "+ e.eventPhase);
        }, false);
        my$("dv3").addEventListener("click", function(e) {
            console.log(this.id +" --- "+ e.eventPhase);
        }, false);

// -------------------------------------------------------
// addEventListener 的第三个参数为 false
// 点击最里面的 dv3
//dv3 --- 2 : 因为是冒泡阶段,从里向外,从 dv3开始,dv3是目标,所以为2
//dv2 --- 3:冒泡阶段,所以为3
//dv1 --- 3:冒泡阶段,所以为3

// 如果将 false 都改为 true 的话:
// 点击最里面的 dv3
//dv1 --- 1:捕获阶段,从外向里,从dv1开始捕获,所以dv1为1
//dv2 --- 1:捕获阶段,从外向里
//dv3 --- 2:捕获阶段,从外向里,到达dv3目标,随意dv3为目标阶段。

    </script>
</body>

二、小案例

目的:为同一个元素绑定多个不同的事件指向相同的事件处理函数。

<body>
    <input type="button" value="按钮" id="btn" >

    <script src="common.js"></script>
    <script>
        my$("btn").onclick = func;
        my$("btn").onmouseover = func;
        my$("btn").onmouseout = func;

        function func(e) {
            switch(e.type) {
                case "click" :
                    console.log("onclick");
                    break;
                case "mouseover" :
                    console.log("onmouseover");
                    break;
                case "mouseout" :
                    console.log("onmouseout");
                    break;
                default:
                    break;
            }
        }
    </script>
</body>

使用事件处理参数对象的 type 属性可以判断事件触发时候,事件的类型,从而做出相应的事件处理。

三、百度搜索小项目

目标:在搜索框输入关键字,自动在搜索框下方显示相关内容。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #dv1 {
            width: 500px;
            margin-top: 100px;
            margin-left: 200px;
            font: 400 18px/30px "Microsoft Yahei";
            color: #595959;
        }

        input {
            width: 500px;
            height: 30px;
        }

        .dvv {
            width: 500px;
            /*height: 10px;*/
            border: 1px solid green;
        }

        .ps {
            padding: 2px 0 2px 5px;
            cursor: pointer;
        }
    </style>
</head>
<body>
<div id="dv1">
    <input type="text" placeholder="日向雏田" id="txt">
</div>

<script src="common.js"></script>
<script>
    var KeyWords = [
        "旋涡鸣人", "旋涡辛久奈", "旋风小子", "旋风少女",
        "日向雏田", "日向花火", "日向本家",
        "奈良鹿丸", "奈良大佐",
        "旗木卡卡西"
    ];

    my$("txt").onkeyup = function () {
        while(my$("dv2")) {
            my$("dv1").removeChild(my$("dv2"));
        }
        // console.log(this.value);
        var findArr = []; // 每次输入文字的时候都先清除临时数组
        for (var i = 0; i < KeyWords.length; i++) {
            if (KeyWords[i].indexOf(this.value) === 0) {
                // console.log("yes");
                findArr.push(KeyWords[i]);
            }
        }
        // 文本框输入了内容,并且临时数组不为空
        if ((findArr.length !== 0) && (this.value.length !== 0)) {

            var dvObj = document.createElement("div");
            dvObj.className = "dvv";
            dvObj.id = "dv2";
            my$("dv1").appendChild(dvObj);

            for (var i = 0; i < findArr.length; i++) {
                var pObj = document.createElement("p");
                pObj.className = "ps";
                setInnerText(pObj, findArr[i]);
                my$("dv2").appendChild(pObj);

                pObj.onmouseover = f1; // 循环里面不要使用匿名函数
                pObj.onmouseout = f2;

            }
        }
    };

    function f1() {
        this.style.backgroundColor = "greenyellow";
    }
    function f2() {
        this.style.backgroundColor = "";
    }
</script>
</body>
</html>

1、这里的候选数据本来应该来自服务器,这里用数组来模拟。
2、这里使用的是鼠标输入文字后的鼠标抬起事件:onkeyup。
3、 需要准备个临时数组存储于文本框输入文字匹配的字符串。
4、当搜索框的文本为空或者临时数组的内容为空时,循环删除下拉列表。
5、之所以输入多个文字,但是只创建了一个下拉列表的原因是因为在输入第二个文字的时候,先输入的其实是字母,这个时候不匹配,而我们在每次鼠标抬起的时候会清空临时数组,所以这个时候会先删除下拉列表,当我们输入第二个文字的时候,再重新创建相匹配的下拉列表。
6、每次进入鼠标抬起按键时,如果有下拉列表就循环删除。
7、注意在循环里面不要使用匿名函数。

原文地址:https://www.cnblogs.com/lvonve/p/9217677.html

时间: 2024-10-09 20:54:06

从零开始学 Web 之 DOM(七)事件冒泡的相关文章

从零开始学 Web 之 DOM(一)DOM的概念,对标签操作

大家好,这里是「 Daotin的梦呓 」从零开始学 Web 系列教程.此文首发于「 Daotin的梦呓 」公众号,欢迎大家订阅关注.在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目.现在就让我们一起进入 Web 前端学习的冒险之旅吧! 一.DOM概念 DOM 的全称为:Document Object Model 文档对象模型 我们把 html 文件看成一个文档,因为万物皆对象,所以这个文档也是一个对象.这个文档中所有的标签都可以看成一个对象,比如

从零开始学 Web 之 DOM(二)对样式的操作,获取元素的方式

大家好,这里是「 Daotin的梦呓 」从零开始学 Web 系列教程.此文首发于「 Daotin的梦呓 」公众号,欢迎大家订阅关注.在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目.现在就让我们一起进入 Web 前端学习的冒险之旅吧! 1.对样式的操作 1.1.点击按钮设置 div 的宽高和背景颜色 <body> <input type="button" value="显示颜色" id="

从零开始学 Web 之 DOM(四)节点

大家好,这里是「 Daotin的梦呓 」从零开始学 Web 系列教程.此文首发于「 Daotin的梦呓 」公众号,欢迎大家订阅关注.在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目.现在就让我们一起进入 Web 前端学习的冒险之旅吧! 一.节点 1.节点的概念 页面中的所有内容,包括标签,属性,文本(文字,空格,回车,换行等),也就是说页面的所有内容都可以叫做节点. 2.节点相关的属性 2.1.节点分类 标签节点:比如 div 标签,p 标签等.

从零开始学 Web 之 jQuery(六)为元素绑定多个相同事件,解绑事件

大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:http://www.cnblogs.com/lvonve/ CSDN:https://blog.csdn.net/lvonve/ 在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目.现在就让我们一起进入 Web 前端学习的冒险之旅吧! 一.为元素绑定多个

从零开始学ios开发(七):Delegate,Action Sheet, Alert

Action Sheet和Alert是2种特殊的控件(暂且称之为控件吧,其实不是控件真正的控件,而是ios中的2个类,这2个类定义了2种不同类型的用于和用户交互的弹出框),Action Sheet是从底部弹出,上面有2个或者2个以上的选项供用户选择,Alert就是一个警告框,上面有1个或者1个以上的按钮供用户进行选择. 在继续这一篇的内容之前,稍微花点时间说一下ios中用到的Delegate Pattern(委托\代理模式). ios中有很多已经定义好的类可以供我们在编写程序时直接使用,例如UI

从零开始学 Web 之 BOM(一)BOM的概念,一些BOM对象

大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... +------------------------------------------------------------ github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:http://www.cnblogs.com/lvonve/ CSDN:https://blog.csdn.net/lvonve/ +-----------------------

从零开始学 Web 之 BOM(三)offset,scroll,变速动画函数

大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:http://www.cnblogs.com/lvonve/ CSDN:https://blog.csdn.net/lvonve/ 在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目.现在就让我们一起进入 Web 前端学习的冒险之旅吧! 一.直接使用 do

从零开始学 Web 之 Ajax(五)同步异步请求,数据格式

大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:http://www.cnblogs.com/lvonve/ CSDN:https://blog.csdn.net/lvonve/ 在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目.现在就让我们一起进入 Web 前端学习的冒险之旅吧! 一.同步请求与异步

从零开始学 Web 之 Ajax(六)jQuery中的Ajax

大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:http://www.cnblogs.com/lvonve/ CSDN:https://blog.csdn.net/lvonve/ 在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目.现在就让我们一起进入 Web 前端学习的冒险之旅吧! 一.jQuery中