JavaScript高级程序设计——第十三章(事件)

一.前言

本章主要介绍JS中的事件,包括事件的一般写法和兼容浏览器的写法。事件的种类等。由于篇幅有限,IE中很多特性就不在本文介绍,很多平时用不到的事件也就请看书啦。

二.事件处理程序

  1. DOM0级事件处理程序

    每个程序都有自己的事件处理程序,例如onclick。

    var btn = document.getElementById('myBtn')
    btn.onclick  = function(){
    	alert(this.id)  //myBtn
    }
    

    已这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。
    可以通过btn.onclick = null删除事件处理程序。

  2. DOM2级事件处理程序
    “DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。包含三个参数:最后的布尔值参数如果是false,表示在捕获阶段调用事件处理程序。参数为true,表示在冒泡阶段调用事件处理程序。

    var btn = document.getElementById('myBtn')
    
    btn.addEventListener('click',function(){
    	alert(this.id)
    },false)
    
    btn.addEventListener('click',function(){
    	alert('hello')
    },false)
    

    使用DOM2级方法添加事件处理程序的主要好处是可以添加多个时间处理程序。这里为事件添加了两个事件处理程序。这两个事件处理程序会按照添加它们的顺序触发。

    通过addEventListener()添加的事件只能使用removeEventListener()来移除。移除时传入的参数与添加处理程序时使用的参数相同。所以使用addEventListener()添加的匿名函数将无法移除

    var btn = document.getElementById('myBtn')
    
    btn.addEventListener('click',function(){
    	alert(this.id)
    },false)
    
    btn.removeEventListener('click',function(){
    	alert(this.id)
    },false)  //无效,因为是匿名函数
    
    var btn = document.getElementById('myBtn')
    var handle = function(){
    	alert(this.id)
    }
    btn.addEventListener('click',handle,false)
    btn.removeEventListener('click',handle,false)  //有效删除
    
  3. IE事件处理程序
    IE实现与DOM类似的两个方法:attachEvent(),detachEvent()。
    attachEvent()与addEventListener()的不同点是当定义多个方法时,是从后往前执行

  1. 跨浏览器的事件处理程序

    我们定义一个对象,里面定义添加和删除事件的两个方法,用于适应所有浏览器。

    var EventUtil = {
    	addHandler:function(element,type,handler){
    		if(element.addEventListener){
    			element.addEventListener(type,handler,false)
    		}else if(element.attachEvent){
    			element.attachEvent('on'+type,handler)
    		}else {
    			element['on'+type] = handler
    		}
    	},
    	removeHandler:function(element,type,handler){
    		if(element.removeEventListener){
    			element.removeEventListener(type,handler,false)
    		}else if(element.attachEvent){
    			element.detachEvent('on'+type,handler)
    		}else {
    			element['on'+type] = null
    		}
    	}
    }
    

三.事件对象

  1. DOM中的事件对象

    var btn = document.getElementById('myBtn')
    btn.onclick = function(event){
    	alert(event.type)  //click
    }
    
  2. IE中的事件对象

    var btn = document.getElementById('myBtn')
    btn.onclick = function(event){
    	var event = window.event
    	alert(event.type)  //click
    }
    
  3. 跨浏览器的事件对象

    var EventUtil = {
    	addHandler:function(element,type,handler){
    		if(element.addEventListener){
    			element.addEventListener(type,handler,false)
    		}else if(element.attachEvent){
    			element.attachEvent('on'+type,handler)
    		}else {
    			element['on'+type] = handler
    		}
    	},
    	getEvent:function(event){
    		return event ? event : window.event	
    	},
    	getTarget:function(event){
    		return event.target || event.srcElement
    	},
    	//取消事件的默认行为
    	preventDefault:function(event){
    		if(event.preventDefalut){
    			event.preventDefalut()
    		}else {
    			event.returnValue = false
    		}
    	},
    	removeHandler:function(element,type,handler){
    		if(element.removeEventListener){
    			element.removeEventListener(type,handler,false)
    		}else if(element.attachEvent){
    			element.detachEvent('on'+type,handler)
    		}else {
    			element['on'+type] = null
    		}
    	},
    	//阻止事件的捕获和冒泡
    	stopPropagation:function(event){
    		if(event.stopPropagation){
    			event.stopPropagation()
    		}else {
    			event.cancelBubble = true
    		}
    	}
    }
    

四.事件类型

‘DOM3级事件’规定了几种类型的事件:焦点事件,鼠标事件,滚轮事件等。需要用到的时候查资料即可,常见了我们都知道,在这里我就列举几个不常见但是会用到的事件。

  1. UI事件

    • load:当页面完全加载后,就会触发。
    EventUtil.addHandler(window,'load',function(event){
    	alert('loaded')
    })
    
    • unload:这个事件在文档被完全卸载后触发。
    	EventUtil.addHandler(window,'unload',function(event){
    		alert('unloaded')
    	})
    	```
    
    
    
  2. 键盘与文本事件
    有三个键盘事件:

    • keydown:当用户按下键盘上的任意键时触发,如果按住不放的话,会重复触发此事件。

    • keypress:当用户按下键盘上的字符键时触发,如果按住不放的话,会重复触发此事件。

    • keyup:当用户释放键盘上的键时触发。

    • textInput:‘DOM3级事件’新增了一个新事件,当用户在可编辑区域中输入字符时,就会触发这个事件。这个用于替代keypress,但是两个有两个不同。一是任何可以获得焦点的元素都可以触发keypress,但只有可编辑区域才能触发textInput。二是textInput只有用户按下能够输入实际字符的键时才能触发,keypress在按下能用印象文本显示的键时就能触发(如退格键)。

    虽然所有元素都支持上述三个事件,但只有在用户通过文本框输入文本时才最常用到
    在用户按下一个键盘上的字符键时,首先触发keydown,紧跟着时keypress,最后释放时是keyup。keydown和keypress都是在文本框发生变化之前被触发的;keyup是在文本框已经发生变化之后触发。

  • 键码:在发生keydown和keyup事件时,event对象的keyCode属性会包含一个代码。DOM和IE的event对象都支持keyCode属性。

    var textbox = document.getElementById('myText')
    EventUtil.addHandler(textbox,'keyup',function(event){
    		event = EventUtil.getEvent(event)
    		alert(event.keyCode)
    	})
    
  • 字符编码:发生keypress事件意味按下的键会影响到屏幕中文本的显示。DOM3级事件不再包含charCode属性,而是包含两个新属性:key和char。
    key属性是为了取代keyCode而新增的,它的值是一个字符串。按下某个字符键时,key的值就是相应的文本字符(如:S,M)。按下非字符按键时,key的值时相应的按键名(如:‘shift’,‘esc’)。
    char属性在按下字符按键时与key值相同,按下非字符按键时为null。

五.内存和性能

  1. 事件委托
    利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。例如:click事件会冒泡到document层次,也就是说,我们可以为整个页面指定一个onclick事件处理程序,而不是给每个可单击的元素分别添加事件处理程序。

    <ul id = 'myLinks'>
    	<li id = 'doit'> do </li>
    	<li id = 'goit'> go </li>
    	<li id = 'kissit'> kiss </li>
    </ul>
     
     var list = docuemnt.getElementById('myLinks')
     EventUtil.addHandler(list,'click',function(event){
    	event = EventUtil.getEvent(event)
    	var target = EventUtil.getTarget(event)
    	
    	switch(target.id){
    		case 'doit':
    			document.title = 'I do it'
    			break;
    		case 'goit':
    			document.title = 'I will go '
    			break;
    		case 'kissit':
    			document.title = 'kiss u'
    			break;
    	}
    })
    

    由于所有的列表项都是这个元素的子节点,而且它们的事件都会冒泡,所以单击事件最终都会被这个函数处理。这种写法可以让内存占用更少,所有用到按钮的事件都可以采用事件委托技术。

  2. 移除事件处理程序

    <div id = 'myDiv'>
    	<input type = 'button' value = 'click me' id = 'myBtn'>
    </div>
    
    <script>
    	var btn = document.getElementById('myBtn')
    	btn.onclick = function(){
    		......
    		docuemnt.getElementById('myDiv').innerHtml = 'hello!'
    	}
    

    上述我们先使用了input标签中的事件,然后将div中的文本变为字符串‘hello’。但是事件处理程序仍然和按钮保持联系,所以会有一系列的麻烦,我们在确定某个元素将被删除,最好手工移除事件处理程序。

    btn.onclick = function(){
    	......
    	btn.onclick = null  //移除事件处理程序
    	docuemnt.getElementById('myDiv').innerHtml = 'hello!'
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值