JS事件的介绍、绑定方式和事件冒泡事件捕获
事件介绍
事件三要素 :
事件源 : 什么元素
事件类型 : 什么时候
事件处理 : 做什么事 (函数)
交互 : 哪个元素在什么时候做什么事
事件 : js用来处理用户交互的机制
元素注册事件的本质 : 就是给对象属性赋值
语法结构 : 事件源.事件类型 = 事件处理函数
事件的工作原理 :
- 当元素注册事件的时候, 事件处理函数不会执行
- 当用户触发事件的时候, 浏览器就会捕捉事件源(执行事件处理函数)
onclick 在点击的时候
box.onclick = function() {
console.log(111);
}
事件分类(事件类型)
鼠标事件
click : 点击事件
dbclick : 双击 (300ms以内连续发生两次点击事件)
mouseover : 鼠标进入
mouseout : 鼠标滑出
mouseenter : 鼠标进入
mouseleave : 鼠标离开
mousedown : 鼠标按下(左键)
mouseup : 鼠标弹起
mousewheel : 鼠标滚轮滚动
mouseover和mouseenter的区别:
mouseover:只要鼠标指针移入事件所绑定的元素或其子元素,都会触发该事件
mouseenter:只有鼠标移入时间所绑定的元素时,才会触发该事件
如果一个元素没有子元素,那么该元素绑定mouseover和mouseenter效果没有区别
如果绑定了mouseover的元素存在子元素不管鼠标移入该元素还是该元素的子元素都会触发该事件
键盘事件
keyup : 键盘抬起
keydown : 键盘按下
keypress : 键盘按下 (按下去和弹起来两个过程)
表单元素常用的事件
blur : 失去焦点
focus : 获取焦点事件
change : 内容改变事件
select : 被选中事件
其他事件
load:页面加载完毕执行
error:捕获网页中的错误
scroll:元素滚动时执行
resize:浏览器窗口被调整大小执行
事件的注册方式
-
直接在DOM元素中注册(html事件)
直接在html标签通过on+事件类型 = "function() {} "来绑定事件
缺点 : 结构混合在一起 -
在js代码中直接绑定 (dom0级事件)
先在js代码中获取元素, 使用点语法注册
缺点 : 就是不能重复注册同名事件, 否则就会覆盖, 默认冒泡
one.onclick = function() {
console.log(123);
one.style.backgroundColor = "red";
}
- 使用事件监听函数绑定事件(dom2级事件)
addEventListener
事件对象
当用户触发某个事件的时候, 浏览器会捕捉到与触发事件相关的一些信息
获取事件对象 : 谷歌火狐 : e, ev, event, 但是在IE8及其以下版本浏览器里面, 不需要形参, 直接使用全局变量 window.event;
兼容的方法:
function(e) {
e = e || window.event;
}
var box = document.getElementById("box");
box.onclick = function(e) {
e = e || window.event;
console.log(e);
alert(123);
}
addEventListener
点语法注册事件的缺点 : 注册多个同名事件, 后者会覆盖前者
box.onclick = function() {
alert("你好");
}
box.onclick = function() {
alert("今天天气真好")
}//覆盖前面的
使用addEventListener来注册事件 不会覆盖, 而是一次触发
三个参数
type : 事件类型 不要on (click mouseover mouseenter)
listener : 事件处理函数
布尔类型 默认是false, 不传时false
false表示冒泡 true表示捕获
function fun() {
console.log(this);
alert(888);
}
box.addEventListener("click", fun, false)
box.addEventListener("click", function() {
alert(999);
})
IE8注册事件 不支持addEventListener 使用attachEvent()
attachEvent只有两个参数
type :事件类型 这里必须加on (onclick, onmouseover)
listener : 事件处理函数
function fun() {
console.log(this);
alert(888);
}
box.attachEvent("onclick", fun);
box.attachEvent("onclick", function() {
alert(999);
})
谷歌火狐和IE8的兼容
function addEvent(ele, type, fun) { // 这里默认不加on
if(ele.addEventListener) { // 谷歌火狐
ele.addEventListener(type, fun )
} else if(ele.attachEvent) { // IE8及以下的
ele.attachEvent("on" + type, fun)
} else { // 其他浏览器
ele["on" + type] = fun;
}
}
innerText、textContent和innerHTML
innerText 获取元素文本(包含子元素的文本) 但是innerText不是W3C的标准语法 而是微软的自己的语法
火狐42版本以前的版本不支持
textContent 作用和innerText完全一致 只是浏览器兼容性不同
textContent 是W3C的标准语法 但是微软IE8及以前浏览器不支持
<div id="box"> 我是div标签
<p>我是一个p标签</p>
</div>
<script>
var box =document.getElementById("box");
console.log(box.innerText);
console.log(box.textContent);
console.log(box.innerHTML);
</script>
innerText 和innerHTML的区别
innerText : 无法识别标签, 会把所有的内容都设置成元素的文本
innerHTML : 可以识别内容中的标签, 并进行解析
box.innerText = "<a>我是一个a标签</a><p>我是一个p标签</p>"
box.innerHTML = "<a>我是一个a标签</a><p>我是一个p标签</p>"
事件冒泡
事件冒泡 : 当一个元素的事件被触发时, 这个元素所有的度元素的同名事件就会被依次触发
元素 --> 父元素 --> body --> html --> document --> window
事件冒泡一直存在 只是我们以前没有给父元素注册同名事件
<div id="box">
<input type="button" value="点我呀" id="btn">
<div id="son">我是子元素</div>
</div>
<script>
document.getElementById("box").onclick = function() {
alert("我是父盒子")
};
document.getElementById("btn").onclick = function() {
alert("我是小按钮")
};
document.getElementById("son").onclick = function() {
alert("我是小盒子")
};
document.body.onclick = function() {
alert("我是body")
};
document.documentElement.onclick = function() {
alert("我是html")
};
document.onclick = function() {
alert("我是document")
};
window.onclick = function() {
alert("我是window")
};
</script>
案例
需求 : 给每一个li标签注册点击事件, 显示各自的文本
<ul id="ul">
<li>我是li标签1</li>
<li>我是li标签2</li>
<li>我是li标签3</li>
<li>我是li标签4</li>
<li>我是li标签5</li>
<li>我是li标签6</li>
<li>我是li标签7</li>
<li>我是li标签8</li>
</ul>
<script>
// 不用事件冒泡一般做法
// var ul = document.getElementById("ul");
// 遍历li元素, 注册点击事件
// for(var i = 0 ; i < ul.children.length; i++) {
// ul.children[i].onclick = function() {
// alert(this.innerText)
// }
// }
// 使用事件冒泡来做 : 只给父元素注册
var ul = document.getElementById("ul");
ul.onclick = function(e) {
e = e || window.event;
alert(e.target.innerText)
}
</script>
IE8及以下不认target这个属性
IE8的事件目标元素:e.srcElement
兼容IE8及以下版本方法的事件冒泡方法:
var ul = document.getElementById("ul");
ul.onclick = function(e) {
e = e || window.event;
e.target = e.target || e.srcElement;
alert(e.target.innerText)
}
阻止事件冒泡
阻止事件冒泡, 要先获取事件对象
e.stopPropagation(); 谷歌火狐阻止事件冒泡的方法
e.cancelBubble = true; IE8及以前版本浏览器阻止冒泡的方法
对比事件冒泡盒子案例
document.getElementById("box").onclick = function() {
alert("我是父盒子")
};
document.getElementById("btn").onclick = function() {
alert("我是小按钮")
};
document.getElementById("son").onclick = function() {
alert("我是小盒子")
};
document.body.onclick = function(e) {
// console.log(e);
e = e || window.event;
alert("我是body")
// 阻止事件冒泡, 要先获取事件对象
// e.stopPropagation(); // 谷歌火狐阻止事件冒泡的方法
e.cancelBubble = true; // IE8及以前版本浏览器阻止冒泡的方法
};
document.documentElement.onclick = function() {
alert("我是html")
};
document.onclick = function() {
alert("我是document")
};
window.onclick = function() {
alert("我是window")
};
事件捕获
事件捕获 : 当一个元素的事件被触发, 先从最顶级的父元素往下依次触发, 直到目标元素
window --> document --> html --> body --> 父元素 --> 目标元素
e.stopPropagation(); 也可以用来阻止事件捕获
<div id="box">
<input type="button" value="点我呀" id="btn" />
<div id="son">我是子元素</div>
</div>
<script>
document.getElementById("btn").addEventListener(
"click",
function() {
alert("我是小按钮");
},
true
);
document.getElementById("box").addEventListener(
"click",
function() {
alert("我是父盒子");
},
true
);
document.getElementById("son").addEventListener(
"click",
function() {
alert("我是子盒子");
},
true
);
document.body.addEventListener(
"click",
function(e) {
alert("我是body");
e = e || window.event;
e.stopPropagation(); // 也可以用来阻止事件捕获
},
true
);
document.documentElement.addEventListener(
"click",
function() {
alert("我是html");
},
true
);
document.addEventListener(
"click",
function() {
alert("我是document");
},
true
);
window.addEventListener(
"click",
function() {
alert("我是window");
},
true
);
</script>
事件冒泡和事件捕获同时存在事件捕获会先执行