<input type="button" value="按钮" onclick="alert('Lee');" />//注意单双引号脚本模型
var input = document.getElementsByTagName('input')[0];//得到input对象input.onclick = function () {//匿名函数执行 alert('Lee');};事件对象
事件对象,我们一般称作为event对象,这个对象是浏览器通过函数把这个对象作为参数传递过来的。input.onclick = function (evt) { var e = evt || window.event;//实现跨浏览器兼容获取event对象 alert(e);};直接接收event对象,是W3C的做法,早期IE不支持,IE自己定义了一个event对象,直接在window.event获取即可鼠标事件
通过鼠标事件对象可以获取到鼠标按钮信息和屏幕坐标获取等可视区及屏幕坐标<!DOCTYPE html><head> <meta charset="UTF-8"> <title>Document</title></head><body> <div style="width:300px;margin-left:100px;height:300px;background-color: red"></div></body><script type="text/javascript"> document.getElementsByTagName("div")[0].onclick = function (evt) { var e = evt || window.event; console.log(e.clientX + ',' + e.clientY); console.log(e.screenX + ',' + e.screenY); console.log(e.offsetX + ',' + e.offsetY); console.log(e.pageX + ',' + e.pageY); };</script></html>键盘事件
键码
在发生keydown和keyup事件时,event对象的keyCode属性中会包含一个代码,与键盘上一个特定的键对应。对数字字母字符集,keyCode属性的值与ASCII码中对应小写字母或数字的编码相同。字母中大小写不影响。<script type="text/Javascript"> document.onkeydown = function (evt) { console.log(evt.keyCode);//按任意键,得到相应的keyCode };</script>不同的浏览器在keydown和keyup事件中,会有一些特殊的情况:在Firefox和Opera中,分号键时keyCode值为59,也就是ASCII中分号的编码;而IE和Safari返回186,即键盘中按键的键码。字符编码
Firefox、Chrome和Safari的event对象都支持一个charCode属性,这个属性只有在发生keyPRess事件时才包含值,而且这个值是按下的那个键所代表字符的ASCII编码。此时的keyCode通常等于0或者也可能等于所按键的编码。IE和Opera则是在keyCode中保存字符的ASCII编码。function getCharCode(evt) { var e = evt || window.event; if (typeof e.charCode == 'number') { return e.charCode; } else { return e.keyCode; }}PS:可以使用String.fromCharCode()将ASCII编码转换成实际的字符。W3C与IE事件模型
事件对象属性
function getTarget(evt) { var e = evt || window.event; return e.target || e.srcElement;//兼容得到事件目标DOM对象}document.onclick = function (evt) { var target = getTarget(evt); alert(target);};target和currentTarget的区别
currentTarget始终是监听事件者,而target是事件的真正发出者<!DOCTYPE html><head> <meta charset="UTF-8"> <title>Document</title></head><body> <div id="outdiv" style="width:300px;margin-left:100px;height:300px;background-color: red"> <div id="indiv" style="width:100px;height: 100px;background-color: blue;"></div> </div></body><script type="text/javascript"> document.getElementById("outdiv").onclick = function (evt) { var e = evt || window.event; console.log(e.currentTarget); console.log(e.target); };</script></html>蓝色框表示点击蓝色区域时的输出,红色框表示点击红色区域时的输出。事件流
事件流是描述的从页面接受事件的顺序,当几个都具有事件的元素层叠在一起的时候,那么你点击其中一个元素,并不是只有当前被点击的元素会触发事件,而层叠在你点击范围的所有元素都会触发事件。事件流包括两种模式:冒泡和捕获。事件冒泡,是从里往外逐个触发。事件捕获,是从外往里逐个触发。那么现代的浏览器默认情况下都是冒泡模型,而捕获模式则是早期的Netscape默认情况。而现在的浏览器要使用DOM2级模型的事件绑定机制才能手动定义事件流模式。在阻止冒泡的过程中,W3C和IE采用的不同的方法,那么我们必须做一下兼容。function stopPro(evt) { var e = evt || window.event; window.event ? e.cancelBubble = true : e.stopPropagation(); }事件绑定
传统事件绑定的问题
前面定义的事件函数会被后面定义的事件函数覆盖window.onload = function () {//第一组程序项目或第一个JS文件 alert('Lee');};window.onload = function () {//第二组程序项目或第二个JS文件,会覆盖上面的函数 alert('Mr.Lee');};解决覆盖问题<script type="text/javascript"> function addEvent(obj, type, fn) {//取代传统事件处理函数 var saved = null;//保存每次触发的事件处理函数 if (typeof obj['on' + type] == 'function') {//判断是不是事件 saved = obj['on' + type];//如果有,保存起来 } obj['on' + type] = function () { if (saved) saved();//执行上一个 fn.call(this);//执行函数,把this传递过去 }; } var box = document.getElementById("outdiv"); addEvent(box,"click",function(){ console.log("fun1"); }); addEvent(box,"click",function(){ console.log("fun2"); }); addEvent(box,"click",function(){ console.log("fun3"); });</script>W3C事件处理函数
“DOM2级事件”定义了两个方法,用于添加事件和删除事件处理程序的操作:addEventListener()和removeEventListener()。所有DOM节点中都包含这两个方法,并且它们都接受3个参数;事件名、函数、冒泡或捕获的布尔值(true表示捕获,false表示冒泡)。window.addEventListener('load', function () { alert('Lee');}, false);window.addEventListener('load', function () { alert('Mr.Lee');}, false);W3C的现代事件绑定比我们自定义的好处就是:1.不需要自定义了;2.可以屏蔽相同的函数;3.可以设置冒泡和捕获。window.addEventListener('load', init, false);//第一次执行了window.addEventListener('load', init, false);//第二次被屏蔽了IE事件处理函数
IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。这两个方法接受相同的参数:事件名称和函数。在使用这两组函数的时候,先把区别说一下:1.IE不支持捕获,只支持冒泡;2.IE添加事件不能屏蔽重复的函数;3.IE中的this指向的是window而不是DOM对象。4.在传统事件上,IE是无法接受到event对象的,但使用了attchEvent()却可以,但有些区别。函数重复问题<script type="text/javascript"> var box = document.getElementById("outdiv"); box.attachEvent('onclick', init); box.attachEvent('onclick', init); function init(){ alert("init") }</script>this问题<script type="text/javascript"> var box = document.getElementById("outdiv"); box.attachEvent('onclick', function () { alert(this === window);//this指向的window }); box.attachEvent('onclick', function () { toBlue.call(box);//可以把this直接call过去 });</script>event对象传参<script type="text/javascript"> var box = document.getElementById("outdiv"); box.onclick = function (evt) { alert(evt);//undefined }; //定义了传统事件后,还可以继续绑定事件,不会覆盖 box.attachEvent('onclick', function (evt) { alert(evt);//object alert(evt.type);//click });</script>PS:IE中的事件绑定函数attachEvent()和detachEvent()可能在实践中不去使用,有几个原因:1.IE9就将全面支持W3C中的事件绑定函数;2.IE的事件绑定函数无法传递this;3.IE的事件绑定函数不支持捕获;4.同一个函数注册绑定后,没有屏蔽掉;5.有内存泄漏的问题。至于怎么替代,我们将在以后的项目课程中探讨。事件对象的其他补充
relatedTarget属性
在W3C提供了一个属性:relatedTarget;这个属性可以在mouSEOver和mouseout事件中获取从哪里移入和从哪里移出的DOM对象。<script type="text/javascript"> var box = document.getElementById("indiv"); box.onmouseover = function (evt) {//鼠标移入box console.log(evt.relatedTarget);//获取移入box最近的那个元素对象 } box.onmouseout = function (evt) {//鼠标移出box console.log(evt.relatedTarget);//获取移出box最近的那个元素对象 }</script>IE提供了两组分别用于移入移出的属性:fromElement和toElement,分别对应mouseover和mouseout。<script type="text/javascript"> var box = document.getElementById("indiv"); box.onmouseover = function (evt) {//鼠标移入box console.log(window.event.fromElement.tagName);//获取移入box最近的那个元素对象span } box.onmouseout = function (evt) {//鼠标移入box console.log(window.event.toElement.tagName);//获取移入box最近的那个元素对象span }</script>组织浏览器默认行为
<script type="text/javascript"> link.onclick = function () { alert('Lee'); return false;//直接给个假,就不会跳转了。 }; link.onclick = function (evt) { evt.preventDefault();//W3C,阻止默认行为,放哪里都可以 alert('Lee'); }; link.onclick = function (evt) { //IE,阻止默认行为 window.event.returnValue = false; alert('Lee'); };</script>阻止右键菜单
<script type="text/javascript"> document.addEventListener("contextmenu",function(event){ event.preventDefault(); console.log("hehe"); },false);</script>卸载前事件:beforeunload
用beforeunload事件,在某些浏览器上(chrome、ie、firefox)可以监听到浏览器关闭操作,能够在关闭之前,弹出一个对话框,让用户选择是否关闭<script type="text/javascript"> window.addEventListener("beforeunload", function (e) { var confirmationMessage = '确定离开此页吗?本页不需要刷新或后退'; (e || window.event).returnValue = confirmationMessage; // Gecko and Trident return confirmationMessage;// Gecko and WebKit });</script>
新闻热点
疑难解答