js事件处理模型——事件冒泡、捕获

事件冒泡:

结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素。(自底向上)

这里写图片描述

<div class="wrapper">
    wrapper
    <div class="content">
        content
        <div class="box">box</div>
    </div>
</div>

<script>
    var wrapper = document.getElementsByTagName('div')[0];
    var content = document.getElementsByTagName('div')[1];
    var box = document.getElementsByTagName('div')[2];

    wrapper.addEventListener('click', function () {
        console.log('wrapper');
    }, false);
    //wrapper

    content.addEventListener('click', function () {
        console.log('content');
    }, false);
    //content
    //wrapper

    box.addEventListener('click', function () {
        console.log('box');
    }, false);
    //box
    //center
    //wrapper

</script>

事件捕获:

addEventListener第三参数为true时,发生事件捕获
只有Google Chrome上可以实现事件捕获;
新版本的火狐也有时间捕获

结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自向上)

注:一对象的一个事件类型只能遵循一种事件模型,不能同时存在

wrapper.addEventListener(click', test, false);
//把这里的false变成true;他的事件处理模型就会变成捕获;

<script>
    var wrapper = document.getElementsByTagName('div')[0];
    var content = document.getElementsByTagName('div')[1];
    var box = document.getElementsByTagName('div')[2];

    wrapper.addEventListener('click', function () {
        console.log('wrapper');
    }, true);
    //wrapper事件执行
    content.addEventListener('click', function () {
        console.log('content');
    }, true);
    //wrapper事件捕获
    //content事件执行

    box.addEventListener('click', function () {
        console.log('box');
    }, true);
    //wrapper事件捕获
    //content事件捕获
    //box事件执行


</script>


同一个对象上面同一个事件处理类型,绑定了两个事件处理函数,一个符合事件冒泡,一个符合事件捕获,他么的触发顺序是先捕获,后冒泡

    var wrapper = document.getElementsByTagName('div')[0];
    var content = document.getElementsByTagName('div')[1];
    var box = document.getElementsByTagName('div')[2];

    wrapper.addEventListener('click', function () {
        console.log('wrapperBubble');
    }, false);
    content.addEventListener('click', function () {
        console.log('contentBubble');
    }, false);
    box.addEventListener('click', function () {
        console.log('boxBubble');
    }, false);


    wrapper.addEventListener('click', function () {
        console.log('wrapper');
    }, true);
    content.addEventListener('click', function () {
        console.log('content');
    }, true);
    box.addEventListener('click', function () {
        console.log('box');
    }, true);
点击wrapper区域点击content区域点击box区域
wrapperBubble事件执行wrapper事件捕获wrapper 事件捕获
wrapper 事件执行contentBubble事件执行content 事件捕获
content事件执行boxBubble 事件执行
wrapperBubble事件冒泡box 事件执行
contentBubble 事件冒泡
wrapperBubble 事件冒泡

注 : focus,blur,change,submit,reset,select 等事件不冒泡

其他形式的捕获

非事件处理模型,而是真实的事件获取的过程;用于解决拖拽鼠标容易超出div范围
仅在IE中能用

div.setCapture();执行这个方法,div会获取,会捕获页面中发生的所有事件,捕获到自己身上来,即使是在div外部的事件,也算是在div上面触发的。

用完这个之后;要用div.releaseCapture();来释放;

取消冒泡

W3C标准 event.stopPropagation();但不支持ie9以下版本

    document.onclick =function () {
        console.log('你闲的呀!')
    }
    var div = document.getElementsByTagName('div')[0];
    div.onclick = function (e) {
        e.stopPropagation();
        this.style.background = 'green';
    } //div变绿,但是不执行docunment上面的事件了,说明冒泡被取消了;

IE上的方法 event.cancelBubble = true;

    document.onclick =function () {
        console.log('你闲的呀!')
    }
    var div = document.getElementsByTagName('div')[0];
    div.onclick = function (e) {
        e.cancelBubble = true;
        this.style.background = 'green';
    }  //div变绿,但是不执行docunment上面的事件了,说明冒泡被取消了;

封装取消冒泡的函数 stopBubble(event)

function stopBubble(event) {
    if(event.stopPropagation) {
        event.stopPropagation();
    }else{
        event.cancelBubble = true;
    }
}

阻止默认事件:

默认事件 — 表单提交,a标签跳转,右键菜单等
1.return false; 以对象属性的方式注册的事件才生效

document.oncontextmenu = function () {
    console.log('a');
    return false; //取消右键出菜单事件;
                  //如果return false写在上面,console.log('a')就不会执行
}

只有以句柄的方式绑定的事件才能用retur false 取消默认事件

2.event.preventDefault(); W3C标注,IE9以下不兼容

document.oncontextmenu = function (e) {
    console.log('a');
    e.[reventDefault();
}

3.event.returnValue = false; 兼容IE

document.oncontextmenu = function (e) {
    console.log('a');
    e.returnValue = false;
}

<a>标签取消默认事件

1.  a.onclick = function () { return false }
2.  <a href="javascript:void(false)">demo</a>
3.  <a href="javascript:alert('a')">demo</a> //可以在行间设置js语法

封装阻止默认事件的函数 cancelHandler(event);

function cancelHander(event) {
    if(e.preventDefault) {
        e.preventDefault();
    }else{
        e.returnValue = false;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值