JavaScript之事件

JavaScript之事件

1. 概念


事件流描述的是从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序。

事件就是用户或浏览器自身执行的某种动作。诸如click(点击)、load(加载)、mouseover(鼠标悬停)。

事件处理程序响应某个事件的函数就叫事件处理程序(或事件侦听器)。

2. 事件的触发有四个阶段


        a. document 往事件触发地点,捕获前进,遇到相同注册事件立即触发执行
        b. 到达事件位置,触发事件
        c. 事件触发地点往 document 方向,冒泡前进,遇到相同注册事件立即触发
        d. 事件的默认行为

举例:
<html>  
	<head>
		<style>
			#div1 {
				width:300px;
				height:300px;
				background-color:#16a085;
			}

			#div2 {
				width:200px;
				height:200px;
				background-color:gray;
				margin:25px auto;
			}

			a {
				text-decoration: none;
			}
		</style>
	</head>
	<body>  
	    <div id="div1">  
	        <h3>#div1</h3>  
	        <div id="div2">  
	            <h3>#div2</h3>   
	            <a href="https://www.baidu.com/">a标签默认行为</a>
	        </div>  
	    </div>  

	    <script>  
		    var a = document.getElementById('div1');  
		    var b = document.getElementById('div2');  

		    /*除IE8及之前版本外的所有浏览器*/
		    a.addEventListener('click', alertCaptureID, true);  
		    b.addEventListener('click', alertCaptureID, true);  

		    a.addEventListener('click', alertBubbleID, false);  
		    b.addEventListener('click', alertBubbleID, false);  
		  
		    function alertCaptureID() {  
		        console.log("Capture: " + this.id);  
		    }  

		    function alertBubbleID() {
		        console.log("Bubble: " + this.id);  
		    }
		</script>  
	</body>  
</html>  
如果点击是div2不是a标签的话,我们会看到如下图示结果:

如果点击的是a标签,不仅会上面提示的结果,最后还会跳转到baidu的搜索页面,这里最后的页面跳转就是a标签的默认行为。

这里与其说是默认行为,个人感觉应该是HTML标签的语义,和javascript的关系不大,a标签的语义就是一个指向其href属性的链接。即使禁用浏览器的javascript,a标签依然可以跳转。


3. 注册事件处理程序


(1). 设置JavaScript对象属性为事件处理程序

通过javaScript指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序的属性。这种为事件处理程序赋值的方法是在第四代Web浏览器中出现的,而且至今仍然为所有现在浏览器支持。原因主要有两点: 1.简单 2.具有跨浏览器优势。

每个元素(window和document)都有自己的事件处理程序属性,这些属性通常全部小写,例如 onclick, onmousedown. 
var btn = document.getElementById('mybtn');
btn.onclick = function () {
  alert('click');
}

(2) 设置HTML标签属性为事件处理程序

用于设置的文档元素事件处理程序属性(property)也能换成对应HTML标签的属性(attribute)。这也是最基本的一种方式。如果这样做,这段代码应该是事件处理程序函数的主体,而不是完整的函数声明,也就是说,html事件处理程序代码不应该使用大括号包围且使用function关键字作为前缀。
<button οnclick="alert('click event')"><button>


(3) addEventListener

在除IE8及以前版本外的所有浏览器支持的标准事件模型中,任何能成为时间目标的对象-这些对象包括Window对象,Document对象和所有文档元素都定义了一个名叫addEventListener()的方法,使用这个方法可以为事件目标注册处理程序。

addEventListener()接受三个参数
第一个参数是要注册处理程序的事件类型,这个事件类型(或名字)是字符串,但它不应该包括用于设置事件处理程序属性的前缀“on”。
第二个参数是指定类型的时间发生时应该调用的函数。
第三个参数是布尔值,这个值决定以何种方式进行事件传递,默认是为false,注册捕获事件的处理程序,如果是true,那么函数将注册为捕获事件处理程序。

具体的例子在上面的例子在上面已经提及到。

需要注意的是: 可以通过多次调用addEventListener为同一个对象注册同一个事件类型的多个处理程序。调用顺序会按照注册的顺序进行调用。如下面的图示:

使用相同的参数在同一个对象上多次掉用addEventListener是没用的的,处理程序仍然只会注册一次。

相对addEventListener()的是removeEventListener()方法,这个方法用于删除事件处理程序函数。
element.removeEventListener('click', alertCaptureID, true);  
element.removeEventListener('click', alertBubbleID, false);  

(4) attachEvent()

IE9之前的IE不支持addEventListener,removeEventListener。IE5及以后版本定义了类似的方法addachEvent,和detachEvent.因为IE事件模型不支持事件捕获,所以addachEvent,和detachEvent要求只有两个参数:事件类型和处理程序函数

IE方法的第一个参数使用了代“on”前缀的事件处理程序属性名,而非没有前缀的事件类型。

attachEvent()允许相同的参数注册事件处理函数多次,并且调用次数和注册次数相同
<html>  
	<head>
		<style>
			#div1 {
				width:300px;
				height:300px;
				background-color:#16a085;
			}

			#div2 {
				width:200px;
				height:200px;
				background-color:gray;
				margin:25px auto;
			}

			a {
				text-decoration: none;
			}
		</style>
	</head>
	<body>  
	    <div id="div1">  
	        <h3>#div1</h3>  
	        <div id="div2">  
	            <h3>#div2</h3>   
	        </div>  
	    </div>  

	    <script>  
		    var a = document.getElementById('div1');  
		    var b = document.getElementById('div2');  

		    /*除IE8及之前版本外的所有浏览器*/
		    a.attachEvent('onclick', namespace1AlertBubbleID.bind(a));  
		    b.attachEvent('onclick', namespace1AlertBubbleID.bind(b));  
		
		    a.attachEvent('onclick', namespace1AlertBubbleID.bind(a));  
		    b.attachEvent('onclick', namespace1AlertBubbleID.bind(b));  

		    function namespace1AlertBubbleID(event) {
		        console.log("Bubble: " + this.id);  
		    }
		</script>  
	</body>  
</html>  



(5) 跨浏览器时间注册

var EventUtil =  {
        addEventListener: function (element, type, callback) {  //注册事件,因为浏览器的兼容性考虑,注册事件一般都是注册在事件的捕获阶段
            if (element.addEventListener) {
                element.addEventListener(type, callback, false);
            } else if (element.attachEvent) {
                element.attachEvent('on' + type, callback);
            } else {
                element['on' + type] = callback;
            }
        }, 
        getEvent:function(event){           //获取事件
            return event||window.event;
        },                
        getTarget:function(event){           //获取事件的触发目标
            return event.target||event.srcElement;
        },
        preventDefault:function(event){        //阻止事件的默认行为
            event.preventDefault?event.preventDefault():event.returnValue=false;
        },
        stopPropagation:function(event){          //阻止事件冒泡
            event.stopPropagation?event.stopPropagation:event.cancelBubble=true;
        },
        removeEventListener: function(element, type, callback) {  //撤销事件
            if (element.removeEventListener) {
                element.removeEventListener(type, callback, false);
            } else if (element.detachEvent) {
                element.detachEvent('on' + type, callback);
            } else {
                element['on' + type] = null;
            }
        }
    };



4. 事件处理程序的调用


(1) event对象

非IE浏览器使用event参数来构造函数,而IE在构造函数时没有要求参数,这个时候我们可以通过window.event调用。
event = event || window.event;


(2) 事件处理程序的运行环境

使用addEventListener注册程序处理程序使用事件目标作为它们的this值,但是对于attachEvent来讲是不对的;使用attachEvent()注册的处理程序作为函数调用,它们的this值是全局对象,如果你对上面的代码看的仔细的话,应该注意说道attchEvent的时候我已经用了bind来实现了this的问题,也可以是用call,或者apply实现。


5. 调用顺序


通过设置对象属性或者HTML属性注册的处理程序一直优先调用。

使用addEventListener()注册的处理程序按照注册顺序调用。

使用attachEvent()注册的处理顺序可能按照任何顺序调用。


6. 事件取消


(1) 取消调用对象的默认事件

a.addEventListener('click', cancelHandler, true);  

function cancelHandler() {  
    console.log("Capture: " + this.id);  

    if (event.preventDefault) {
    	event.preventDefault(); //标准技术
    }

    if (event.returnValue) {
    	event.returnValue = false; //IE
    }

    return false;  //没有起到作用,但是直接在html属性或者js属性上是可以的
}  

(2) 取消事件传播

对于addEventListener()的浏览器中,可以调用时间对象的一个stopPropagation()方法阻止事件的继续传播。
对于attachEvent可以使用cancelBubble属性,将这个属性设置为true能阻止事件进一步传播。

Note: 阻止事件传播但是不会阻止在其同一对象定义了的其他处理程序。

stopImmediatePropagation
这个方法阻止了任何其他对象的事件传播,但也阻止了在相同对象上注册的任何其他的时间处理程序的调用,这个具体的使用还需要在哥哥浏览器进行测试。

5. 文档加载

window.onload = function(){};
当页面DOM对象加载完毕,web浏览器能够运行JS时,此方法即被触发。

$(document).ready();
当web页面以及其附带的资源文件,如CSS,Scripts,图片等,加载完毕后执行此方法。
常用于检测页面(及其附带资源)是否加载完毕。 

调用顺序是window.onload = function(){}; >> $(document).ready(); 

他们之间的区别

执行时间 
        window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行。
        $(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕。 

编写个数不同
         window.onload不能同时编写多个,如果有多个window.onload方法,只会执行一个
         $(document).ready()可以同时编写多个,并且都可以得到执行

简化写法
         window.onload没有简化写法
         $(document).ready(function(){})可以简写成$(function(){});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值