文章目录
1.元素的事件绑定
HTML DOM可以让JavaScript对HTML事件做出反应。
- dom 元素的常用事件有哪些:
(下图为菜鸟教程官网内容,仅供个人整理和学习)
了解了常用事件之后,就可以去进行元素的事件的绑定了!
注意:
- 在js中,事件使用的时候要加"on“,也就是上面图中的书写格式。
- 在事件监听中,事件类型时不带”on“
方法一:在DOM元素的行内直接绑定事件
怎么实现呢❓上代码!
<button class="btn" onclick="change()">点击</button>
<!--后面两个方法同样引用此代码-->
js代码部分:
function change(){
console.log("改变");
}
当点击button的时候,即触发onclick事件,此时函数会被执行,触发几次事件,函数就会被执行几次。
当然,元素通过行内进行事件绑定时,同类型事件只能绑定一次。
- 多次绑定同一事件会出现什么错误呢❓ 当然是会报错,不允许绑定两个函数。
强行去测试,也不会出现结果的。
方法二:直接动态绑定事件
在函数中获取元素之后,再绑定事件。
var btn=document.getElementsByTagName("button")[0];
btn.onclick=function(){
console.log("1");
}
btn.onclick=function(){
console.log("2");
}
此方法元素可以多次绑定同类事件,结果由最后绑定的输出内容覆盖。
如何移除绑定的事件呢❓
btn.onclick=null;
如果将此语句写在绑定函数之后,事件的函数不会被执行,很简单,你设置了它,又删除了它,自然是没有反应的;
那如果想让它实现一次,就把移除事件写在绑定函数里面,这样就可以执行一次,之后不再有反应。
方法三:事件的监听(事件类型不带on)
1)向原元素添加一次事件句柄
- 使用回调函数:(移除时没有函数名,因此如果后期需要移除监听事件,不用此方法)
btn.addEventListener("click",function(){
console.log(1);
});
- 使用常用方法:
btn.addEventListener("click",m1);
function m1(){
console.log(1);
}
2)向同一个元素中添加多个事件句柄
btn.addEventListener("click",m1);
function m1(){
console.log(1);
}
btn.addEventListener("click",m2);
function m2(){
console.log(2);
}
结果如下:
证明:同一元素的同一事件可多次监听,且不会覆盖上一次的结果,即多次监听的返回值都会显示。
3)移除监听
btn.removeEventListener("click",m1);
注意:有几次监听,就要移除几次。如果移除一部分的监听,结果返回的是未移除监听的事件的调试值。
4)移除语句的位置
可写在监听语句之外,也可写在监听语句之内。效果和 (方法二:直接动态绑定事件 )同理。
谈谈回调函数是什么❓
- 在事件的监听中
btn.addEventListener("click",function(){});
函数作为方法的参数出现,称为回调函数。- (在此之前举个小栗子,说说同步异步的含义):
同步:早晨起来先穿衣服,再穿鞋,紧接着刷牙、洗脸…一切有序进行,做完一件事紧接着另一件事。
异步:刷牙的时候、厨房里同时烧着水,两件事情同时发生。
- 我们都知道js是单线程的,引擎一步步的去完成和执行相关的操作,这样的设计模式有很多便利。不过当在某一阶段出现死循环或者时间复杂度很大的操作时,代码就会停滞不前,后面的任务出现等待状态,浏览器甚至出现假死现象。所以js在同步机制的缺陷下设计出了异步模式。
- 异步模式是怎样实现的❓
在这种状态下,每个异步的任务都有自己一个或多个回调函数。当前在执行的异步任务执行完之后,不会跳转到下一个任务,而是执行它的回调函数;在此同时,下一个任务也不会就地等待,开始执行。
异步模式代码举例:
var a=function() {
setTimeout(function () {
console.log(1);
},500);
}
var b=function() {
console.log(2);
}
a();
b();
结果:
很明显:第二个任务没有等待第一份任务执行回调函数,便开始执行自己的任务。因为执行快,提前输出结果。
冒泡还是捕获
为什么要说这个问题呢,因为事件监听的语法是这样的:
element.addEventListener(event, function, useCapture);
第一个参数是事件的类型 (如 “click” 或 “mousedown”).
第二个参数是事件触发后调用的函数。
第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的。
addEventListener() 方法允许你在 HTML DOM 对象添加事件监听, HTML DOM 对象如: HTML 元素, HTML 文档, window 对象。或者其他支出的事件对象如: xmlHttpRequest 对象。所以,语法中的
element可以换作其他的。
- 这里主要来看第三个参数:可写true / false
- 事件传递有两种方式:冒泡与捕获。默认值为 false, 即冒泡传递(由内向外),当值为 true 时, 事件使用捕获传递(由外向内)。
以此图为例:
事件传递定义了元素事件触发的顺序。 如果你将 <p>元素插入到 <div> 元素中,用户点击<p>元素, 哪个元素的 “click” 事件先被触发呢?
- 在 冒泡 中,内部元素的事件会先被触发,然后再触发外部元素,即: <p>元素的点击事件先触发,然后会触发 <div> 元素的点击事件。
- 在 捕获 中,外部元素的事件会先被触发,然后才会触发内部元素的事件,即: <div> 元素的点击事件先触发 ,然后再触发 <p> 元素的点击事件。
用代码测试:
1) 冒泡
(1)实现冒泡
页面部分:
<div class="btn">
<button class="btn" >点击</button>
</div>
js部分:
var btn=document.getElementsByClassName("btn");
for(var i=0;i<btn.length;i++){
btn[i].onclick=function () {
console.log(this);
}
}
结果:(由内到外冒泡)
(2)阻止事件冒泡 / 阻止默认行为 / 同时阻止事件冒泡和默认行为
- 阻止事件冒泡 (event.stopPropagation())
for(var i=0;i<btn.length;i++){
btn[i].onclick=function (e) {
console.log(this);
e.stopPropagation();
}
请注意:阻止冒泡需要与函数的执行参数e连用。所以就不能将此语句写在函数外。
- 阻止默认行为(event.preventDefault())
- 比如超链接<a>,如果设置了可以跳转的链接,它会执行默认的跳转行为。而现在,想让它仅仅去执行另一个行为,这该怎么解决呢?这就用到了event.preventDefault()方法。
<a href="http://baidu.com" id="ad">进入百度</a>
var a=document.getElementById("ad");
a.onclick=function(e){
e.preventDefault();
console.log(1);
}
出现的结果:(仅仅执行调试代码,不会跳转页面)
- 同时阻止事件冒泡和默认行为(return false)
var a=document.getElementById("ad");
a.onclick=function(e){
console.log(1);
return false;
}
2) 捕获
var btn=document.getElementsByClassName("btn");
for(var i=0;i<btn.length;i++){
btn[i].addEventListener("click",function(){
console.log(this);
},true);
}