01 事件流
- 事件冒泡概念
事件开始从最具体的元素开始接受,逐级向上传播到较为不具体的文档
如:div-body-html-document-window - 事件捕获概念
事件开始从较为不具体的文档开始接受,逐级向下传播到最具体的元素
如:window-document-html-body-div
02 事件处理程序
- HTML事件处理程序
例:在div元素里的事件属性调用函数
<div id="box" onclick:"test();"></div>
<script type='text/javascript'>
function test(){
document.getElementById('box').innerHTML += '1';
//点击这个div部分将会打印一个1
}
</script>
- DOM0级事件处理程序
<div id="box"><div>
<script type='text/javascript'>
var box = document.getElementById('box');
box.onclick = function(){
this.innerHTML += 1;
}
//删除事件处理程序
box.onclick = null;
//缺点是会有覆盖现象
box.onclick = function(){
this.innerHTML += 2;
}//这个会覆盖+=1
</script>
3.DOM2级事件处理程序(IE8不支持DOM2级事件处理程序)
<div id="box"><div>
//addEventListner(事件名,处理程序的函数,布尔值)
//布尔值默认为false 处于冒泡阶段,true为事件捕获阶段
//removeEventListner()
<script type='text/javascript'>
var box = document.getElementById('box');
box.addEventListner('click', function(){
this.innerHTML +=1;
},false);
box.addEventListner('click', function(){
this.innerHTML +=2;
},false);
//这种情况下1和2都会出来
//正确移除事件方式
function test(){
this.innerHTML += 1 ;
}
box.addEventListner('click', test, false);
box.removeEventListner('click',text, false);
</script>
4.IE事件处理程序
//IE:attachEvent()添加事件监听者 detachEvent()移除
//用法与DOM2级事件处理程序大体一样
//事件名click要改成onclick 且没有布尔值
//函数里的this.innerHTML改成
兼容IE8与其他浏览器的方法(自己封装一个函数)
<div id="box"><div>
<script type='text/javascript'>
var box = document.getElementById('box');
addEvent(box,'click',function(){
console.log(this.innerHTML);
})
function addEvent (target, eventType, handler){
if(target.addEventListener){//是否有这个属性
target.addEventListener(eventType, handler ,false);
}else{
target.attachEvent('on' + eventType, function(){
handler.call(target);//call方法可以改变this指向
//这里把指向从window改向了box
});
}
}
</script>
03 事件调用顺序
相同点
- 如果同时出现HTML事件处理程序和DOM0级事件处理程序,DOM0级事件处理程序会覆盖HTML事件处理程序
不同点
如果同时出现HTML、DOM0级、DOM2级、IE事件处理程序
- chorme,safari,FF浏览器以及IE11结果:DOM0级、DOM2级、IE
- IE9、10结果:DOM0级、DOM2级、IE
- IE8:DOM0级、IE
04 如何获取事件对象
<div id="box"><div>
<script type='text/javascript'>
window.onload = function(){
var box = document.getElementById('box');
//1.event对象是事件处理程序的第一个参数
//ie8不兼容 打印出来为undefined
box.onclick = function(e){
this.innerHTML = e;//打印出来mouseevent
}
//2.直接可以使用event变量 低版本火狐不兼容
box.onclick = function(){
this.innerHTML = event;
}
//3.兼容性写法
box.onclick = function(e){
e = e || window.event ;
this.innerHTML = e;
}
}
</script>
05 事件目标
currentTarget target srcElement
- currentTarge属性返回时间当前所在的节点,正在执行的监听函数所绑定的节点 基本=this
<ul id = "box">
<li class="item">1</li>
<li class="item">2</li>
</ul>
<script type='text/javascript'>
var box = document.getElementById('box');
box.onclick = function(){
e = e || window.event;
console.log(e.currentTarget);//打印的是ul标签
var items = document.getElementTagName('li');
itmes[0].innerHTML = e.currentTarget;//打印的是object HTMLUListElement
}
</script>
- target属性返回的是事件的实际目标对象不支持IE8
//点击li部分
box.onclick = function(){
e = e || window.event;
console.log(e.target);//打印的是li标签
console.log(e.target===this);//打印的是false因为this指向ul标签
//this对象跟e.currentTarget属性是一致的
console.log(e.currentTarget===this);true
- srcElement 跟target方法一致 不支持低版本火狐
box.onclick = function(){
e = e || window.event;
console.log(e.srcElement);//打印的是li标签
}
- 兼容性代码
box.onclick = function(){
e = e || window.event;
var target = e.target || e.srcElement;
console.log(target);
}
06 事件代理
//目的:鼠标移到li部分 li部分变色 移开鼠标 恢复原来颜色
<head>
<style type="text/css">
* {
list-style: none;
}
li {
float: left;
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
color: red;
background-color: black;
margin: 0 10px;
}
</style>
</head>
<body>
<ul id="box">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script type='text/javascript'>
//常规方法实现 1.获取标签
var lis = document.getElementsByTagName('li');
for (var i = 0; i < lis.length; i++) {
lis[i].onmouseover = function () {
this.style.backgroundColor = 'blue';
}
lis[i].onmouseout = function () {
this.style.backgroundColor = 'black';
}
}
//事件代理的方式实现
//事件代理应用:事件实际目标对象target和srcElement属性完成
//优点:提高性能以及降低代码复杂度 且未来添加的li标签也会生效
var box = document.getElementById('box');
box.onmouseover = function (e) {
e = e || window.event;
var target = e.target || e.srcElement;
target.style.backgroundColor = 'blue';
}
box.onmouseout = function (e) {
e = e || window.event;
var target = e.target || e.srcElement;
target.style.backgroundColor = "black";
}
</script>
07 事件冒泡
- bubble
<button id="btn" style="height: 30px;width:200px;">按钮</button>
<input type="text" id="test">
<script type="text/javascript">
//1.bubbles 返回一个布尔值 表示当前时间是否会冒泡 只读
//大部分事件都冒泡 focus blur scroll事件不会冒泡 false
var btn = document.getElementById('btn');
var test = document.getElementById('test');
btn.onclick = function (e) {
e = e || window.event;
console.log(e.bubbles);//true
}
test.onfocus = function (e) {
e = e || window.event;
console.log(e.bubbles);//false
}
</script>
- stopPropagation()表示取消时间的进一步冒泡 无返回值 ie8不支持
btn.onclick = function(e){
e = e || window.event;
e.stopPropagation();
}
document.body.onclick = function(e){
e = e || window.event;
console.log('body');//不会被打印出来
}
//但是无法阻止同一时间的其他监听函数被调用
//如果有两个addEventListener 在第一个addEventListener添加stopPropagation()
//第二个addEventListener一样会执行
-
stopImmediatePropagation()可以组织其他监听函数被调用
-
cancelBubble 阻止冒泡 可读写 默认为false
btn.onclick = function (e) {
e = e || window.event;
e.cancelBubble = true;
}
document.body.onclick = function(e){
e = e || window.event;
console.log('body');//不会被打印出来
}
小结:stopImmediatePropagation() stopPropagation()属性 IE8不支持
cancelBubble = true;全浏览器支持但是不是标准写法
- 兼容写法
btn.onclick = function(e){
e = e || window.event;
if(e.stopPropagation){//如果存在这个方法
e.stopPropagation();
}else{
e.cancelBubble = true;
}
}
08 取消默认事件
//1.<a href="javascript:void(0);">111</a>//不会跳转页面
//2.<a href="javascript:;">111</a>
<a href = "#" id="box">111</a>
<script type="text/javascript">
var box = document.getElementById('box');
box.onclick = function(e){
e = e || window.event;
if(e.preventDefault){
e.preventDefault();//不兼容ie8及以下
}else{
e.returnVaule = false;//不兼容ie8以上
}
}
</script>
box.onclick = function(e){
e = e || window.event;
return false;
09 鼠标事件对象属性
//坐标位置
<head>
<style type="text/css">
#box {
height: 300px;
width: 300px;
background: red;
}
</style>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
var box = document.getElementById('box');
box.onmousemove = function (e) {
e = e || window.event;
//clientX/Y和x/y:相对于浏览器的x轴y轴距离(浏览器的有效区域)
this.innerHTML = `clinetX:${e.clientX};clinetY:${e.clientY};X:${e.x};Y:${e.y}`;
//screenX/Y:相对于显示器屏幕的x轴和y轴的距离
this.innerHTML = `screenX:${e.screenX};screenY:${e.screenY};`;
//pageX/Y:相对于页面x轴和y轴的距离
this.innerHTML = `pageX:${e.pageX};pageY:${e.pageY};`;
//offsetX/Y:相对于事件源的x轴和y轴的距离
this.innerHTML = `offsetX:${e.offsetX};offsetY:${e.offsetY};`;
}
</script>