事件 传播

简介: 事件 传播

浏览器内的事件流机制

什么是事件的执行机制呢?

  • 思考一个问题?
  • 当一个大盒子嵌套一个小盒子的时候,并且两个盒子都有点击事件
  • 要不要执行
  • 当元素触发一个事件的时候,其父元素也会触发相同的事件,父元素的父元素也会触发相同的事件

事件流的三个阶段:

捕获 / 目标 / 冒泡

  1. 事件捕获 : 从上到下、从祖先到子孙依次传递事件的过程
  2. 事件目标(事件源) : 触发事件的对象,你是点击在哪个元素身上了,那么这个事件的 目标 就是什么
  3. 事件冒泡 : 从下到上、从子孙到祖先依次传递事件的过程
  4. 浏览器默认启动了事件冒泡!!!
  5. IE和欧朋浏览器不支持事件捕获

阻止事件传播

标准浏览器: event.stopPropagation() IE浏览器: event.cancelBubble = true; 兼容:

//阻止事件冒泡的兼容
function stopPropagation(evt){
    var e = evt || window.event;
    e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
}
————————————————
版权声明:本文为CSDN博主「秃头请走开」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cc2231293148/article/details/133342124

默认行为

  • 默认行为,就是不用我们注册,它自己就存在的事情
  • 比如我们点击鼠标右键的时候,会自动弹出一个菜单
  • 比如我们点击 a 标签的时候,我们不需要注册点击事件,他自己就会跳转页面
  • 这些不需要我们注册就能实现的事情,我们叫做 默认事件

右键菜单事件 :oncontextmenu

阻止浏览器默认行为

标准浏览器: event.preventDefault() IE浏览器: event.returnValue = false 兼容:

//阻止浏览器默认行为的兼容
function preventDefault(evt){
    var e = evt || window.event;
    e.preventDefault ? e.preventDefault() : e.returnValue = false;
    // ruturn  false ; 既阻止默认行为,也阻止事件冒泡 (方法二)
}

return false : 既阻止默认行为,也阻止事件冒泡!

事件委托

  • 就是把我要做的事情委托给别人来做
  • 因为我们的冒泡机制,点击子元素的时候,也会同步触发父元素的相同事件
  • 所以我们就可以把子元素的事件委托给父元素来做

将加到子元素上的事件,添加到父元素上,为了提高性能。原理是利用了事件冒泡。

  1. 实现事件委托

事件添加到父元素 通过事件对象获取事件源 进行过滤

  1. 事件源

target 目标

  • target 这个属性是事件对象里面的属性,表示你点击的目标
  • 当你触发点击事件的时候,你点击在哪个元素上,target 就是哪个元素
  • 这个 target 也不兼容,在 IE 下要使用 srcElement

标准浏览器: event.target IE浏览器: event.srcElement

// 获取事件源的兼容
function getTarget(evt){
    var e = evt || window.event;
    return e.target || e.srcElement;
}

封装事件库

  1. 移动端tap事件
// 封装事件
// dom : 事件源,触发事件的对象
// tapCallback : 轻击后的回调函数,轻击后想要执行什么?
// clickCallback : 点击后的回调函数,点击后想要执行什么?
var bindTapEvent = function(dom, tapCallback, clickCallback) {
    // 声明变量-开始时间
    var startTime = 0;
    // 声明变量-记录是否移动-默认为false,没有移动
    var isMove = false;
    //监听触摸开始事件
    dom.addEventListener('touchstart', function(e) {
        //记录触摸后的时间
        startTime = Date.now()
    });
    //监听触摸移动事件
    dom.addEventListener('touchmove', function(e) {
        //移动后,记录为true
        isMove = true
    });
    //监听触摸结束事件
    dom.addEventListener('touchend', function(e) {
        //检测触摸时间 与 是否移动
        if ((Date.now() - startTime) < 150 && isMove) {
            // 假设点击的时间间隔小于150ms为轻击事件
            tapCallback && tapCallback.call(this, e)
        } else {
            // 假设点击的时间间隔大于150ms为点击事件
            clickCallback && clickCallback.call(this, e)
        }
        //开始时间恢复为0
        startTime = 0;
        //记录移动为false
        isMove = false;
    });
}
  1. 移动端左滑右滑事件
匿名函数:
1.给函数一个变量  var 变量名 = function(){}
2.给函数前增加 运算符 + - !  进行自调用 !function(){ } ();
3.给函数一个伪装, 让函数包含在括号里面
/*
Touch事件:
touches:当前位于屏幕上的所有手指的一个列表
targetTouches:位于当前DOM元素上的手指的一个列表;
changedTouches:涉及当前事件的手指的一个列表;
screenX,screenY:触摸点相对于屏幕上边缘的坐标;
clientX,clientY:触摸点相对于浏览器的viewport左边缘的坐标,不包括左边的滚动距离;
pageX,pageY:触摸点相对于document的左边缘的坐标,与clientX不同的是它包括左边滚动的距离,如果有的话;
target:总是表示手指最开始放在触摸设备上的触发点所在位置的element。
*/
/**
 * 用touch事件模拟点击、左滑、右滑、上拉、下拉等事件,
 * 是利用touchstart和touchend两个事件发生的位置来确定是什么操作。
 * 例如:
 * 1、touchstart和touchend两个事件的位置基本一致,也就是没发生位移,那么可以确定用户是想点击按钮等。
 * 2、touchend在touchstart正左侧,说明用户是向左滑动的。
 * 利用上面的原理,可以模拟移动端的各类事件。
 **/
var EventUtil = (function() {
    //支持事件列表(左滑、右滑)
    var eventArr = ['eventswipeleft', 'eventswiperight'
    ];
    //touchstart事件,delta记录开始触摸位置
    function touchStart(event) {
        //声明空对象,用来记录触摸开始时的位置和时间信息
        this.delta = {};
        //添加x坐标值
        this.delta.x = event.touches[0].pageX;
        //添加y坐标值
        this.delta.y = event.touches[0].pageY;
    }
    /**
     * touchend事件,计算两个事件之间的位移量
     * 1、如果位移量很小或没有位移,看做点击事件
     * 2、如果位移量较大,x大于y,可以看做平移,x>0,向右滑,反之向左滑。
     * 这样就模拟的移动端几个常见的时间。
     * */
    function touchEnd(event) {
        //记录开始时的位置时间信息
        var delta = this.delta;
        //删除开始时记录的信息
        delete this.delta;
        //计算坐标差值
        delta.x -= event.changedTouches[0].pageX;
        delta.y -= event.changedTouches[0].pageY;
        // 左右滑动
        if (Math.abs(delta.x) > Math.abs(delta.y)) {
            //左滑
            if (delta.x > 0) {
                this['eventswipeleft'].map(function(fn) {
                    fn(event);
                });
            } else { //右滑
                this['eventswiperight'].map(function(fn) {
                    fn(event);
                });
            }
        }
    }
    //绑定事件
    function bindEvent(dom, type, callback) {
        if (!dom) { //如果没有节点对象,则抛出错误
            console.error('dom is null or undefined');
        }
        //遍历数组,检测节点对象是否绑定过事件
        var flag = eventArr.some(function(key){
            return dom[key]
        });
        //未绑定过事件
        if (!flag) {
            //进行绑定事件
            dom.addEventListener('touchstart', touchStart);
            dom.addEventListener('touchend', touchEnd);
        }
        //如果节点事件为空
        if (!dom['event' + type]) {
            //添加空数组
            dom['event' + type] = [];
        }
        //将回调函数添加到节点事件的数组中
        dom['event' + type].push(callback);
    }
    return {
        bindEvent
    }
})();
相关文章
|
2月前
(18):事件
(18):事件
在事件冒泡中阻止特定事件的传播
在事件冒泡中阻止特定事件的传播
|
3月前
在事件冒泡中,如何区分需要阻止传播的事件和不需要阻止的事件
在事件冒泡中,如何区分需要阻止传播的事件和不需要阻止的事件
|
8月前
|
JavaScript
程序化的事件侦听器
程序化的事件侦听器
29 0
|
10月前
爱格停刊事件舆情传播分析
爱格停刊事件舆情传播分析
|
11月前
|
数据可视化 架构师
什么是事件风暴?
什么是事件风暴?
|
12月前
|
JavaScript API
StencilJs 学习之事件
其实并没有所谓的 stencil Event,相反 stencil 鼓励使用 DOM event。然而,Stencil 提供了一个 API 来指定组件可以触发的事件,以及组件监听的事件。 这是通过 Event()和 Listen()装饰器实现的。
66 0
|
Java Spring
【传播行为】
【传播行为】
【传播行为】
|
JavaScript 前端开发
简单解析事件捕捉
简单解析事件捕捉 上篇博客说到了事件冒泡,其实在JavaScript中,说到事件冒泡还有两个个不得不提的事件捕获和默认事件,我们先来说一下事件捕获。效果如下图: 在这里插入图片描述 HTML代码: &lt;div class=&quot;box1&quot;&gt; &lt;div class=&quot;box2&quot;&gt; &lt;div class=&quot;box3&quot;&gt; &lt;div class=&quot;box4&quot;&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; 1 2 3 4 5
简单解析事件捕捉
|
C#
C# 事件
C# 事件
101 0
C# 事件