绑定事件的两种方式/DOM事件的级别 我们在之前的一篇文章《04-JavaScript/22-DOM简介和DOM操作》中已经讲过事件的概念。这里讲一下绑定(注册)事件的两种方式,我们以onclick事件为例。
DOM0的写法:onclick 1 2 3 element.onclick = function ( ) { }
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <body > <button > 点我</button > <script > var btn = document .getElementsByTagName("button" )[0 ]; btn.onclick = function () { console .log("事件1" ); } btn.onclick = function () { console .log("事件2" ); } </script > </body >
点击按钮后,上方代码的打印结果:
我们可以看到,DOM对象.事件 = 函数
的这种绑定事件的方式:一个元素的一个事件只能绑定一个响应函数。如果绑定了多个响应函数,则后者会覆盖前者。
DOM2的写法:addEventListener(高版本浏览器) 1 2 3 element.addEventListener('click' , function ( ) { }, false );
参数解释:
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <body > <button > 按钮</button > <script > var btn = document .getElementsByTagName("button" )[0 ]; btn.addEventListener("click" , fn1); btn.addEventListener("click" , fn2); function fn1 () { console .log("事件1" ); } function fn2 () { console .log("事件2" ); } </script > </body >
点击按钮后,上方代码的打印结果:
我们可以看到,addEventListener()
这种绑定事件的方式:
一个元素的一个事件,可以绑定多个响应函数。不存在响应函数被覆盖的情况。执行顺序是 :事件被触发时,响应函数会按照函数的绑定顺序执行。
addEventListener()中的this,是绑定事件的对象。
addEventListener()
不支持 IE8 及以下的浏览器。在IE8中可以使用attachEvent
来绑定事件(详见下一小段)。
DOM2的写法:attachEvent(IE8及以下版本浏览器) 1 2 3 element.attachEvent('onclick' , function ( ) { });
参数解释:
参数1:事件名的字符串(注意,有on)
参数2:回调函数:当事件触发时,该函数会被执行
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <body > <button > 按钮</button > <script > var btn = document .getElementsByTagName('button' )[0 ]; btn.attachEvent('onclick' , function () { console .log('事件1' ); }); btn.attachEvent('onclick' , function () { console .log('事件2' ); }); </script > </body >
在低版本的IE浏览器上,点击按钮后,上方代码的打印结果:
我们可以看到,attachEvent()
这种绑定事件的方式:
兼容性写法 上面的内容里,需要强调的是:
既然这两个写法的this
不同,那么,有没有一种兼容性的写法可以确保这两种绑定方式的this是相同的呢?我们可以封装一下。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 <body > <button > 按钮</button > <script > var btn = document .getElementsByTagName('button' )[0 ]; myBind(btn , "click" , function () { alert(this ); }); /* * addEventListener()中的this ,是绑定事件的对象 * attachEvent()中的this ,是window * 需要统一两个方法this */ /* * 参数: * element 要绑定事件的对象 * eventStr 事件的字符串(不要on) * callback 回调函数 */ function myBind (element , eventStr , callback) { if(element.addEventListener){ element.addEventListener(eventStr , callback , false ); }else { /* * this 是谁,由调用方式决定 * callback.call(element) */ element.attachEvent("on" +eventStr , function () { callback.call(element); }); } } </script > </body >
事件对象 当事件的响应函数被触发时,会产生一个事件对象event
。浏览器每次都会将这个事件event
作为实参传进之前的响应函数。
这个对象中包含了与当前事件相关的一切信息。比如鼠标的坐标、键盘的哪个按键被按下、鼠标滚轮滚动的方向等。
获取 event 对象(兼容性问题) 所有浏览器都支持event对象,但支持的方式不同。如下。
(1)普通浏览器的写法是 event
。比如:
(2)ie 678 的写法是 window.event
。此时,事件对象 event 是作为window对象的属性保存的。
于是,我们可以采取一种兼容性的写法。如下:
1 event = event || window .event;
代码举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <!DOCTYPE html > <html > <head lang ="en" > <meta charset ="UTF-8" > <title > </title > </head > <body > <script > document .onclick = function (event ) { event = event || window .event; console .log(event); console .log(event.timeStamp); console .log(event.bubbles); console .log(event.button); console .log(event.pageX); console .log(event.pageY); console .log(event.screenX); console .log(event.screenY); console .log(event.target); console .log(event.type); console .log(event.clientX); console .log(event.clientY); } </script > </body > </html >
event 属性 event 有很多属性,比如:
由于pageX 和 pageY的兼容性不好,我们可以这样做:
鼠标在页面的位置 = 滚动条滚动的距离 + 可视区域的坐标。
Event举例 举例1:使 div 跟随鼠标移动 代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 <!DOCTYPE html > <html > <head > <meta charset ="UTF-8" /> <title > </title > <style type ="text/css" > #box1 { width: 100px; height: 100px; background-color: red; /* * 开启box1的绝对定位 */ position: absolute; } </style > <script type ="text/javascript" > window .onload = function ( ) { /* * 使div可以跟随鼠标移动 */ var box1 = document .getElementById("box1" ); document .onmousemove = function (event ) { event = event || window .event; var pagex = event.pageX || scroll().left + event.clientX; var pagey = event.pageY || scroll().top + event.clientY; box1.style.left = pagex + "px" ; box1.style.top = pagey + "px" ; }; }; function scroll () { return { left: window .pageYOffset || document .body.scrollTop || document .documentElement.scrollTop, right: window .pageXOffset || document .body.scrollLeft || document .documentElement.scrollLeft }; } </script > </head > <body style ="height: 1000px;width: 2000px;" > <div id ="box1" > </div > </body > </html >
举例2:获取鼠标距离所在盒子的距离 关键点:
1 鼠标距离所在盒子的距离 = 鼠标在整个页面的位置 - 所在盒子在整个页面的位置
代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 <!DOCTYPE html > <html > <head lang ="en" > <meta charset ="UTF-8" > <title > </title > <style > .box { width: 300px; height: 200px; padding-top: 100px; background-color: pink; margin: 100px; text-align: center; font: 18px/30px "simsun"; cursor: pointer; } </style > </head > <body > <div class ="box" > </div > <script src ="animate.js" > </script > <script > var div = document .getElementsByTagName("div" )[0 ]; div.onmousemove = function (event) { event = event || window .event; var pagex = event.pageX || scroll().left + event.clientX; var pagey = event.pageY || scroll().top + event.clientY; var targetx = pagex - div.offsetLeft; var targety = pagey - div.offsetTop; this .innerHTML = "鼠标在盒子中的X坐标为:" + targetx + "px;<br>鼠标在盒子中的Y坐标为:" + targety + "px;" } </script > </body > </html >
实现效果:
举例3:商品放大镜 代码实现:
(1)index.html:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 <!DOCTYPE html > <html > <head lang ="en" > <meta charset ="UTF-8" > <title > </title > <style > * { margin: 0; padding: 0; } .box { width: 350px; height: 350px; margin: 100px; border : 1px solid #ccc ; position: relative; } .big { width: 400px; height: 400px; position: absolute; top: 0; left: 360px; border : 1px solid #ccc ; overflow: hidden; display: none; } .mask { width: 175px; height: 175px; background : rgba (255, 255, 0, 0.4 ); position: absolute; top: 0; left: 0; cursor: move; display: none; } .small { position: relative; } img { vertical-align: top; } </style > <script src ="tools.js" > </script > <script > window .onload = function ( ) { var box = document .getElementsByClassName("box" )[0 ]; var small = box.firstElementChild || box.firstChild; var big = box.children[1 ]; var mask = small.children[1 ]; var bigImg = big.children[0 ]; small.onmouseenter = function () { show(mask); show(big); } small.onmouseleave = function () { hide(mask); hide(big); } small.onmousemove = function (event) { event = event || window .event; var pagex = event.pageX || scroll().left + event.clientX; var pagey = event.pageY || scroll().top + event.clientY; var x = pagex - box.offsetLeft - mask.offsetWidth / 2 ; var y = pagey - box.offsetTop - mask.offsetHeight / 2 ; if (x < 0) { x = 0; } if (x > small.offsetWidth - mask.offsetWidth) { x = small.offsetWidth - mask.offsetWidth; } if (y < 0) { y = 0; } if (y > small.offsetHeight - mask.offsetHeight) { y = small.offsetHeight - mask.offsetHeight; } console .log(small.offsetHeight); mask.style.left = x + "px" ; mask.style.top = y + "px" ; var bili = bigImg.offsetWidth / small.offsetWidth; var xx = bili * x; var yy = bili * y; bigImg.style.marginTop = -yy + "px" ; bigImg.style.marginLeft = -xx + "px" ; } } </script > </head > <body > <div class ="box" > <div class ="small" > <img src ="images/001.jpg" alt ="" /> <div class ="mask" > </div > </div > <div class ="big" > <img src ="images/0001.jpg" alt ="" /> </div > </div > </body > </html >
(2)tools.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 function show (ele ) { ele.style.display = "block" ; } function hide (ele ) { ele.style.display = "none" ; } function scroll ( ) { if (window .pageYOffset != null ) { return { left: window .pageXOffset, top: window .pageYOffset } } else if (document .compatMode === "CSS1Compat" ) { return { left: document .documentElement.scrollLeft, top: document .documentElement.scrollTop } } return { left: document .body.scrollLeft, top: document .body.scrollTop } }
效果演示:
我的公众号 想学习更多技能 ?不妨关注我的微信公众号:千古壹号 (id:qianguyihao
)。
扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外: