参考链接: DOM事件简介: DOM事件模型:
一、概念
客户端浏览器的交互模式的实现实际上是基于JavaScript的异步事件驱动模型编程的著作权归作者所有。
1.事件的原理
- Javascript与HTML之间的交互式通过事件实现的。
- 事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。
- 事件流描述的是从页面接收事件的顺序。
2.DOM0级模型(基本事件模型Basic Event Model)
事件在未达到标准之前,各浏览器有一个事件模型——基本事件模型
在基本事件模型中,要在某个事件发生时,调用指定的函数,即事件处理程序。这个程序会指定事件触发将会做什么样的事情。比如:当Web页面加载完所有资源后,即windwo的load事件
window.onload = function(){
//window的load事件发生时要做的事情···
}
除此之外,事件还可以由使用者操作一些事情来触发事件。比如按钮上绑定一个click事件:
let handler = function (){
console.log(this)
}
document.querySelctor('button').onclick = handler
上面代码,用户点击执行handler() 函数,打印出来的this 就是用户点击的按钮
DOM0级事件模型(基本事件模型)有一个典型的缺点,就是只能注册一个事件处理程序,如果注册多个事件处理程序会覆盖。比如:
let handler1 = function () {
console.log('Handler1:',this)
}
let handler2 = function () {
console.log('Handler2',this)
}
document.querySelector('button').onclick = handler1
document.querySelector('button').onclick = handler2
当你点击button按钮时,浏览器控制台只会输出hander2()函数,handle1被覆盖。 如果要移出监听函数,可以通过事件赋值null 来实现
document.querySelector('button').onclick = null
3.DOM Level2模型
DOM Level 2事件模型属于W3C标准,现代浏览器都支持,在该事件模型中,一次事件共有三个过程
-
事件捕获阶段(Capturing Phase):事件从document一直向下传播到目标元素,依次检查经历过的节点是否绑定了事处监听函数(事件处理程序),如果有则执行,反之不执行
-
事件处理阶段(Target Phase):事件到达目标元素,触发目标元素的监听函数
-
事件冒泡阶段(Bubbling Phase):事件从目标元素冒泡到document,依次检查经过的节点是否绑定了事件监听函数,如果有则执行,反之不执行。
简而言之:事件一开始从文档的根节点流向目标对象(捕获阶段),然后在目标对向上被触发(目标阶段),之>后再回溯到文档的根节点(冒泡阶段)。
在DOM2事件模型中,要注册事件,必须使用addEventListener() 方法,而且可以注册多个事件,同时可以移除注册事件 IE事件模型:attachEvent()和detachEvent()
element.addEventListener(,,);
-
element:要监听的事件对象,通常使一个DOM元素,也可以是window、document等
-
event-name(string):你想监听的事件的名称或类型。它可以是任何的标准DOM事件(click,mousedown,touchstart,transitionEnd,等等),当然也可以是你自己定义的事件名称
-
callback(function):这个回调函数会在事件触发的时候被调用。相应的事件对象,以及事件的数据,会被作为第一个参数传入这个函数。这个函数也被称为事件处理程序
-
use-capture(boolean):这个参数决定了回调函数(callback)是否在“捕获(capture)”阶段被触发,
true表示该元素在事件的“捕获阶段”(由外往内传递时)响应事件; false表示该元素在事件的“冒泡阶段”(由内向外传递时)响应时间
- Jquery的e.stopPropagation会阻止冒泡,意思就是到我为止,我的爹和祖宗的事件就不要触发了
let handler1 = function () { console.log('handler1:',this) }
let handler2 = function () { console.log('handler2',this) }
//注册事件
document.querySelector('button').addEventListener('click',handler1,true) document.querySelector('button').addEventListener('click',handler2,true)
这个时候点击按钮时,handler1()和handler2()两个函数都会被触发
//移除事件
btn.querySelector('button').removeEventListener('click',true)
IE的事件流是事件冒泡流 Netscape Communicator的事件流是事件捕获流
4.案例
4.1 事件冒泡
这是HTML结构
现在我们给它们绑定上事件
document.getElementById("parent").addEventListener("click",function(e){
alert("parent事件被触发,"+this.id);
})
document.getElementById("child").addEventListener("click",function(e){
alert("child事件被触发,"+this.id)
})
结果:
点击parent
parent事件被触发,parent
点击child
先弹出:child事件被出发,child
再弹出:parent事件被触发,parent
结论:先child,然后parent。事件的触发顺序自内向外,这就是事件冒泡。
4.2 事件捕获
现在改变第三个参数的值为true
document.getElementById("parent").addEventListener("click",function(e){
alert("parent事件被触发,"+e.target.id);
},true)
document.getElementById("child").addEventListener("click",function(e){
alert("child事件被触发,"+e.target.id)
},true)
结果:
点击parent
parent事件被触发,parent
点击child
先弹出:parent事件被触发,parent
再弹出:child事件被出发,child
结论:先parent,然后child。事件触发顺序变更为自外向内,这就是事件捕获。
4.3 应用:事件委托
利用事件冒泡
需求是这样的:鼠标放到li上对应的li背景变灰。 利用事件冒泡实现:
$("ul").on("mouSEOver","li",function(e){
$(e.target).css("background-color","#ddd").siblings().css("background-color","white");
})
也许有人会说,我们直接给所有li都绑上事件也可以啊,一点也不麻烦,只要……
$("li").on("mouSEOver",function(){
$(this).css("background-color","white");
})
是,这样也行。而且从代码简洁程度上,两者是相若仿佛的。但是,前者少了一个遍历所有li节点的操作,所以在性能上肯定是更优的。
利用事件冒泡处理动态元素事件绑定的方法,专业术语叫事件委托
事件里面的代码是在触发事件的时候发生 因此通过on绑定事件,可以绑定动态创建的元素,因为其绑定的是父元素,与子元素无关,子元素只是触发这个事件
语法格式:$(selector).on( events [,selector ] [,data ],handler )
参数介绍:
第一个参数:events,事件名
第二个参数:selector,类似delegate
第三个参数: 传递给事件响应方法的参数,在事件对象中使用
第四个参数:handler,事件处理方法
例如:
//绑定一个方法
$( "#dataTable tbody tr" ).on( "click",function() {
console.log( $( this ).text() );
});
//给子元素绑定事件
$( "#dataTable tbody" ).on( "click","tr",function() {
console.log( $( this ).text() );
});
//绑定多个事件的方式
$( "div.test" ).on({
click: function() {
$( this ).toggleClass( "active" );
},mouseenter: function() {
$( this ).addClass( "inside" );
},mouseleave: function() {
$( this ).removeClass( "inside" );
}
});
5.自定义事件模型(扩展阅读)
事件模型的实现从设计模式的角度来看,是一种观察者模式或者也叫发布订阅模式, 订阅者订阅一个消息,发布者发布这个消息,订阅者收到消息,这是一种数据流动的方式,使用这个模式的好处是,可以有多个订阅者,一个发布者,发布一条消息,可被多个订阅者收到。
比如下面这样的一个事件模型:
;(function(global){
class Events {
constructor(){
this.cache = {};
this.onceKeys = [];
}
on(key,fn){
if(!this.cache[key]) this.cache[key] = [];
this.cache[key].push(fn);
}
one(key,fn){
this.cache[key]=[];
this.on(key,fn);
this.onceKeys.push(key);
}
off(key,fn){
if(this.cache[key]) this.cache[key] = fn ? this.cache[key].filter(v=>v !== fn) : [];
}
emit(key,...args){
if(this.cache[key]){
this.cache[key].forEach(v=>v.apply(null,args))
if(this.onceKeys.includes(key)){
this.cache[key] = [];
this.onceKeys = this.onceKeys.filter(v=>v!==key);
}
}
}
}
global.Events = new Events();
})(this)
这是一个简单的自定义事件型型:
- on()用于绑定事件,参数:事件名称,事件处理函数
- emit()用于触发事件,参数:事件名称,传递给事件处理函数的参数
- off 用于解除绑定的指定事件, 参数:事件名称,要解绑的事件函数
- one 用于绑定一次性事件,只能触发一次,参数:事件名称,事件处理函数
如果要使用,可以这样:
Events.on('cus',(a,b) => console.log(a+b))
Events.emit('cus',1,2); // => 3
Events.off('cus');
Events.emit('cus',2)
// 只触发一次
Events.one('once',a => console.log(a))
Events.emit('once',1); // => 1
Events.emit('once',2);
常用
1. 获取html的内容(重点)
$(selector).text() - 设置或返回所选元素的文本内容
特点:获取所有的拼接起来
js中innerText / textContent
$(selector).html() - 设置或返回所选元素的内容(包括 HTML 标记)
html() 获取html()获取的是第一个匹配的(里边的的子元素标签) html("小红"); // 设置html内容
html(""); // 清空元素 empty(); innerHTML
html('')
$(selector).val() - 设置或返回表单字段的值,获取第一个
2.index方法
特点:获取元素中对应的索引
3.表单相关
3.1 select
获取值 $("").val();
3.2 checkbox
获取值 $("").is(":checked"); true或者false
移除选中状态 $("").removeAttr("checked");
3.简单事件绑定
mouseenter mouseleave不会冒泡,一般用着两个
4.绑定事件
事件绑定是在页面加载的时候发生,而里面的代码是在触发事件的时候发生。 on事件绑定是通过事件冒泡实现的,因此通过on绑定事件,可以绑定动态创建的元素,因为其绑定的是父元素,与子元素无关,子元素只是触发这个事件。
4.1 js事件绑定
4.1.1 btn.onclick = function (){} 4.1.2 btn.addEventListener(“click”,function(){})
4.2 jQuery事件绑定
bind delegate on (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|