的onclick的事件處理函數了,那么就把cancelbubble設置為false即可。[br] [br]二、 ie中拖動dom元素的例子[br]/*[br] 該函數由mousedown事件處理調用[br] 它為隨后發生的mousemove和mouseup事件注冊了臨時的捕捉事件處理程序[br] 并用這些事件處理程序拖動指定的文檔元素[br] 第二個參數必須是mousedown事件的事件對象[br]*/[br]function begindrag(elementtodrag,event)[br]{[br] //該元素當前位于何處[br] //該元素的樣式性質必須具有left和top css屬性[br] //此外,我們假定他們用象素做單位[br] //var x=parseint(elementtodrag.style.left);[br] //var y=parseint(elementtodrag.style.top); [br] //計算一個點和鼠標點擊之間的距離,下面的嵌套的movehandler函數需要這些值[br] var deltax=event.clientx-parseint(elementtodrag.style.left);[br] var deltay=event.clienty-parseint(elementtodrag.style.top); [br]// 注冊mousedown事件后發生的mousemove和mouseup事件的處理程序[br]// 注意,它們被注冊為文檔的捕捉事件處理程序[br]// 在鼠標按鈕保持按下的狀態的時候,這些事件處理程序保持活動的狀態[br]// 在按鈕被釋放的時候,它們被刪除[br] document.attachevent("onmousemove",movehandler);[br] document.attachevent("onmouseup",uphandler); [br] //我們已經處理了該事件,不要讓別的元素看到它[br]event.cancelbubble=true;[br]event.returnvalue=false; [br] /*[br] 這是在元素被拖動時候捕捉mousemove事件的處理程序,它響應移動的元素 [br] */[br] function movehandler(e) [br] {[br] //把元素移動到當前的鼠標位置[br] e=window.event;[br] elementtodrag.style.left=(event.clientx-deltax)+"px";[br] elementtodrag.style.top=(event.clienty-deltay)+"px"; [br] //不要讓別的元素看到該事件[br] event.cancelbubble=true; [br] } [br] /*[br] 該事件將捕捉拖動結束的時候發生的mouseup事件[br] */[br] function uphandler(e)[br] {[br] //注銷事件處理程序[br] document.detachevent("onmouseup",uphandler);[br] document.detachevent("onmousemove",movehandler);} [br] event.cancelbubble=true;[br] } [br] 調用它的html文件代碼:[br] [br] [br]
untitled page[br] [br] [br] [br]
[br]
[br] 拖動我 [br]
[br]
[br]
this is a test.testing,testing
[br]
[br] [br]三、 dom中的高級事件處理[br]ie 6中的事件處理,并不是w3c dom標準的事件處理模型,所以如果上述代碼運行在mozilla firefox的瀏覽器中,就會失去作用,同時即將發布的ie 7也將支持w3c dom的二級標準,所以掌握dom的高級事件處理顯得就很重要了,因為w3c dom二級標準是未來web的發展方向,同時w3c dom的api非常常用,為未來更加復雜的web開發提供了良好的基礎。[br](一)事件處理程序的作用域和事件的傳播[br] 在正式討論dom高級事件處理之前,我們有必要了解一下事件處理程序的作用域。事件處理程序的作用域要比普通的函數作用域復雜很多。普通的函數作用域鏈比較容易,例如在一個普通函數中查找一個變量a,那么javascript解釋器會先在該函數的調用對象中查找是否有a這個變量,如果沒有,將會在作用域鏈的下一個對象,一般是全局對象中查找。但是事件處理程序沒這么簡單,特別是用html的屬性定義的,它們的作用域鏈的頭部是調用它們的對象,而下一個對象并不是全局對象,而是觸發事件處理程序的對象。這樣就會出現一個問題,window和document都有一個方法open(),如果open()前面不加修飾,那么在事件處理的函數中將會調用document.open()方法,而不是常用的window.open()方法,所以使用的時候應該明確指明是window.open()。[br](二)事件傳播和注冊事件處理程序[br]1.事件傳播[br] 在二級dom標準中,事件處理程序比較復雜,當事件發生的時候,目標節點的事件處理程序就會被觸發執行,但是目標節點的父節點也有機會來處理這個事件。事件的傳播分為三個階段,首先是捕捉階段,事件從document對象沿著dom樹向下傳播到目標節點,如果目標的任何一個父節點注冊了捕捉事件的處理程序,那么事件在傳播的過程中就會首先運行這個程序。下一個階段就是發生在目標節點自身了,注冊在目標節點上的相應的事件處理程序就會執行;最后是起泡階段,事件將從目標節點向上傳回給父節點,同樣,如果父節點有相應的事件處理程序也會處理。在ie中,沒有捕捉的階段,但是有起泡的階段。可以用stoppropagation()方法來停止事件傳播,也就是讓其他元素對這個事件不可見,在ie 6中,就是把cancelbubble設置為true。[br]2.注冊事件處理程序[br] 和ie一樣,dom標準也有自己的事件處理程序,不過dom二級標準的事件處理程序比ie的強大一些,事件處理程序的注冊用addeventlistner方法,該方法有三個參數,第一個是事件類型,第二個是處理的函數,第三個是一個布爾值,true表示制定的事件處理程序將在事件傳播的階段用于捕捉事件,否則就不捕捉,當事件發生在對象上才觸發執行這個事件處理的函數,或者發生在該對象的字節點上,并且向上起泡到這個對象上的時候,觸發執行這個事件處理的函數。例如:document.addeventlistener("mousemove",movehandler,true);就是在mousemove事件發生的時候,調用movehandler函數,并且可以捕捉事件。[br] 可以用addeventlistener為一個事件注冊多個事件處理的程序,但是這些函數的執行順序是不確定,并不像c#那樣按照注冊的順序執行。[br] 在mozilla firefox中用addeventlistener注冊一個事件處理程序的時候,this關鍵字就表示調用事件處理程序的文檔元素,但是其他瀏覽器并不一定是這樣,因為這不是dom標準,正確的做法是用currenttarget屬性來引用調用事件處理程序的文檔元素。[br]3.二級dom標準中的event[br] 和ie不同的是,w3c dom中的event對象并不是window全局對象下面的屬性,換句話說,event不是全局變量。通常在dom二級標準中,event作為發生事件的文檔對象的屬性。event含有兩個子接口,分別是uievent和mutationevent,這兩個子接口實現了event的所有方法和屬性,而mouseevent接口又是uievent的子接口,所以實現了uievent和event的所有方法和屬性。下面,我們就看看event、uievent和mouseevent的主要屬性和方法。[br] 1.event[br] type:事件類型,和ie類似,但是沒有“on”前綴,例如單擊事件只是“click”。[br] target:發生事件的節點。[br] currenttarget:發生當前正在處理的事件的節點,可能是target屬性所指向的節點,也可能由于捕捉或者起泡,指向target所指節點的父節點。[br] eventphase:指定了事件傳播的階段。是一個數字。[br] timestamp:事件發生的時間。[br] bubbles:指明該事件是否起泡。[br] cancelable:指明該事件是否可以用preventdefault()方法來取消默認的動作。[br] preventdefault()方法:取消事件的默認動作;[br] stoppropagation()方法:停止事件傳播。[br] 2.uievent[br] view:發生事件的window對象。[br] detail:提供事件的額外信息,對于單擊事件、mousedown和mouseup事件都代表的是點擊次數。[br] 3.mouseevent[br] button:一個數字,指明在mousedown、mouseup和單擊事件中,鼠標鍵的狀態,和ie中的button屬性類似,但是數字代表的意義不一樣,0代表左鍵,1代表中間鍵,2代表右鍵。[br] altkey、ctrlkey、shiftkey、metakey:和ie相同,但是ie沒有最后一個。[br] clientx、clienty:和ie的含義相同,但是在dom標準中,這兩個屬性值都不考慮文檔的滾動情況,也就是說,無論文檔滾動到哪里,只要事件發生在窗口左上角,clientx和clienty都是0,所以在ie中,要想得到事件發生的坐標相對于文檔開頭的位置,要加上document.body.scrollleft和document.body.scrolltop。[br] screenx、screeny:鼠標指針相對于顯示器左上角的位置,如果你想打開新的窗口,這兩個屬性很重要。[br] relatedtarget:和ie中的fromelement、toelement類似,除了對于mouseover和mouseout有意義外,其他的事件沒什么意義。[br](三)兼容于兩種主流瀏覽器的拖動dom元素的例子[br] 好了,剛才講了這么多dom編程和ie中的事件,那么如何編寫兼容ie和mozilla firefox兩種主流瀏覽器的拖拽程序呢?代碼如下:[br]function begindrag(elementtodrag,event)[br]{[br] var deltax=event.clientx-parseint(elementtodrag.style.left);[br] var deltay=event.clienty-parseint(elementtodrag.style.top);[br][color=#800000] //hgx注:個人覺得使用通過css的left/top屬性來計算不是一個好方法,可以通過offserleft和offsertop得到。[/color][br]if(document.addeventlistener) [br]{[br] document.addeventlistener("mousemove",movehandler,true);[br] document.addeventlistener("mouseup",uphandler,true);[br]}[br]else if(document.attachevent)[br]{[br] document.attachevent("onmousemove",movehandler);[br] document.attachevent("onmouseup",uphandler);[br] [br]}[br] [br] if(event.stoppropagation) event.stoppropagation();[br] else event.cancelbubble=true;[br] if(event.preventdefault) event.preventdefault();[br] else event.returnvalue=false;[br] [br] function movehandler(e) [br] {[br] if (!e) e=window.event; //如果是ie的事件對象,那么就用window.event[br] //全局屬性,否則就用dom二級標準的event對象。[/p]
[p][color=#800000]//hgx注:也可以這樣:e = e || window.event;[/color][br] elementtodrag.style.left=(event.clientx-deltax)+"px";[br] elementtodrag.style.top=(event.clienty-deltay)+"px";[br] [br] if(event.stoppropagation) event.stoppropagation();[br] else event.cancelbubble=true;[br] [br] }[br] [br] function uphandler([br]e)[br] {[br] if(document.removeeventlistener)[br] {[br] document.removeeventlistener("mouseup",uphandler,true);[br] document.removeeventlistener("mousemove",movehandler,true);}[br] else[br] {[br] document.detachevent("onmouseup",uphandler);[br] document.detachevent("onmousemove",movehandler);}[br] }[br] if(event.stoppropagation) event.stoppropagation();[br] else event.cancelbubble=true;[br] [br] }[/p]
該文章在 2010/4/24 11:24:04 編輯過