从零开始学前端:程序猿小白也可以完全掌握!—今天你学习了吗?(JS)
复习:从零开始学前端:键盘事件、小球运动 — 今天你学习了吗?(JS:Day21)
文章目录
前言
第二十二~二十三节课:事件对象,事件冒泡,事件捕获
一、事件对象
1、事件对象
type:当前这个对象的Type类型记录的是这个事件的名称(click);
on:是绑定事件的写法,要加上on.
document.onclick = function( e ){
console.log( e )
}
为什么不报错:
因为形参已经被声明了,与显示地声明一个变量是完全相同的。
IE8以下的兼容写法:
window.event
document.onclick = function( e ){ //形参
console.log( e );
console.log( window.event ); //IE8传参;
e = e || window.event; //兼容的写法;
}
// 逻辑或,e取值为true的时候停止,停止的时候把时间对象e赋值给e,
//在IE里面e转换为布尔值的时候为false,false的时候往后去取值,这时候取到后面的值为event。
document.onclick = function(){
alert( 1 )
}
document.onclick = fn;
function fn( a , b , c ){
console.log( a )
console.log( b )
console.log( c )
}
fn( 1 , 2 , 3 )
//点击时,用一个有时函数作为事件函数的时候,第一个参数还是事件对象,其他的内容还是undedfined;
2、冒泡事件
事件从子元素往父级元素向上触发,这个过程叫做事件冒泡。
- 所有的事件都有泡泡(鼠标事件),文档脱离文档流也照样有冒泡事件;
- 阻止事件对象【阻止泡泡,而不是不让代码执行】;
e.stopImmediatePropagation()
;//消灭泡泡,阻止了事件的冒泡。此方法不兼容IE8及其以下。
e.cancelBubble = true
;//兼容低版本IE。
var box = document.getElementById('box');
box.onclick = function( e ){
e = e || window.event;
e.stopPropagation();
e.stopImmediatePropagation();
console.log('box is click');
}
document.onclick = function(){
console.log('document is click');
}
3、事件监听
*{
margin: 0;
padding: 0;
}
#box{
width:100px;
height:100px;
background-color: #f90;
}
<div id="box"></div>
var box = document.getElementById('box');
//DOM零级事件:都兼容、缺点:一个对象只绑定一个事件,不能绑定多个事件。
box.onclick = function(){
console.log( '1' );
};
box.onclick = function(){
console.log( '2' );
};
//DOM 二级(直接跨过一级,没有一级)同一个事件处理多个问题
//对象添加事件监听:行为为点击,如果有的话,执行函数。
//可以多次进行点击;
box.addEventListener('click',function(e){
e.stopPropagation();//处理冒泡事件
console.log('box1');
});
box.addEventListener('click',function(e){
e.stopPropafation();//处理冒泡事件
console.log( 'box2' );
});
document.addEventListener('click',function(){
console.log('dom');
})
4、事件捕获(true)
一、有多个参数:
addEventListener( type ,function(){ },boolean)
;
从子级到父级叫事件冒泡,
从父级到子级叫事件捕获。(不会冒泡,当布尔值为true的时候,为事件捕获)
如果为false的话,不进行事件捕获,
如果为true的话,进行事件冒泡。
区别:事件的出发顺序不同
IE刚开始实现的是冒泡,捕获是谷歌开发的,先出现冒泡才出现捕获。
如果一开始不传值的话,就是false,就是事件冒泡。
如果一开始传值为true,就是事件捕获。
事件不能带on
box.addEventListener('click',function(){
console.log('eventListener')
},true);
document.addEventListener('click',function(){
console.log('eventListener')
},true);
(1)捕获与冒泡的执行
先出现捕获才出现冒泡
box.addEventListener('click',function(){
console.log('event1')
},true);
wrap.addEventListener('click',function(){
console.log('event2')
});
document.addEventListener('click',function(){
console.log('dom')
});
(2)低版本IE处理
//2.低版本IE处理(只有两个参数),所以支持冒泡(false),不支持捕获(true)
box.attachEvevt('onclick',function(e){
e = window.event;
console.log( e );
})
//attachEvent事件参数要加on
box.attachEvent('onclick',function{
console.log( 'event1' )
});
box.attachEvent( 'onclick' ,function{
console.log( 'event2' )
});
//优点:可以作时间代理;
5、低版本IE处理
//2.低版本IE处理(只有两个参数,所以支持冒泡(false),不支持(true))
box.attachEvent( 'onclick',function(e){
e = window.event;
console.log( e );
} )
//attachEvent事件参数要加on
box.attachEvent( 'onclick',function(){
console.log( 'event1' )
})
box.attachEvent( 'onclick',function(){
console.log( 'event2' )
})
6、事件代理
/*
target: 触发事件的源头
事件源(target):在哪个元素点击的对象就是事件源。
事件代理(target):用来区别对象
*/
document.addEventListener( 'click' ,function(e){
console.log( e.target );
})
/*判断事件源*/
document.addEventListener( 'click' ,function(e){
console.log( e );
console.log( e.target.tagName );
if( e.target.tagName === 'DIV' ){
console.log('事件源是div')
}else{
console.log( '事件源不是div' )
}
})
/*
如何取消事件监听?
Dom零级直接document.onclick = null;
要取消事件监听,事件对象必须要是一个有名函数,让一个有名函数成为它的函数,才可以取消。如果使用了匿名函数,无法删除,因为只是应用了函数名。
*/
function fn(e){
if( e.target.tagName === 'DIV' ){
console.log( '事件源是div' );
}else{
console.log('事件源不是div');
}
}
document.addEventListener('click',fn);
document.removeEventListener('click',fn);
box.onclick = function(e){
var that = e.target;//返回触发事件的元素
console.log(that)
if(that.tagName == "LI"){
that.className="on"
}
}
/*
为什么不能绑定匿名函数?
因为一个事件可以绑定多个事件,如果多个事件都是同一个类型的,都是click事件的。那么不可
能取消,因为都是无名函数,都是object类型,都是引用型对象,内存地址都是一样的,无法区别出来。两
个无名函数长得一样,但是都是独立存在的,内存地址是不可能是一致的,所以不可能去解除方法。
使用有名函数,是为了便于去解除对应的函数。
*/
document.addEventListener('click',function(e){
console.log( e );
console.log( e.target.tagName );
if( e.target.tagName === 'DIV' ){
console.log( '事件源是div' );
}else{
console.log( '事件源不是div' );
}
})
//函数为引用型数据类 型,在删除对象的时候,一定要把事件函数提出来,用有名函数作为事件函数,便于
好把这个事件删除。删除的时候只是引用它的函数名,无论写多少遍,都是指向同一个对象。内存地址一致,
就可以实现删除的效果。
//第二个参数必须写上。
document.removeEventListener( 'click' , function(){} );
document.removeEventListener( 'click' , function(){} );
7、低版本IE兼容问题
/*
ele.removeEventListener( type , fn )
e.target 返回事件源 不兼容低版本IE
e.srcElement
*/
function fn( e ){
e = e || window.event;
//srcElement 低版本IE兼容写法
if( e.srcElement.tagName ==='DIV' ){
console.log( '事件源是div' );
}else{
console.log( '事件源不是div' );
}
}
document.addEventListener( 'onclick' , fn );
document.datachEvent( 'onclick' , fn );
预习:从零开始学前端:正则表达式— 今天你学习了吗?(JS:Day24)