事件

最新更新时间:2019年2月14日10:45:54
《猛戳-查看我的博客地图-总有你意想不到的惊喜》

本文内容:DOM原生事件、DOM自定义事件、事件处理程序、事件对象、react事件

事件

JavaScript与HTML的交互是通过事件完成的,事件流模型包括:事件冒泡和事件捕获

事件冒泡

IE事件流叫做事件冒泡(event bubbling),即事件由最具体的元素向上传播到顶层对象。

  • IE9、Firefox、Chrome和Safari将事件一直冒泡到window对象
事件捕获

IE事件流叫做事件冒泡(event capturing),即事件由顶层对象向下传播到最具体的元素。

  • IE9、Firefox、Chrome和Safari将事件一直冒泡到window对象
事件处理程序(事件侦听器)

响应某个事件的函数

事件处理程序的形式
HTML事件处理程序
//形式一
<input type='button' value='i am button' onclick="console.log(123)" />
//形式二
<input type='button' value='i am button' onclick="print()" />
function print(){
	console.log(123)
}
DOM0级事件处理程序
<input id='btn' type='button' value='i am button' />
var btn = document.getElementById('btn');
btn.onclick = function(){
	console.log(123)
}
//删除事件处理程序
btn.onclick = null;
DOM2级事件处理程序-w3c规范
<input id='btn' type='button' value='i am button' />
var btn = document.getElementById('btn');
btn.addEventListener('click', handler, false);//arguments[2] true-捕获阶段调用事件处理程序 false-冒泡阶段调用事件处理程序
function handler(){
	console.log(123)
}
btn.addEventListener('click', function(){
	console.log(456)
}, false);
//移除事件
btn.removeEventListener('click', handler, false);//btn第二次添加的匿名函数事件无法移除

DOM2级事件处理程序优点:可以为一个元素添加多个事件处理程序

DOM2级事件处理程序-IE规范
<input id='btn' type='button' value='i am button' />
var btn = document.getElementById('btn');
//注意:事件明多了on
btn.attachEvent('onclick', handler);//没有arguments[2] 由于IE8及更早版本只支持事件冒泡,所以attachEvent添加的时间处理程序都会被添加到冒泡阶段。
function handler(){
	console.log(123)//attachEvent定义事件的情况下 this === window true
}
//移除事件
btn.detachEvent('click', handler, false);//btn第二次添加的匿名函数事件无法移除
跨浏览器的事件处理程序
var EventUtil = {
	addHandler: function(element, type, handler){
		if(element.addEventListener){
			element.addEventListener(type, handler, false)//w3c DOM2
		}else if(element.attachEvent){
			element.attachEvent("on" + type, handler)//IE DOM2
		}else{
			element.['on' + type] = handler//DOM0
		}
	},
	removeHandler: function(element, type, handler){
		if(element.removeEventListener){
			element.removeEventListener(type, handler, false)
		}else if(element.datachEvent){
			element.datachEvent("on" + type, handler)
		}else{
			element.['on' + type] = null
		}
	},
	//跨浏览器的事件对象,DOM中的event和IE中的event
	getEvent: function(event){
		return event ? event : window.event;
	},
	getTarget: function(event){
		return event.target || event.srcElement;
	},
	preventDefault: function(event){
		if(event.preventDefault){
			event.preventDefault();
		}esle{
			event.returnValue = false;
		}
	},
	stopPropagetion: function(event){
		if(event.stopPropagetion){
			event.stopPropagetion();
		}esle{
			event.cancelBubble = true;
		}
	}
}
事件对象:DOM中的event和IE中的event
//w3c event 对象属性全是只读不可写的
var event = {
	bubbles: true | flase,//事件是否冒泡
	cancelable: true | flase,//是否可以取消事件默认行为
	currentTarget: Element,//当前正在处理的元素
	defaultPrevented: true | flase,//true表示已经调用了preventDefault()(DOM3级事件中新增)
	detail: Integer,//与事件相关的细节信息
	eventPhase: Integer,//调用事件处理程序的阶段:1表示捕获阶段,2表示处于目标阶段,3表示冒泡阶段
	preventDefaule(): Function,//取消事件默认行为。如果cancelable为true,则可以使用这个方法
	stopImmediatePropagation(): Function,//取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用(DOM3级事件中新增)
	stopPropagetion(): Function,//取消事件的进一步捕获或冒泡,如果bubbles为true,则可以使用这个方法
	target: Element,//事件的目标
	trusted: true | flase,//true表示事件是浏览器生成的 false表示事件是开发人员通过JavaScript创建的(DOM3级事件中新增)
	type: String,//被触发的事件类型
	view: AbstractView,//与事件关联的抽象视图,等同于发生事件的window对象
}
//IE event 前两个可读可写,后两个只读不可写
var event = {
	cancelable: true | flase,//默认为false,设为false可以取消事件冒泡
	returnValue: true | flase,//默认为true,设为false可以取消事件默认行为
	srcElement: Element,//事件目标
	type: String,//被触发的事件类型
}
取消事件的相关场景
event.preventDefault();//可以阻止a标签链接的默认跳转行为
event.stopPropagetion();//立即停止事件在DOM层级中的传播,即取消进一步的事件捕获或冒泡
//event.eventPhase的三种情况
var btn = document.getElementById('btn');
btn.onclick = function(event){
	console.log(event.eventPhase)//2
}
document.body.addEventListener('click',function(event){
	console.log(event.eventPhase)//1
},true)
document.body.onclick = function(event){
	console.log(event.eventPhase)//3
}
react中的事件
//注册事件的形式:合成事件 原生事件
//原生事件的绑定与销毁
<div ref='parent2' id='parent2' className='parent2' style={{background:'#ff6788',padding: '1rem'}}></div>
componentDidMount(){
	document.getElementById('parent2').addEventListener('click',(e)=>{this.parentCallback2(e)})
}
componentWillUnmount(){
	document.getElementById('parent2').removeEventListener('click',(e)=>{this.parentCallback2(e)})
}
//合成事件
<div className='child1' onClick={(e) => {this.childCallback1(e)}} style={{background:'red'}}>1</div>
childCallback1(e){
	console.log('child1 click');
}
//取消事件的进一步捕获或冒泡,分为两种情况
//在子元素上使用e.stopPropagation()的情况:合成→合成 | 原生→原生 | 原生→合成
childCallback3(e){
	e.stopPropagation();
}
//在父元素上做拦截:合成→原生
parentCallback2(e){
	if(e.target.id == 'child2' || e.className == "parent2"){e.target.className e.target.nodeName
		return
	}
}
react中的合成事件和原生事件

执行先后顺序:先执行原生事件,后执行合成事件

import React, { Component } from 'react';

class Demo extends Component {

	constructor(props) {
		super(props);
		this.state = {
			
		}
	}

	componentWillMount(){
	
	}

	componentDidMount(){
		//原生事件只能在这个生命周期方法中绑定,因为此时才能获取DOM元素
		document.getElementById('parent').addEventListener('click',(e)=>{console.log('原生事件')})
	}

	componentWillUnmount(){
		document.getElementById('parent').removeEventListener('click',(e)=>{console.log('原生事件')})
	}

	render() {
		return (
			<div id='parent' onClick={(e) => {console.log('合成事件')}}>这个元素绑定了原生事件和合成事件</div>
		);
	}
}

export default Demo;
自定义事件
var divDom = document.getElementById('test')
//dom元素添加用户自定义事件,customEvent01为自定义的事件类型
divDom.addEventListener('customEvent01',customFunc)
//dom元素添加click事件
divDom.addEventListener('click',clickFunc)
//触发条件:代码触发
function customFunc(data){
    console.log('触发自定义事件customEvent01成功')
    console.log(data)
    console.log(data.type)//"customEvent01"
}
//触发条件:鼠标单击dom元素
function clickFunc(data){
    console.log('触发原生click事件成功')
    console.log(data.type)//"click"
}
setTimeout(function(){
    //创建自定义事件
    var event = new Event("customEvent01");
    //用户可自定义添加属性和方法
    event.state = 'ok'
    event.data = '123';
    //触发自定义事件
    divDom.dispatchEvent(event);
},3000)

感谢阅读,欢迎评论^-^

打赏我吧^-^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值