一, 事件流程
1.1 事件的三要素:
事件源:发生事件的对象
事件类型:类型比如单击、双击、鼠标的移入、移除
事件处理程序: 触发事件之后做些什么,事件处理的函数
1.2事件分为三个阶段:
事件捕获阶段:事件是由最外层的元素向目标元素传递的过程(IE不支持事件捕获)
事件处理阶段:事件正位于目标元素之上
事件冒泡阶段:有目标元素向外层元素传递的过程
执行顺序:事件捕获–》事件处理–》事件冒泡
事件的捕获和冒泡指的是当前元素的子元素跟当前元素拥有相同的事件,触发子元素的时候,当前元素对应事件发生在什么阶段
二,事件
2.1 DOM0 级事件
注:dom0级都属于冒泡阶段
结构:
1. <div id="box1">
2. <div id="box2">
3. <div id="box3"></div>
4. </div>
5. </div>
执行代码:
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var box3 = document.getElementById("box3");
box1.onclick = function(){
console.log("我是box1");
}
box2.onclick = function(){
console.log("我是box2");
}
box3.onclick = function(){
console.log("我是box3");
}
结果:
2.2 DOM2级添加事件
dom.addEventListener(type,fn,bool)
dom:要添加事件的对象
type:事件类型
fn:事件处理函数
bool:事件的触发阶段 默认值为false false表示冒泡阶段 如果为true则表示捕获阶段
注意:当事件达到最精确时,会根据绑定顺序来执行。
结构:
1. <div id="box1">
2. <div id="box2">
3. <div id="box3"></div>
4. </div>
5. </div>
执行代码:
1. // 获得元素
2. var box1 = document.getElementById('box1');
3. var box2 = document.getElementById('box2');
4. var box3 = document.getElementById('box3');
5.
6. // 事件捕获
7. // 绑定事件
8. box1.addEventListener('click',function() {
9. console.log('box1的事件捕获阶段');
10. }, true);
11. box1.addEventListener('click',function() {
12. console.log('box1的事件冒泡阶段');
13. }, false);
14. box2.addEventListener('click',function() {
15. console.log('box2的事件捕获阶段');
16. }, true);
17. box2.addEventListener('click',function() {
18. console.log('box2的事件冒泡阶段');
19. }, false);
20. box3.addEventListener('click',function() {
21. console.log('box3的事件冒泡阶段');
22. }, false);
23. box3.addEventListener('click',function() {
24. console.log('box3的事件捕获阶段');
25. }, true);
结果:
2.3 高级浏览器的DOM2和DOM0的区别
DOM0级事件:给同一个元素绑定相同类型的事件只能绑定一个,多个事件共存的时候,后面的会覆盖掉前面的
DOM2级事件:给同一个元素绑定相同类型的事件可以绑定多个,多个事件共存的时候,按照绑定的顺序依次执行
DOM0级事件和DOM2级事件可以共存,执行顺序跟绑定顺序一样
执行代码:
1. // 获得元素
2. var box1 = document.getElementById('box1');
3. var box2 = document.getElementById('box2');
4. var box3 = document.getElementById('box3');
5. /*
6. DOM0级事件:给同一个元素绑定相同类型的事件只能绑定一个,多个事件共存的时候,后面的会覆盖掉前面的
7. DOM2级事件:给同一个元素绑定相同类型的事件可以绑定多个,多个事件共存的时候,按照绑定的顺序依次执行
8. DOM0级事件和DOM2级事件可以共存,执行顺序跟绑定顺序一样
9. */
10. // 事件捕获
11. // box1.onclick = function() {
12. // console.log('DOM0的box1---1');
13. // }
14. box1.addEventListener('click',function() {
15. console.log('DOM2的box1---1');
16. });
17. box1.addEventListener('click',function() {
18. console.log('DOM2的box1---2');
19. });
20. box1.onclick = function() {
21. console.log('DOM0的box1----2');
22. }
23. box1.addEventListener('click',function() {
24. console.log('DOM2的box1---3');
25. });
26. box1.addEventListener('click',function() {
27. console.log('DOM2的box1---4');
28. });
29.
结果:
2.4高级浏览器中 this 指向的问题
指向绑定事件的对象
执行代码:
1. box1.addEventListener('click',function() {
2. console.log('box1的事件捕获阶段');
3. console.log(this);
4. }, true);
5. box1.addEventListener('click',function() {
6. console.log('box1的事件冒泡阶段');
7. console.log(this);
8. }, false);
9. box2.addEventListener('click',function() {
10. console.log('box2的事件捕获阶段');
11. console.log(this);
12. }, true);
13. box2.addEventListener('click',function() {
14. console.log('box2的事件冒泡阶段');
15. console.log(this);
16. }, false);
17. box3.addEventListener('click',function() {
18. console.log('box3的事件冒泡阶段');
19. console.log(this);
20. }, false);
21. box3.addEventListener('click',function() {
22. console.log('box3的事件捕获阶段');
23. console.log(this);
24. }, true);
结果:
2.5 IE的高级绑定事件
IE不支持事件捕获,只有事件冒泡
dom.attachEvent(ontype, fn);
dom:要绑定事件的对象
type:事件类型
fn:处理函数
执行代码:
1. // 获得元素对象
2. var div = document.getElementsByTagName('div')[0];
3.
4. // dom0的绑定事件
5. // div.onclick = function() {
6. // console.log('dom0事件----1');
7. // }
8. // div.onclick = function() {
9. // console.log('dom0事件----2');
10. // }
11.
12. // dom2级事件绑定
13. div.attachEvent('onclick', function() {
14. console.log('dom2事件----1');
15. });
16. div.attachEvent('onclick', function() {
17. console.log('dom2事件----2');
18. });
19. // dom0的绑定事件
20. div.onclick = function() {
21. console.log('dom0事件----1');
22. }
23. div.attachEvent('onclick', function() {
24. console.log('dom2事件----3');
25. });
26. div.attachEvent('onclick', function() {
27. console.log('dom2事件----4'); });
结果:
2.6 IE的DOM2和DOM0的区别和执行顺序
所有的DOM0,相同元素的同类型事件只能存在一个,后面的会覆盖掉前面
DOM2级,相同元素的同类型事件可以绑定多个
IE中的执行顺序:
1. 首先执行DOM0级事件
2. 按照绑定事件的倒序执行DOM2级事件
2.7IE中 this的指向问题
DOM0指向的是绑定事件的对象
DOM2指向window对象
执行代码:
1. // 获得元素
2. var box1 = document.getElementById('box1');
3. var box2 = document.getElementById('box2');
4. var box3 = document.getElementById('box3');
5.
6. // 事件捕获
7. // 绑定事件
8. box1.attachEvent('onclick',function() {
9. console.log('box1的事件冒泡阶段');
10. console.log(this);
11. });
12. box2.attachEvent('onclick',function() {
13. console.log('box2的事件捕获阶段');
14. console.log(this);
15. });
16. box3.attachEvent('onclick',function() {
17. console.log('box3的事件冒泡阶段');
18. console.log(this); });
结果:
2.8 兼容绑定事件
封装一个函数
1. // 获得元素对象
2. var div = document.getElementsByTagName('div')[0];
3.
4. /*
5. 封装一个函数
6. 函数名: bindEvent
7. 调用方式:bindEvent(div,'click', function() {
8. this.backgroundColor = 'green';
9. })
10. 参数:bindEvent(dom, type, fn)
11. */
12. function bindEvent(dom, type, fn) {
13. // 三类浏览器:高级浏览器 IE浏览器 杂牌浏览器
14. // 能力检测
15. if (dom.addEventListener) {
16. // 高级浏览器
17. dom.addEventListener(type, fn);
18. } else if (dom.attachEvent) {
19. // IE浏览器
20. dom.attachEvent('on' + type, function() {
21. // attachEvent绑定的事件this指向window
22. fn.call(dom);
23. });
24. } else {
25. // 其他浏览器
26. dom['on' + type] = fn;
27. }
28.
29. }
30. bindEvent(div,'click', function() {
31. this.style.backgroundColor = 'green';
32. console.log(111); });
2.9 点和中括号的区别
.不解析变量
[] 可以解析变量
执行代码:
1. var obj = {
2. a: 1,
3. b: 2
4. }
5. var a = 'b';
6. console.log(obj.a); // 1
7. console.log(obj[a]);// obj[a]==obj["b"]=2
8. console.log(obj['a']);// obj.a = 1
结果:
2.10 移除事件
高级浏览器:
dom.removeEventListener(type, fn, bool)
需要把需要移除事件的函数在外部声明后引用,否则不能实现移除
type:事件类型
fn:要移除的函数(函数名)
bool:要移除的阶段 默认值为false 表示冒泡阶段,true表示捕获阶段
执行代码:
1. // 获得元素对象
2. var div2 = document.getElementById('div2');
3. var div1 = document.getElementById('div1');
4.
5. // 绑定事件
6. div2.onclick = function() {
7. console.log('div2被点击了');
8. }
9. function demo1() {
10. console.log('div1被点击了----捕获');
11. }
12. // div1绑定dom2事件
13. div1.addEventListener('click', demo1, true);
14. div1.addEventListener('click', function() {
15. console.log('div1被点击了---冒泡');
16. }, false);
17.
18. // 移除事件
19. div1.removeEventListener('click', demo1, true);
结果:
IE浏览器:
dom.detachEvent(ontype, fn)
type:事件类型
fn:要移除的函数(函数名)
执行代码:
1. // 获得元素对象
2. var div2 = document.getElementById('div2');
3. var div1 = document.getElementById('div1');
4.
5. // 绑定事件
6. div2.onclick = function() {
7. console.log('div2被点击了');
8. }
9. function demo1() {
10. console.log('div1被点击了----冒泡1');
11. }
12. // div1绑定dom2事件
13. div1.attachEvent('onclick', demo1);
14. div1.attachEvent('onclick', function() {
15. console.log('div1被点击了---冒泡2');
16. });
17.
18. // 移除事件
19. div1.detachEvent('onclick', demo1);
结果:
三,事件对象
当事件触发的时候,会产生一个对象,该对象记录着发生事件相关的详细信息。
3.1 DOM0
DOM0级的情况:
高级浏览器会自动传递事件对象,只需要用形参接受即可使用
IE浏览器不会自动传递事件对象,需要手动接收,接受的方式为 e = window.event
IE中的事件对象
经过测试,在IE中没有将事件对象传递,而是在window.event身上
列表不能打开,用**for(in)**循环展开
DOM0兼容处理
var e = e || event
执行代码:
1. // DOM0级的事件对象
2. var div = document.getElementsByTagName('div')[0];
3. /*
4. DOM0级的情况:
5. 高级浏览器会自动传递事件对象,只需要用形参接受即可使用
6. IE浏览器不会自动传递事件对象,需要手动接收,接受的方式为 e = window.event
7. DOM0兼容处理
8. var e = e || event//短路语法
9. */
10. // 绑定事件
11. div.onclick = function(e) {
12. var e = e || event;
13. console.log(e); }
结果:
3.2 DOM2
DOM2级都可以传递事件对象,可以使用形参接收,然后直接使用
执行代码:
1. // DOM0级的事件对象
2. var div = document.getElementsByTagName('div')[0];
3. /*
4. DOM2级都可以传递事件对象,可以使用形参接收,然后直接使用
5. */
6. // 高级浏览器
7. if (div.addEventListener) {
8. div.addEventListener('click', function(e) {
9. console.log(e);
10. });
11. } else {
12. // IE
13. div.attachEvent('onclick', function(e) {
14. console.log(e);
15. }); }
结果:
四、 事件对象的属性和方法
查看 :
高级浏览器直接查看
IE浏览器需要使用for in 进行查看
1. // IE
2. div.attachEvent('onclick', function(e) {
3. // console.log(e);
4. for (var i in e) {
5. console.log(i, ' : ', e[i]);
6. }
7. });
4.1 offsetX和offsetY
当前鼠标位于元素内的位置,但注意受子元素的影响
执行代码:
1. console.log('offsetX:', e.offsetX, ' - offsetY:', e.offsetY);
结果:
4.2 clientX和clientY
鼠标位于视口的x值和y值,(当前页面视口,若有滚动页面还是重新计算)
执行代码:
1. console.log('clientX:', e.clientX, ' - clientY:', e.clientY);
结果:
4.3 screenX和screenY
距离屏幕左上角的x和y(当前页面,,若有滚动页面还是重新计算)
执行代码:
1. console.log('screenX:', e.screenX, ' - screenY:', e.screenY);
结果:
4.4 pageX和pageY(IE不兼容)
距离整个网页的顶点的x和y
console.log("y值:",a.pageY);
结果:
五、阻止事件冒泡
高级浏览器使用:
方法:stopPropagation()
属性: cancelBubble = true cancelBubble 是否阻止冒泡 默认值为false
IE浏览器:
属性: cancelBubble = true cancelBubble 是否阻止冒泡 默认值为false
执行代码:
1. // 获得元素对象
2. var box = document.getElementById('box');
3. var carousel = document.getElementById('carousel');
4.
5. // 绑定事件
6. carousel.onclick = function() {
7. console.log('carousel');
8. }
9.
10. box.onclick = function(e) {
11. console.log('box');
12. // 事件的兼容
13. var e = e || event;
14.
15. // console.log(e);
16. if ( e.stopPropagation) {
17. // 高级浏览器
18. e.stopPropagation();
19. } else {
20. // IE浏览器
21. e.cancelBubble = true;
22. } }
**
六 阻止默认行为
**
a链接在点击的时候,会自动跳转,元素标签的默认行为。表单中的提交按钮,当其被点击的时候,就会提交表单的数据,页面出现滚动条的时候,这也是其默认行为。
DOM0级的方式,阻止默认行为 return false
执行代码:
1. <a href="http://www.baidu.com">百度一下</a>
2. <script>
3. // 获得元素
4. var a = document.getElementsByTagName('a')[0];
5.
6. // 绑定点击事件
7. a.onclick = function() {
8. alert('百度一下');
9. // DOM0级的方式,阻止默认行为
10. return false;
11. }
12. </script>
DOM2级阻止默认行为
高级浏览器:
e.preventDefault();
e.returnValue = false;
IE浏览器:
event.returnValue = false;
return false;
执行代码:
1. <a href="http://www.baidu.com">百度一下</a>
2. <script>
3. // 获得元素
4. var a = document.getElementsByTagName('a')[0];
5.
6. // 绑定点击事件
7. if (a.addEventListener) {
8. // 高级浏览器
9. a.addEventListener('click', function(e) {
10. alert('百度一下');
11. // 方法
12. e.preventDefault();// 阻止默认行为
13. // e.returnValue = false;
14. });
15. } else {
16. // IE浏览器
17. a.attachEvent('onclick', function() {
18. alert('百度一下');
19. // return false;
20. // 事件对象的属性
21. event.returnValue = false;
22. });
23. }
24. </script>
七、滚动条事件
7.1 onscroll
滚动条滚动的事件,
执行代码:
document.onscroll = function() {
console.log('我被触发了');
}
结果:
7.2 获得页面滚动条的卷动值
垂直方向:document.documentElement.scrollTop;
水平方向:document.documentElement.scrollLeft;
执行代码:
1 document.onscroll = function() {
2 console.log(document.documentElement.scrollTop);
3 console.log(document.documentElement.scrollLeft);
4
5 }
结果:
7.3IE中的透明度
高级浏览器: 设置透明度:opacity[0-1]
. IE中: filter:alpha[opacity(0-100)]
7.4,mousewheel事件
该事件触发的条件:当鼠标滚轮上下滚动的时候
兼容性:火狐不支持mousewheel事件,支持DOMMouseScroll
onmousewheel 事件在鼠标滚轮在元素上下滚动时触发。同样可以在触摸板上滚动或放大缩小区域时触发(如笔记本上的触摸板)。
onscroll 事件在元素滚动条在滚动时触发。滚动条必须存在,否则不会触发。无论以那种方式,只要滚动条滚动,事件都会触发。触发方式:鼠标滚轮,鼠标拖动,键盘上下键,或者设置的滚动函数,如 scrollTo,scrollBy,scrollByLines, scrollByPages。
当鼠标滚轮滚动时,onwheel事件先被触发,若滚动条滚动,则onscroll事件会相继被触发。
7.5,键盘事件
OnkeyDown 当键盘按下时触发
绑定方式:
document.onkeyDown = function(e){
Console.log
}
//按下键盘
document.onkeydown = function(e){
console.log("我被按下了");
}
//键盘抬起
document.onkeyup = function(e){
console.log("我被抬起了");
}
//有字符输入
document.onkeypress = function(e){
console.log("字符输入");
}
注意:如果给document添加onkeydown事件,直接添加即可,如果要给一个div元素添加onkeydown事件,要想办法让div获取焦点,获取焦点的方式是添加tabIndex属性,tabIndex的值决定了当按下tab键时候获取焦点的顺序。