咱們經過下面一個實例,進行說明。javascript
<body>
<h1>Event Flow</h1>
<ul id="nav">
<li><a href="../image-load/image-load.html">Image-Load</a></li>
<li><a href="../click/click.html">Click</a></li>
<li><a href="../move/move.html">Move</a></li>
<li><a href="../address/address.html">Address Form</a></li>
<li><a href="../follow/follow.html">Follow</a></li>
<li><a href="../flow/flow.html">Flow</a></li>
<li><a href="../keys/keys.html">Key Press</a></li>
<li><a href="../load/load.html">addLoadEvent</a></li>
</ul>
<div id="content">
<ul id="list1">
<li>
<p>List 1 </p>
<ul id="list2">
<li>
<p>List 2 </p>
<ul id="list3">
<li>
<p>List 3 </p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul id="list4">
<p>List 4 </p>
</ul>
</div>
</body>
提供的CSS樣式經過設置第三個嵌套列表的位置,使其在視覺上處於祖先元素以外、且位於第四個列表之上html
#list1 { height:80px;
} #list2 { margin-top: 10px; height:20px;
} #list3 { position:absolute; top:190px; left:150px;
} #list4 { margin-top:10px; height:100px;
}
//主要任務就是修改被單擊元素的屬性
addEvent(window,'load',function(){ //爲了演示問題所在,使用一個修改後的addEvent方法
function modifiedAddEvent(obj,type,fn) { if (obj.addEventListener) { //W3C方式
/*這個方法在第一章的addEvent()方法基礎上進行修改, 修改後啓用了捕獲階段而取消了冒泡階段*/ obj.addEventListener(type,fn,true); } else if (obj.attachEvent) { //ms 方式
obj['e'+type+fn]=fn; obj[type+fn]=function(){obj['e'+type+fn](window.event);} obj.attachEvent('on'+type,obj[type+fn]); } else { return false; } } var counter=0; //取得無序列表
var lists=document.getElementsByTagName('ul'); for (var i = 0 ;i<lists.length ;i++ ) { //註冊單機事件偵聽器
modifiledAddEvent(lists[i],'click',function(){ //向段落添加表示捕獲單機事件前後順序的數字
var append=document.createTextNode(':'+counter++); this.getElementsByTagName('p')[0].appendChild(append); //修改類名以突出顯示被單擊的元素
this.className='clicked'; }); } });
老實說,我如今又到了沒有耐心的時刻了,看書看不下去。因此上文看的也是迷迷糊糊。可是想到,我必定要堅持下去,我不能浮躁。要不我今天先休息。明天繼續學習。//我仍是客服了我浮躁的心裏,靜下心來看了看前面的代碼,而且理解了,這樣能夠繼續看下去了java
之因此點擊list3的時候12都作出了相應的變化,是由於當你單擊list3的時候,也單擊了其祖先列表node
阻止冒泡瀏覽器
function stopPropagation(eventObject) { eventObject=eventObject||getEventObject(eventObject); if (eventObject.stopPropagation) { eventObject.stopPropagation(); } else { eventObject.cancelBubble=true; } } window['ADS']['stopPropagation']=stopPropagation;
阻止事件app
function preventDefault(eventObject) { eventObject=eventObject||getEventObject(eventObject); if (eventObject.preventDefault) { eventObject.preventDefault(); } else { eventObject.returnValue=false; } } window['ADS']['preventDefault']=preventDefault;
2、註冊事件ide
<a href="www.baidu.com" onclick="window.opent(this.href);return false;">http://baidu.com/</a>
function addEvent(obj,type,fn) { if(obj.attachEvent) { obj['e'+type+fn]=fn; obj[type+fn]=function(){obj['e'+type+fn](window.event);} obj.attachEvent('on'+type+obj[type+fn]); } else obj.addEventListner(type,fn,false); }
window.onload=function() { var anchor=document.getElementById('example'); anchor.onclick=function() { //單擊事件時候執行代碼
} }
Microsoft特有的事件模型函數
function eventListener() { //響應單擊事件的代碼
} window.attachEvent('onload',function(){ var link = document.getElementById('example'); //增長事件
link.attachEvent('onclick',eventListener); //去除事件
//link.detachEvent('onclick',eventListener);
});
//w3c事件註冊
function eventListener() { //響應單擊事件的代碼
} window.addEventListener('load',function(W3CEvent)) { var link = document.getElementById('example'); link.addEventListener('click',eventListener,false); },false); //移除事件監聽器
link.removeEventListener('click',eventListener,false);
不管那種事件註冊方法,load事件會一直等到全部圖像所有加載完以後才被調用,要解決這問題,咱們要在ADS庫中添加以下方法學習
function addLoadEvent(loadEvent,waitForImage) { if (!isCompatible()) { return false; } //若是等標記是ture則使用常規的添加事件的方法
if (waitForImage) { return addEvent(window,'load',loadEvent); } //不然使用一下不一樣的方式包裝loadEvent()方法
//一邊爲this關鍵字指定正確的內容,同事確保事件不會被執行兩次
var init = function() { //若是這個函數已經被調用了,則返回
if (argument.callee.done) { return; } //標記這個函數,以便檢查他是否運行過
arguments.callee.done=true; //在document的環境中運行載入事件
loadEvent.apply(document,arguments); }; //爲DOMContentLoad事件註冊事件偵聽器
if (document.addEventListener) { document.addEventListener("DOMContenLoaded",init , false); } //對於safari使用setInterval()函數檢測document是否咱如完成
if (/WebKit/i.test(navigator.userAgent)) { var _timer=setInterval(function(){ if (/loaded|complete/.test(document.readyState)) { clearInterval(_timer); init(); } },10); } //對於IE(使用條件註釋),附加一個在載入過程最後執行的腳本。
//並檢測該腳本是否載入完成
/*@cc_on*/
/*if(@_win32) document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>"); var script=document.getElementById("__ie_onload"); script.onreadystateChange=function() { if (this.readyState=='complete') { init(); } }; /*@end @*/
return true; } window['ADS']['addLoadEvent']=addLoadEvent;
跨瀏覽器的事件屬性和方法this
定義了下列屬性。
bubbles:是不是冒泡事件;
cancelable:是否能夠被取消默認動做;
currentTarget:是當前正在處理的事件偵聽器所在的事件流中的DOM元素;
target:是DOM文檔中最先調用事件序列的目標對象(EventTarget對象的實例);
timestamp:是一個DOMTimeStamp對象,肯定子建立事件的紀元事件算起通過的毫秒數。但不必定在全部系統中都有效
type:包含時間名稱的字符串值
eventPhase:當前事件偵聽器出去事件流的那個階段123~也能夠用以下:
function eventListener(W3CEvent) { switch (W3CEvent.eventPhase) { case Event.CAPTURING: //若是處於捕獲階段要運行的代碼
break; case Event.AT_TARGET //若是當前目標對象要運行的代碼
break; case Event.BUBBLING_PHASE: //若是處於冒泡階段要運行的代碼
break; } }
W3C DOM2事件模型也定義了下列的Event對象方法
initEvent(eventType,canBubble,cancelable):用於初始化經過document.createEvent('Event')方法建立的事件對象。
preventDefalt():用於取消對象的默認動做
stopPropagation()用於中止事件流的進一步執行,包括捕獲階段、目標對象和冒泡階段。
DOM2事件規範定義的MouseEvent對象:
MouseEvent對象屬性:altKey,ctrlKey,shiftKey,分別表示在鼠標事件發僧是否按住了鍵盤上的Alt,Ctrl,Shift鍵
button ,button中會包含表示哪一個鼠標鍵按下的一個整數值。鼠標山每一個鍵與證書的對應關係:
0表示鼠標的左鍵;1表示中(若是有)2表示右
if (W3CEvent.button==0) { //左鍵的單機事件
} //或者
if (W3CEvent.button==MouseEvent.BUTTON_LEFT) { //左鍵單擊的代碼
}
還有clientX和clientY相似的還有screenX和screenY
document.addEventListener('click',function(W3CEvent){ alert('client:('+W3CEvent.clientX+','+W3CEvent.clientY+')'); },false);
處理諸多不兼容性問題
function getTarget(eventObject) { eventObject=eventObject||getEventObject(eventObject); //若是是W3C或者MSIE的模型
var target=eventObject.target||eventObject.srcElement; //若是想Safari中同樣是一個文本節點,從新將目標對象指定爲父元素
if (target.nodeType==ADS.node.TEXT_NODE) { target=node.parentNode; } return target; } window['ADS']['getTarget']=getTarget;
經過這個方法,能夠取得給定事件的目標:
ADS.addEvent(window,'load',function(){ function eventListener(W3CEvent) { //取得目標
var target=ADS.getTarget(W3CEvent); //target如今引用的是一個適當的元素
window.open(target.href); } var anchor = document.getElementById('example'); addEvent(anchor,'click',eventListener); });
function getMouseButton(eventObject) { eventObject = eventObject || getEventObject(eventObject); // Initialize an object wit the appropriate properties
//使用適當的屬性初始化一個對象變量
var buttons = { 'left':false, 'middle':false, 'right':false }; /*檢查eventObject對象的toString()方法的值,W3C DOM對象有toString方法 而且此時可方法的返回值應該是MouseEvent*/
// Check the toString value of the eventObject
// W3C Dom object have a toString method and in this case it
// should be MouseEvent
if(eventObject.toString && eventObject.toString().indexOf('MouseEvent') != -1) { // W3C Method
switch(eventObject.button) { case 0: buttons.left = true; break; case 1: buttons.middle = true; break; case 2: buttons.right = true; break; default: break; } } else if(eventObject.button) { // MSIE method
switch(eventObject.button) { case 1: buttons.left = true; break; case 2: buttons.right = true; break; case 3: buttons.left = true; buttons.right = true; break; case 4: buttons.middle = true; break; case 5: buttons.left = true; buttons.middle = true; break; case 6: buttons.middle = true; buttons.right = true; break; case 7: buttons.left = true; buttons.middle = true; buttons.right = true; break; default: break; } } else { return false; } return buttons; } window['ADS']['getMouseButton'] = getMouseButton;
處理鼠標的位置:
function getPointerPositionInDocument(eventObject) { eventObject = eventObject || getEventObject(eventObject); var x = eventObject.pageX || (eventObject.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)); var y= eventObject.pageY || (eventObject.clientY + (document.documentElement.scrollTop || document.body.scrollTop)); //x and y now contain the coordinates of the mouse relative to the document origin
return {'x':x,'y':y}; } window['ADS']['getPointerPositionInDocument'] = getPointerPositionInDocument;
function getKeyPressed(eventObject) { eventObject = eventObject || getEventObject(eventObject); var code = eventObject.keyCode; var value = String.fromCharCode(code); return {'code':code,'value':value}; } window['ADS']['getKeyPressed'] = getKeyPressed;