事件流
当某个事件执行时,从子元素向父元素触发 或 从父元素子元素触发,称为事件流
事件流的两种模式
事件冒泡:从子元素向父元素触发 -----> 当某个事件触发时,同样的事情会向父元素触发。
但并不是所有的事件都会产生冒泡问题 onfocus onblue onload 不会产生冒泡问题
事件捕获:从父元素向子元素触发
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#div1{
height: 100px;
width: 100px;
border: 1px solid red;
}
#div2{
height: 300px;
width: 300px;
border: 1px solid red;
}
</style>
</head>
<body>
<div id="div2">
<div id="div1">
</div>
</div>
</body>
</html>
<script type="text/javascript">
//文档结构: window document body body元素
var father = document.getElementById("div2");
var son = document.getElementById("div1");
window.onclick = function(){
alert("window被点击");
}
document.onclick = function(){
alert("document被点击");
}
document.body.onclick = function(){
alert("body被点击");
}
father.onclick = function(){
alert("father被点击");
}
son.onclick = function(){
alert("son被点击");
}
</script>
阻止事件冒泡
e.stopPropagation ? e.stopPropagation() : e.cancelBulle = true; 通过事件对象调用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
ul{
display: none;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<ul id="list">
<li>大黄</li>
<li>钢铁侠</li>
<li>蜘蛛侠</li>
</ul>
</body>
</html>
<script>
var btn = document.getElementById("btn");
var ul = document.getElementById("list");
btn.onclick = function(evt){
var e = evt || event;
//阻止冒泡 时间冒泡的兼容
// e.stopPropagation ? e.stopPropagation():e.cancelBubble = true;
//函数为真
//document.write(e.stopPropagation);
//阻止冒泡
e.stopPropagation();
ul.style.display = "block";
}
//阻止冒泡
document.onclick = function(){
ul.style.display = "none";
}
</script>
阻止浏览器默认事件
e.preventDefault?e.preventDefault() : e.returnValue = false;
return false;
阻止鼠标右键
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#box{
height: 100px;
width: 100px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<div id="box">
</div>
</body>
</html>
<script>
var d = document.getElementById("box");
//单机右键 控制div的位置
document.oncontextmenu = function(evt){
//console.log("嘿嘿");
var e = evt || event;
d.style.left = e.pageX + "px";
d.style.top = e.pageY + "px";
//e.preventDefault?e.preventDefault():e.returnValue = false;
return false;
}
</script>
阻止超链接跳转
<body>
<a href = "http://www.baidu.com">跳转</a>
</body>
</html>
<script type="text/javascript">
var x = document.querySelector("a");
x.onclick = function(){
console.log(1);
return false;
}
</script>
事件绑定的方式
- obj.onclick = function(){}
- div onclick = “fun()”
- addEventListener()
事件监听
addEventListener() 主流高版本浏览器
事件监听的好处
1.—可以为同样的元素绑定多次同一个事件
2.—程序员可以使用事件监听的方式,确定触发的过程是冒泡还是捕获
事件源.addEventListener(“去掉on的事件”,function(){},true/false) 默认是false冒泡
// document.addEventListener("click",function(){
// alert("1");
// });
// document.addEventListener("click",function(){
// alert("2");
// });
// document.onclick = function(){
// alert("1");
// }
// document.onclick = function(){
// alert("2");
// }
document.addEventListener("click",function(){
alert("document");
},true);
window.addEventListener("click",function(){
alert("window");
},true);
一个元素同时拥有捕获和冒泡的情况下,执行顺序是什么?
document.addEventListener("click",function(){
alert("document捕获");
},true);
document.addEventListener("click",function(){
alert("document冒泡");
},false);
window.addEventListener("click",function(){
alert("window捕获");
},true);
window.addEventListener("click",function(){
alert("window冒泡");
},false);
先捕获,后冒泡
事件监听兼容
// ie的事件监听 没有第三个参数 默认冒泡
// 该参数不省略on
// document.attachEvent("onclick",function(){
// alert("document");
// });
----------------------------------------------------
//兼容函数 谁 事件 做什么事
function addEvent(obj,type,callBack){
if(obj.addEventListener){//非IE版本
obj.addEventListener(type,callBack);
}else{//IE版本
obj.attachEvent("on"+type,callBack);
}
}
addEvent(document,"click",function(){alert("document")});
事件委托
委托:让别人去做
事件委托:某个事件让其他元素来完成
例如:页面上有1000个li,为每一个li添加单击事件-------使用委托只需要在li父级上加一次事件就可以。
委托对的好处
- 把某个事件加到父元素上,提高程序的执行效率
- 动态创建的元素 可以在创建元素的函数体外部为其添加事件
委托的机制:
- 利用事件冒泡(常见)或者事件捕获
- 不是所有事件都可以实现事件委托,常见的也就那么几个
委托的实现方法
父级元素.事件 = function(){
}
<body>
<ul id = "list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</body>
<script>
//利用事件委托 为每一个li添加单机事件
//处理事件程序为:改变当前操作的li的背景颜色
//委托里不能用this
var oUl = document.getElementById("list");
oUl.onclick = function(evt){
var e = evt || event;
//注意 实际操作的是li
//获取事件源
//targat就代表了当前操作的li
var targat = e.target || e.srcElement;
//alert(targat);
if(targat.tagName == "LI"){
targat.style.backgroundColor = "pink";
}
}
</script>
或者 父级元素.(事件,function(){
})
var oUl = document.getElementById("list");
oUl.addEventListener("click",function(evt){
var e = evt || event;
//注意 实际操作的是li
//获取事件源
//targat就代表了当前操作的li
var targat = e.target || e.srcElement;
//alert(targat);
if(targat.tagName == "LI"){
targat.style.backgroundColor = "pink";
}
});
事件委托的好处
//为所有的li添加高亮事件
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<ul id = "ulist">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<body>
</body>
</html>
<script>
//为所有的li添加高亮事件
var list = document.getElementsByTagName("li");
for(var i=0; i<list.length; i++){
list[i].onmouseover = function(){
this.style.backgroundColor = "red";
}
list[i].onmouseout = function(){
this.style.backgroundColor = "";
}
}
</script>
//动态添加li元素
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<button id="btn">添加</button>
<ul id = "ulist">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<body>
</body>
</html>
<script>
//为所有的li添加高亮事件
var ulist = document.getElementById("ulist");
var list = document.getElementsByTagName("li");
var btn = document.getElementById("btn");
//创建li
btn.onclick = function(){
var e = document.createElement("li");
e.innerHTML = "新添加的元素";
ulist.appendChild(e);
for(var i=0; i<list.length; i++){
list[i].onmouseover = function(){
this.style.backgroundColor = "red";
}
list[i].onmouseout = function(){
this.style.backgroundColor = "";
}
}
}
</script>
完全版:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<button id="btn">添加</button>
<ul id = "ulist">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<body>
</body>
</html>
<script>
//为所有的li添加高亮事件
var ulist = document.getElementById("ulist");
var list = document.getElementsByTagName("li");
var btn = document.getElementById("btn");
//创建li
btn.onclick = function(){
var e = document.createElement("li");
e.innerHTML = "新添加的元素";
ulist.appendChild(e);
}
// for(var i=0; i<list.length; i++){
// list[i].onmouseover = function(){
// this.style.backgroundColor = "red";
// }
// list[i].onmouseout = function(){
// this.style.backgroundColor = "";
// }
// }
ulist.onmouseover = function(evt){
var e = evt || event;
var target = e.target || e.srcElement;
if(target.tagName == "LI"){
target.style.backgroundColor = "red";
}
}
ulist.onmouseout = function(evt){
var e = evt || event;
var target = e.target || e.srcElement;
if(target.tagName == "LI"){
target.style.backgroundColor = "";
}
}
</script>