事件流
事件流描述的是从页面中接受事件的顺序,当几个都具有事件的元素层叠在一起的时候,那么你点击其中一个元素,并不是只有当前被点击的元素会触发事件,而层叠在你点击范围的所有元素都会触发事件。
事件流包括两种模式:冒泡和捕获
事件捕获:
父级元素先触发,子集元素后触发;(由外到内)
事件冒泡:
子集元素先触发,父级元素后触;(由内到外)
子集元素和父元素具备同样的事件,当触发子元素时,也会触发父元素的事件。
事件冒泡和事件捕获实例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>事件冒泡和事件捕获</title>
<style type="text/css">
#bigDiv{
width: 400px;
height: 400px;
border: 1px solid #000;
}
#innerDiv{
width: 200px;
height: 200px;
border: 1px solid #AFEEEE;
}
</style>
<script type="text/javascript">
window.onload=function(){
var bigDiv=document.getElementById('bigDiv');
var innerDiv=document.getElementById('innerDiv');
var arr=[bigDiv,innerDiv,document,document.body];
for (var i=0;i<arr.length;i++) {
//传统方式
// arr[i].onclick=function(){
// console.log(this);
// }
//通过Dom的经典方式添加事件
// addEventListener(参数1,参数2,参数3)
// 参数1表示的是事件的类型 click,load,mousedown,blur,focus
// 参数2表示的是事件的处理程序
// 参数3表示的是事件是否冒泡 true/false
//表示的是事件的冒泡 设置值为false
arr[i].addEventListener('click',show,false);
//表示的是事件的捕获 设置值为true
// arr[i].addEventListener('click',show,true);
}
function show(){
console.log(this);
}
}
</script>
</head>
<body>
<div id="bigDiv">
<div id="innerDiv">
</div>
</div>
</body>
</html>
通过Dom的经典方式添加事件
addEventListener(参数1,参数2,参数3)
参数1表示的是事件的类型 click,load,mousedown,blur,focus
参数2表示的是事件的处理程序
参数3表示的是事件是否冒泡 true/false
事件冒泡测试结果(由内到外)
事件捕获测试结果(由外到内)
事件兼容
(1)事件绑定
addEventListener 用于注册事件处理程序,IE 中为 attachEvent。
addEventListener 是 DOM 中的标准内容
//语法结构
element.addEventListener(event, function, useCapture)
//通过Dom的经典方式添加事件
// addEventListener(参数1,参数2,参数3)
// 参数1表示的是事件的类型 click,load,mousedown,blur,focus
// 参数2表示的是事件的处理程序
// 参数3表示的是事件是否冒泡 true/false
// 注意:不要使用 "on" 前缀。 例如,使用 "click" ,而不是使用 "onclick"。
// 可以使用函数名,来引用外部函数
事件绑定实例一
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>事件绑定</title>
<script type="text/javascript">
window.onload=function(){
var btn=document.getElementById('txt');
//匿名函数
// btn.addEventListener('click',function(){
// alert('事件注册了');
// })
//有名函数
btn.addEventListener('click',show);
//下面这个有名函数放在window里面或外面都OK
function show(){
alert('事件注册了');
}
}
</script>
</head>
<body>
<input type="button" id="txt" value="事件注册(事件绑定)" />
</body>
</html>
事件绑定实例二
通过 addEventListener(添加点击事件监听器)形式的绑定事件不会互相抵消,从而实现一个按钮控制多个事件
(2)事件移除
**removeEventListener()**移除事件监听器(不能使用匿名函数)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>事件绑定和移除</title>
<script type="text/javascript">
window.onload=function(){
//获取页面元素button
var btn2=document.getElementById('btn2');
//注册事件处理程序 addEventListener()
btn2.addEventListener('click',show);
//移除事件监听器 removeEventListener()
// btn2.removeEventListener('click',show);
//下面这个有名函数放在window里面或外面都OK
function show(){
console.log('第一个事件');
console.log('第二个事件');
}
}
</script>
</head>
<body>
<button id="btn2">按钮2</button>
</body>
</html>
上面代码事件绑定测试结果为:
(3)获取事件对象
事件对象封装了事件发生的详细信息,尤其是鼠标、键盘事件。如鼠标事件发生的位置、键盘事件的键盘键等。
IE 中的事件对象:IE 中的事件对象是一个隐式可用的全局对象:event,它是 window对象的一个属性。
标准 DOM 的事件对象:在标准 DOM 浏览器检测发生了某个事件时,将自动创建一个 Event对象,并隐式地将该对象作为事件处理函数的第一个参数传入
案例一:
返回事件目标的名称 使用属性tagName
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>事件对象</title>
<script type="text/javascript">
window.onload=function(){
var btn=document.getElementById('btn');
btn.ondblclick=Myheader;
function Myheader(e){
if(window.event){
e=window.event;
}
//兼容低版本的IE浏览器
var MyIE;
if(e.srcElement){
MyIE=e.srcElement;
}else{
MyIE=e.target;
}
//返回事件目标的名称 使用属性tagName
alert(MyIE.tagName);
}
}
</script>
</head>
<body>
<button id="btn">请双击我</button>
</body>
</html>
上面代码事件绑定测试结果为:
案例二(常用鼠标事件对象)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>常用鼠标事件对象</title>
<style type="text/css">
#leftDIV{
width: 200px;
height: 200px;
background: pink;
float: left;
}
#rightDIV{
width: 200px;
height: 200px;
border: 1px solid #000;
float: left;
overflow: auto;
}
</style>
</head>
<body>
<div id="leftDIV"></div>
<div id="rightDIV"></div>
<script type="text/javascript">
// var MyMouse=document.getElementById('leftDIV');
var MyMouse=document.getElementById('leftDIV');
var txt=document.getElementById('rightDIV');
MyMouse.onclick=Myheader;
MyMouse.ondblclick=Myheader;
MyMouse.onmouseleave=Myheader;
MyMouse.onmousedown=Myheader;
MyMouse.onmouseup=Myheader;
function Myheader(OEvent){
if(window.event){
OEvent=window.event;
}
txt.innerHTML+=OEvent.type+'\n';
}
</script>
</body>
</html>
上面代码事件绑定测试结果为:
(4)阻止冒泡
event.stopPropagation() 阻止事件冒泡的产生
阻止冒泡案例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>阻止事件冒泡</title>
<style>
#bigDIV{
width: 400px;
height: 400px;
border: 20px solid greenyellow;
position: relative;
}
#innerDIV{
width: 200px;
height: 200px;
border: 20px solid orangered;
position: absolute;
left: 80px;
top: 80px;
}
#span{
display: inline-block;
background: pink;
margin: 90px 9px;
}
</style>
</head>
<body>
<div id="bigDIV">
<div id="innerDIV">
<span id="span">这里是最里面的span标签</span>
</div>
</div>
<script type="text/javascript">
var bigDIV=document.getElementById('bigDIV');
var innerDIV=document.getElementById('innerDIV');
var span=document.getElementById('span');
//有名函数
// bigDIV.addEventListener('click',show,false);
// innerDIV.addEventListener('click',show,false);
// span.addEventListener('click',show,false);
// function show(event){
// alert(this);
// //阻止事件冒泡的产生 event.stopPropagation()
// event.stopPropagation();
// }
//匿名函数
bigDIV.addEventListener('click',function(event){
alert('你点击了最外面的div');
event.stopPropagation();
},false);
innerDIV.addEventListener('click',function(event){
alert('你点击了第二层的div');
event.stopPropagation();
},false);
span.addEventListener('click',function(event){
alert('你点击了最里面的span标签');
event.stopPropagation();
},false);
</script>
</body>
</html>
(5)阻止默认
w3c 的方法是 e.preventDefault(),
IE 则是使用 e.returnValue =false;
preventDefault 它是事件对象(Event)的一个方法,作用是取消一个目标元素的默认行为。比如超链接a
<body>
<a href="事件冒泡.html" target="_blank">啦啦啦啦啦</a>
<script type="text/javascript">
var a1=document.getElementsByTagName('a')[0];
//传统用法阻止事件的默认发生
// a1.onclick=function(e){
// e.preventDefault();
// }
//使用DOM方法来阻止默认发生
a1.addEventListener('click',show);
//兼容
function show(e){
if (e.preventDefault) {
e.preventDefault();
} else{
window.event.returnValue=false;
}
}
</script>
</body>
函数闭包
闭包是指有权限访问另一个函数作用域中的变量的函数。在 javascript 语言中,闭包就是函数和该函数作用域的组合。从这个概念上来讲,在 js 中,所有函数都是闭包(函数都是对象并且函数都有和他们相关联的作用域链 scope chain),但是嵌套的函数闭包作用会更大。
嵌套函数:
js中特殊的作用域链,父对象的所有变量对子对象都是可见的,反之则不成立。
闭包的应用(两大作用)
①读取函数内部的变量
②就是让这些变量的值始终保持在内存中
案例一
<script type="text/javascript">
//闭包是指有权限访问另一个函数作用域中的变量的函数
// 闭包就是函数和该函数作用域的组合
//在js中,所有函数都是闭包(函数都是对象且函数都有他们相关联的作用域链),但是嵌套的函数闭包作用会更大。
//函数的嵌套:
//js中特殊的作用域链:
//父对象的所有变量,对子对象都是可见的,反之则不成立。
function PiKaQiu(){
var color='yellow';
var weight=30;
var height=20;
function PiKaQiu_01(){
alert(color);
}
PiKaQiu_01();
}
PiKaQiu();
//使用return
function cat(){
var color='white';
var height=20;
var weight=50;
function cat_01(){
return color;
}
return cat_01();
}
alert(cat());
</script>
案例二
<script type="text/javascript">
function cat(){
var color='橘黄色';
var height='又矮又胖';
var weight='大肥猫';
function cat_01(){
return '这是一只'+color+'的而且'+height+'的'+weight;
}
return cat_01();
}
// alert(cat());
function Person(){
alert(cat());
}
Person();
//闭包函数的两大作用:
//1、可以读取函数内部的变量
//2、让变量的值始终保持在内存中
</script>
案例二代码测试结果为: