JavaScript DOM高級程序設計 4.3控制事件流和註冊事件偵聽器--我要堅持到底!

  • 1、事件流

咱們經過下面一個實例,進行說明。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

  • 事件冒泡--

  • 事件捕獲--

  • W3C捕獲以及冒泡事件流

阻止冒泡瀏覽器

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>
  • 深刻理解ADS.addEvent()方法
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 DOM2事件模型
//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事件

不管那種事件註冊方法,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

  • W3C DOM2事件模型爲Event對象

定義了下列屬性。

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); });
  • 肯定單擊了哪一個鼠標鍵(下面代碼直接copy源代碼的。不高興敲了)
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;
相關文章
相關標籤/搜索