一、事件的绑定
在Javascript中,事件绑定一共有3种方式:
① 行内绑定
- <标签 属性列表 事件=”事件的处理程序” />
<input type=’button’ onclick=’display()’ />
- this指向window ② 动态绑定
- dom对象.事件 = 事件的处理程序(通常是一个匿名函数)
- this指向了当前正在操作的dom对象
③ 事件监听
- addEventListener
- 三个参数
- 谷歌,火狐,IE11支持,IE8不支持
- addEventListener 中的this指向当前绑定事件的对象
- 事件的类型无on
- attachEvent
- 两个参数
- 谷歌火狐不支持,IE11不支持,IE8支持
- attachEvent中的this指向window
- 事件的类型有on
1. 对象.on事件名字=事件处理函数
缺点: 如果绑定多个事件,前面的事件会被后面的事件覆盖
<input type="button" value="按钮" id="btn" />
<script>
document.getElementById("btn").onclick = function () {
console.log("第一");
};
document.getElementById("btn").onclick = function () {
console.log("第二");
};
</script>
2. 对象.addEventListener("没有on的事件名字",事件处理函数,false);
解释:第三个参数在本篇文章的事件阶段中有解释 优点:可以绑定多个事件 缺点:谷歌、火狐、IE11支持,IE8不支持
<input type="button" value="按钮" id="btn" />
<script>
document.getElementById("btn").addEventListener("click", function () {
console.log("第一");
}, false);
document.getElementById("btn").addEventListener("click", function () {
console.log("第二");
}, false);
</script>
3. 对象.attachEvent("有on的事件名字",事件处理函数);
优点:可以绑定多个事件 缺点:谷歌、火狐、IE11不支持,IE8支持
<input type="button" value="按钮" id="btn" />
<div id="dv"></div>
<script>
document.getElementById("btn").attachEvent("onclik", function () {
console.log("第一");
});
document.getElementById("btn").attachEvent("click", function () {
console.log("第二");
}, false);
</script>
4. 兼容代码
<input type="button" value="第一个按钮" id="btn" />
<script>
//为任意元素.绑定任意的事件, 任意的元素,事件的类型,事件处理函数
function addEventListener(element, type, fn) {
//判断浏览器是否支持这个方法
if (element.addEventListener) {
element.addEventListener(type, fn, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, fn);
} else {
element["on" + type] = fn;
}
}
addEventListener(document.getElementById("btn"), "click", function () {
console.log("码仙1");
});
addEventListener(document.getElementById("btn"), "click", function () {
console.log("码仙2");
});
addEventListener(document.getElementById("btn"), "click", function () {
console.log("码仙3");
});
</script>
二、事件的解绑
用什么方式绑定事件,就应该用对应的方式解绑事件
对象.on事件名字=事件处理函数
对象.on事件名字=null; --> 解绑事件
对象.addEventListener("没有on的事件类型",命名函数,false);
对象.removeEventListener("没有on的事件类型",函数名字,false); --> 解绑事件
对象.attachEvent("on事件类型",命名函数);
对象.detachEvent("on事件类型",函数名字); --> 解绑事件
1. 对象.on事件名字=null;
<input type="button" value="第一个按钮" id="btn1" />
<input type="button" value="干掉第一个按钮的事件" id="btn2" />
<script>
document.getElementById("btn1").onclick = function () {
console.log("码仙");
};
document.getElementById("btn2").onclick = function () {
document.getElementById("btn1").onclick = null;
};
</script>
2. 对象.removeEventListener("没有on的事件类型",函数名字,false);
<input type="button" value="第一个按钮" id="btn1" />
<input type="button" value="干掉第一个按钮的事件" id="btn2" />
<script>
function f1() { console.log("第一个"); };
function f2() { console.log("第二个"); };
document.getElementById("btn1").addEventListener("click", f1, false);
document.getElementById("btn1").addEventListener("click", f2, false);
//点击第二个按钮把第一个按钮的第一个点击事件解绑
document.getElementById("btn2").onclick = function () {
//解绑事件的时候,需要在绑定事件的时候,使用命名函数
document.getElementById("btn1").removeEventListener("click", f1, false);
document.getElementById("btn1").removeEventListener("click", f2, false);
};
</script>
3. 对象.detachEvent("on事件类型",函数名字);
<input type="button" value="第一个按钮" id="btn1" />
<input type="button" value="干掉第一个按钮的事件" id="btn2" />
<script>
function f1() { console.log("第一个"); };
function f2() { console.log("第二个"); };
document.getElementById("btn1").attachEvent("onclick", f1);
document.getElementById("btn1").attachEvent("onclick", f2);
document.getElementById("btn2").onclick = function () {
document.getElementById("btn1").detachEvent("onclick", f1);
};
</script>
4. 兼容代码
<input type="button" value="按钮" id="btn1" />
<input type="button" value="干掉第一个按钮的事件" id="btn2" />
<script>
//绑定事件的兼容
function addEventListener(element, type, fn) {
if (element.addEventListener) {
element.addEventListener(type, fn, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, fn);
} else {
element["on" + type] = fn;
}
}
//为任意的一个元素,解绑对应的事件
function removeEventListener(element, type, fnName) {
if (element.removeEventListener) {
element.removeEventListener(type, fnName, false);
} else if (element.detachEvent) {
element.detachEvent("on" + type, fnName);
} else {
element["on" + type] = null;
}
}
function f1() { console.log("第一个"); }
function f2() { console.log("第二个"); }
addEventListener(document.getElementById("btn1"), "click", f1);
addEventListener(document.getElementById("btn1"), "click", f2);
document.getElementById("btn2").onclick = function () {
removeEventListener(document.getElementById("btn1"), "click", f1);
removeEventListener(document.getElementById("btn1"), "click", f2);
};
</script>
三、事件阶段
通过 e.eventPhase 这个属性可以知道当前事件在哪个阶段
如果这个属性的值是:
1 ---->捕获阶段
2 ---->目标阶段
3 ---->冒泡阶段
一般默认都是冒泡阶段,很少用捕获阶段
冒泡阶段:从里向外
捕获阶段:从外向里
addEventListener方法的第三个参数是false的时候是冒泡阶段
addEventListener方法的第三个参数是true的时候是捕获阶段
<style>
#div1 {
width: 300px;
height: 200px;
background-color: red;
}
#div2 {
width: 250px;
height: 150px;
background-color: green;
}
#div3 {
width: 200px;
height: 100px;
background-color: blue;
}
</style>
<div id="div1">
<div id="div2">
<div id="div3"></div>
</div>
</div>
<script>
//同时注册点击事件
var objs = [document.getElementById("div3"), document.getElementById("div2"), document.getElementById("div1")];
objs.forEach(function (ele) { //遍历注册事件
ele.addEventListener("click", function (e) { //为每个元素绑定事件
console.log(this.id + " ====> " + e.eventPhase);
}, true);
});
</script>
点击蓝色后 addEventListener方法的第三个参数是 false 的时候,点击蓝色div,这时候为冒泡阶段
四、事件冒泡
多个元素嵌套,有层次关系,这些元素都注册了相同的事件,如果里面的元素的事件触发了,外面的元素的该事件自动的触发了
<style>
#div1 {
width: 300px;
height: 200px;
background-color: red;
}
#div2 {
width: 250px;
height: 150px;
background-color: green;
}
#div3 {
width: 200px;
height: 100px;
background-color: blue;
}
</style>
<div id="div1">
<div id="div2">
<div id="div3"></div>
</div>
</div>
<script>
document.getElementById("div1").onclick = function () {
console.log(this.id);
};
document.getElementById("div2").onclick = function () {
console.log(this.id);
};
document.getElementById("div3").onclick = function () {
console.log(this.id);
};
</script>
点击蓝色div后输出
1. 阻止事件冒泡 window.event.cancelBubble=true
<script>
document.getElementById("dv1").onclick = function () {
console.log(this.id);
};
document.getElementById("dv2").onclick = function () {
console.log(this.id);
//阻止事件冒泡,IE特有的,谷歌支持,火狐不支持
window.event.cancelBubble=true;
//阻止超链接默认跳转
e.preventDefault()
};
document.getElementById("dv3").onclick = function () {
console.log(this.id);
};
</script>
2. 阻止事件冒泡 e.stopPropagation()
<script>
document.getElementById("dv1").onclick = function () {
console.log(this.id);
};
document.getElementById("dv2").onclick = function (e) {
console.log(this.id);
//阻止事件冒泡,谷歌和火狐支持
e.stopPropagation();
//阻止超链接默认跳转
e.preventDefault()
};
document.getElementById("dv3").onclick = function () {
console.log(this.id);
};
</script>
五、为同一个元素绑定多个不同的事件,指向相同的事件处理函数
<input type="button" value="码仙" id="btn" />
<script>
//为同一个元素绑定多个不同的事件,指向相同的事件处理函数
document.getElementById("btn").onclick = f1;
document.getElementById("btn").onmouseover = f1;
document.getElementById("btn").onmouseout = f1;
function f1(e) {
switch (e.type) {
case "click":
alert("好帅哦");
break;
case "mouseover":
this.style.backgroundColor = "red";
break;
case "mouseout":
this.style.backgroundColor = "yellow";
break;
}
}
</script>
<input type="button" value="码仙1" id="btn1" />
<input type="button" value="码仙2" id="btn2" />
<script>
//同时注册点击事件
var nodes = [document.getElementById("btn1"), document.getElementById("btn2")]
nodes.forEach(item => {
item.addEventListener("click", function (e) {
console.log(this.id + "====>" + e.eventPhase)
}, true)
})
</script>
六、JS动态添加、删除classl类
<style>
#div { width: 100px; height: 100px; }
.primary { background-color: blue; }
.warning { background-color: yellow; }
.border{border-radius:20px; }
</style>
<div id="div" class="primary"></div>
<input type="button" value="删除" id="btn-del" class="but-primary" />
<input type="button" value="添加" id="btn-add" class="but-primary" />
<input type="button" value="替换" id="btn-replace" class="but-primary" />
<script>
var divNode = document.getElementById("div")
var divClassString = divNode.getAttribute("class") //primary
//删除
document.getElementById("btn-del").addEventListener("click", function () {
// divNode.removeAttribute("class") //移除class属性
var string = divClassString.replace("primary","")
divNode.setAttribute("class",string)
})
//添加
document.getElementById("btn-add").addEventListener("click", function () {
// var string = divClassString+ " border"
var string = divClassString.concat(" border")
divNode.setAttribute("class",string)
})
//替换
document.getElementById("btn-replace").addEventListener("click", function () {
var string = divNode.getAttribute("class").replace("primary", "warning")
divNode.setAttribute("class",string)
})
</script>
七、JQuery中绑定事件的几种方法
主要有on() bind() live() delegate()等几种,相对应的
解绑是off() unbind() die() undelegate()
- on()、bind()、live()、delegate()中除了bind(),其他的都可以给后来追加的元素对象添加绑定事件。
- 这几种方法中各自有对应支持的JQuery版本。
- 在给动态添加的页面元素绑定事件时,通常用on()方法