# 事件处理函数
如何绑定事件处理函数?
***1.***ele.onxxx = function(event){}
兼容性很好,但是一个元素的同一个事件上只能绑定一个事件,基本上等同于写在HTML行间上
<div style="width:100px;" onclick="consloe.log('a')"></div>
<div style="width:100px;height:100px;background-color:red;"></div>
var div = document.getElementsByTagName('div')[0];
div.onclick = function() {
this.style.backgroundColor = 'green';
}
2
3
4
2.obj.addEventListener(事件类型,处理函数,fasle)
IE9以下不兼容,可以为一个事件绑定多个处理程序
,并且按照绑定的顺序来执行
div.addEventListener('click',function(){
console.log('a');
},false);
div.addEventListener('click',function(){
console.log('b');
},false);
2
3
4
5
6
3.obj.attachEvent('on'+事件类型,处理函数);
IE独有,一个事件同样可以绑定多个处理程序
div.attachEvent('onclick',function(){
console.log('a');
});
2
3
小提示
绑定事件的处理函数里面如果用到for循环里面的i,就要考虑下是否是闭包的问题
事件处理函数的运行环境
ele.onxxx和obj.addEventListener程序this指向的是dom元素本身
obj.attachEvent程序this指向window
# 小练习
<div class="container">
<p>
<button id="btnClear">清空</button>
</p>
<ul class="list">
<li>项目1<button>删除</button></li>
<li>项目2<button>删除</button></li>
<li>项目3<button>删除</button></li>
<li>项目4<button>删除</button></li>
<li>项目5<button>删除</button></li>
<li>项目6<button>删除</button></li>
<li>项目7<button>删除</button></li>
<li>项目8<button>删除</button></li>
<li>项目9<button>删除</button></li>
<li>项目10<button>删除</button></li>
</ul>
</div>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var btnclear = document.getElementById("btnClear");
var ul = document.querySelector(".list");
btnclear.onclick = function() {
ul.innerHTML = "";
}
//得到ul下的所有按钮
var btns = ul.querySelectorAll("button");
for (var i = 0; i < btns.length; i++){
var b = btns[i]; //得到当前按钮
b.onclick = function() {
this.parentNode.remove();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 封装函数
封装兼容性的addEvent(elem,type,handle);方法,三个参数,一个元素,一个事件类型,一个处理函数
function addEvent(elem,type,handle) {
if(elem.addEventListener) {
elem.addEventListener(type,handle,fasle);
}else if(elem.attachEvent) {
elem,attachEvent('on'+type,function(){
handle.call(elem);
})
}else{
elem['on'+type] = handle;
}
}
2
3
4
5
6
7
8
9
10
11
# 解除事件处理程序
elel.onclick = false/null;
ele.removeEventListener(type,fn,false);
ele.detachEvent('on'+type,fn);
//若绑定匿名函数,则无法解除
2
3
4
var div = document.getElementsByTagName('div')[0];
div.onclick = function() {
console.log('a');
this.onclick = null;
}
2
3
4
5
var div = document.getElementsByTagName('div')[0];
div.addEventListener('click',test,false);
function test(){
console.log('a');
}
div.removeEventListener('click',test,false);
2
3
4
5
6
# 事件处理模型
# 事件冒泡
<div class="wrapper">
<div class="content">
<div class="box"></div>
</div>
</div>
2
3
4
5
.wrapper {
width: 400px;
height: 400px;
background-color: red;
}
.content {
width: 300px;
height: 300px;
background-color: green;
}
.box {
width: 200px;
height: 200px;
background-color: blue;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var wrapper = document.getElementsByClassName('wrapper')[0];
var content = document.getElementsByClassName('content')[0];
var box = document.getElementsByClassName('box')[0];
wrapper.addEventListener('click',function(){
console.log('wrapper')
},false);
content.addEventListener('click',function(){
console.log('content')
},false);
box.addEventListener('click',function(){
console.log('box')
},false);
2
3
4
5
6
7
8
9
10
11
12
13
事件冒泡
结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素(从代码的角度上自底向上冒泡)
点击蓝色区域会自底向上冒泡
# 事件捕获
事件捕获
结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)(自顶向下)
依次点击蓝色绿色红色,捕获正好和冒泡相反
,触发捕获就是给addEventListener的第三个参数填true即可触发
IE没有捕获事件
事件冒泡和捕获
触发顺序,先捕获,后冒泡
事件捕获
跟事件冒泡
正好传递顺序相反
,想要触发事件捕获
,把里面的false该位true
就可以,同一个对象只能绑定一个事件类型
focus
,blur
,change
,submit
,reset
,select
等事件不冒泡
同一个对象的同一个事件类型,上面绑定了两个处理函数,一个冒泡,一个捕获
wrapper.addEventListener('click',function(){
console.log('wrapperBubble')
},false);
content.addEventListener('click',function(){
console.log('contentBubble')
},false);
box.addEventListener('click',function(){
console.log('boxBubble')
},false);
wrapper.addEventListener('click',function(){
console.log('wrapper')
},true);
content.addEventListener('click',function(){
console.log('content')
},true);
box.addEventListener('click',function(){
console.log('box')
},true);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
事件执行一定要按照顺序来
,因为是boxBubble先绑定的,所以就先执行boxBubble,如果把整个三个捕获放在前面,等到蓝色区域(box)执行的时候就先打印box,再打印boxBubble.
# 阻止冒泡
document.onclick = function (){
console.log('你闲的呀');
}
div.conclick = function(e) {
this.style.backgroundColor = 'green';
// e.stopPropagation();
//此时的e就是系统的事件对象
e.cancelBubble = true;
//IE的
}
//W3C标准event.stopPropagation(),但不支持IE9以下版本
//IE独有event.cancelBubble = true;
2
3
4
5
6
7
8
9
10
11
12
# 封装函数
封装取消冒泡的函数
function stopBubble(event) {
if(event.stopPropagation) {
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}
stopBubble(e);
2
3
4
5
6
7
8
# 阻止默认事件
默认事件
表单提交,a标签跳转,右键菜单等等
# 1.return false
; 以对象属性的方式注册的事件才生效
document.oncontextmenu = function () {
console.log('a');
return false;//禁止右键菜单呼出
}
2
3
4
# 2.event.preventDefault()
;w3c标注,ie9以下不兼容
document.oncontextmenu = function (e) {
console.log('a');
e.preventDefault();//禁止右键菜单呼出
}
2
3
4
# 3.event.returnValue = false;兼容IE
document.oncontextmenu = function (e) {
console.log('a');
e.returnValue = false;//禁止右键菜单呼出
}
2
3
4
# 封装函数
封装阻止默认事件的函数cancelHandler(event)
document.oncontextmenu = function(e) {
console.log('a');
cancelHandler(e);
}
function canceHandler(event) {
if(event.preventDefault) {
event.preventDefault();
}else{
event.returnValue = false;
}
}
2
3
4
5
6
7
8
9
10
11
# 事件对象
event谷歌||window.event用于IE
# 事件源对象
event.target
火狐只有这个
event.srcElement
IE只有这个
chrome上面包含了这两个.
# 封装函数
div.onclick = function(e) {
var event = e || window.event;
var target = even.target || event.srcElement;
console.log(target);
}
2
3
4
5
# 事件委托
事件委托
利用事件冒泡,和事件源对象进行处理
优点:1.性能 不需要循环所有的元素一个个绑定事件
2.灵活 当有新的子元素时不需要重新绑定事件
事件委托例子(打印ul里面的li里面的文本内容)
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
2
3
4
5
6
7
8
9
10
11
12
var li = document.getElementsByTagName('li');
var len = li.length;
for (var i = 0; i < len; i ++){
li[i].onclick = function(){
console.log(this.innerText);
}
}
2
3
4
5
6
7
如果li多了,给每个li绑定事件,这样效率会很低,所以建议用事件委托
var ul = document.getElementsByTagName('ul')[0];
ul.onclick = function(e) {
var event = e || window.event;
var target = event.target || event.srcElement;
console.log(target.innerText);
//因为ul里面li的源对象就是它自己,所以打印自己的文本内容
}
2
3
4
5
6
7
# 事件分类
# 鼠标事件
click
,mousedown
,mousemove
,mouseup``,contextmenu
,mouseover
,mouseout
,mouseenter
,mouseleave
click = mousedown+mouseup
三个事件同时在页面上执行顺序是mousedown
,mouseup
,click
mousemove
鼠标移动事件
contextmenu
鼠标右键唯一的用途就是禁止鼠标右键事件
mouseover
当鼠标移入该区域发生函数样式
mouseout
当鼠标移出该区域发生函数样式
mouseenter
,mouseleave
跟mouseover,mouseout
功能和写法都一样,都是H5的新语法
Dom3标准规定
click事件只能监听左键,只能通过mousedown和mouseup来判断鼠标键
# 例子
用事件对象button来区分鼠标的按键,0/1/2
document.onmousedown = function(e) {
if(e.button == 2) {
console.log('right');
}else if(e.button == 0) {
console.log('left');
}
}
2
3
4
5
6
7
<div style="width: 100px;height: 100px;background-color: red;position: absolute;left:0;top:0;"></div>
var div = document.getElementsByTagName('div')[0];
var disX,
disY;
div.onmousedown = function(e) {
disX = e.pageX - parseInt(div.style.left);
disY = e.pageY - parseInt(div.style.top);
document.onmousemove = function(e) {
var event = e|| window.event;
div.style.left = e.pageX - disX + "px";
div.style.top = e.pageY - disY + "px";
}
document.onmouseup = function() {
div.onmousemove = null;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
typeof 的几个特例
div.setCapture
捕获页面上发生的所有事件,在任意地方发生的任何事件都加到自己身上
div.releaseCapture()
快用完的时候释放掉
# 键盘事件
keydown
keyup
keypress
触发顺序 keydown>keypress>keyup
keydown和keypress的区别
keydown
的charCode = 0
;
keydown
可以响应所有键盘按键,
keypress
只可响应字符类键盘按键
keypress
返回ascll码
,可以转换为对应字符
document.onkeypress = function(e) {
console.log(String.fromCharCode(e.charCode));
//返回按下的相应按键
}
2
3
4
# 文本操作事件
input
var input = document.getElementsByTagName('input')[0];
input.oninput = function (e) {
console.log(this.value);
//在输入框无论输入什么值都会在控制台上从左到右打印
//删除一个值也会在控制台从左到右打印
}
2
3
4
5
6
focus,blur <input type="text" value="请输入用户名"style="color:#999" onfocus="if(this.value=='请输入用户名'){this.value='';this.style.color='#424242'}" onblur="if(this.value==''){this.value='请输入用户名';this.style.color='#999'}">
change 鼠标聚焦到输入框上,输入字符不发生改变,鼠标离开输入框发生改变
# window上的事件
窗口操作类事件
scroll
滚动条滚动的位置
load
整个页面图片等解析完毕后window触发onload事件才执行函数,效率最低
window.onload = function() {
var div = document.getElementsByTagName('div')[0];
console.log(div);
div.style.width = "100px";
div.style.height = "100px";
div.style.backgroundColor = "red";
2
3
4
5
6
# 二维数组
扫雷游戏会用到二维数组
var arr = [
[1 ,2 ,3],
[11 ,22 ,33],
[111,222,333]
]
arr[0][0];//第一行的第一个
arr[1][0];//第二行的第一个
2
3
4
5
6
7
8
← 窗口尺寸&脚本化CSS json异步加载 →