日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

【转】JavaScript事件顺序

發(fā)布時間:2025/7/14 javascript 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】JavaScript事件顺序 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文出處(據(jù)說是個大牛的blog):http://www.quirksmode.org/js/events_order.html

我是在搜索js冒泡時發(fā)現(xiàn)的這篇文章,覺得很好,所以轉(zhuǎn)了。格式可能有點亂,建議點擊上面鏈接看原文,可能會發(fā)現(xiàn)更多驚喜喲!

=============================================================================== 華麗的分割線,下面是全文

?

Event order

On the?Introduction to events?page I asked a question that at first sight seems incomprehensible: “If an element and one of its ancestors have an event handler for the same event, which one should fire first?” Not surprisingly, this depends on the browser.

The basic problem is very simple. Suppose you have a element inside an element

----------------------------------- | element1 | | ------------------------- | | |element2 | | | ------------------------- | | | -----------------------------------

and both have an onClick event handler. If the user clicks on element2 he causes a click event in both element1 and element2. But which event fires first? Which event handler should be executed first? What, in other words, is the?event order?

Two models

Not surprisingly, back in the bad old days Netscape and Microsoft came to different conclusions.

  • Netscape said that the event on element1 takes place first. This is called event?capturing.
  • Microsoft maintained that the event on element2 takes precedence. This is called event?bubbling.

The two event orders are radically opposed. Explorer only supports event bubbling. Mozilla, Opera 7 and Konqueror support both. Older Opera's and iCab support neither.

Event capturing

When you use event capturing

| | ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 \ / | | | ------------------------- | | Event CAPTURING | -----------------------------------

the event handler of element1 fires first, the event handler of element2 fires last.

Event bubbling

When you use event bubbling

/ \ ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 | | | | | ------------------------- | | Event BUBBLING | -----------------------------------

the event handler of element2 fires first, the event handler of element1 fires last.

W3C model

W3C has very sensibly decided to take a middle position in this struggle. Any event taking place in the?W3C event model?is first captured until it reaches the target element and then bubbles up again.

| | / \ -----------------| |--| |----------------- | element1 | | | | | | -------------| |--| |----------- | | |element2 \ / | | | | | -------------------------------- | | W3C event model | ------------------------------------------

You, the web developer, can choose whether to register an event handler in the capturing or in the bubbling phase. This is done through theaddEventListener()?method explained on the?Advanced modelspage. If its last argument is?true?the event handler is set for the capturing phase, if it is?false?the event handler is set for the bubbling phase.

Suppose you do

element1.addEventListener('click',doSomething2,true) element2.addEventListener('click',doSomething,false)

If the user clicks on element2 the following happens:

  • The?click?event starts in the capturing phase. The event looks if any ancestor element of element2 has a?onclick?event handler for the capturing phase.
  • The event finds one on element1.?doSomething2()?is executed.
  • The event travels down to the target itself, no more event handlers for the capturing phase are found. The event moves to its bubbling phase and executes?doSomething(), which is registered to element2 for the bubbling phase.
  • The event travels upwards again and checks if any ancestor element of the target has an event handler for the bubbling phase. This is not the case, so nothing happens.
  • The reverse would be

    element1.addEventListener('click',doSomething2,false) element2.addEventListener('click',doSomething,false)

    Now if the user clicks on element2 the following happens:

  • The?click?event starts in the capturing phase. The event looks if any ancestor element of element2 has a?onclick?event handler for the capturing phase and doesn’t find any.
  • The event travels down to the target itself. The event moves to its bubbling phase and executes?doSomething(), which is registered to element2 for the bubbling phase.
  • The event travels upwards again and checks if any ancestor element of the target has an event handler for the bubbling phase.
  • The event finds one on element1. Now?doSomething2()?is executed.
  • Compatibility with traditional model

    In the browsers that support the W3C DOM, a traditional event registration

    element1.onclick = doSomething2;

    is seen as a registration in the?bubbling phase.

    Use of event bubbling

    Few web developers consciously use event capturing or bubbling. In Web pages as they are made today, it is simply not necessary to let a bubbling event be handled by several different event handlers. Users might get confused by several things happening after one mouse click, and usually you want to keep your event handling scripts separated. When the user clicks on an element, something happens, when he clicks on another element, something else happens.

    Of course this might change in the future, and it’s good to have models available that are forward compatible. But the main practical use of event capturing and bubbling today is the registration of default functions.

    It always happens

    What you first need to understand is that event capturing or bubbling always happens. If you define a general onclick event handler for your entire document

    document.onclick = doSomething; if (document.captureEvents) document.captureEvents(Event.CLICK);

    any?click?event on any element in the document will eventually bubble up to the document and thus fire this general event handler. Only when a previous event handling script explicitly orders the event to stop bubbling, it will not propagate to the document.

    Uses

    Because any event ends up on the document, default event handlers become possible. Suppose you have this page:

    ------------------------------------ | document | | --------------- ------------ | | | element1 | | element2 | | | --------------- ------------ | | | ------------------------------------element1.onclick = doSomething; element2.onclick = doSomething; document.onclick = defaultFunction;

    Now if the user clicks on element1 or 2,?doSomething()?is executed. You can stop the event propagation here, if you wish. If you don’t the event bubbles up to?defaultFunction(). If the user clicks anywhere elsedefaultFunction()?is also executed. This might be useful sometimes.

    Setting document–wide event handlers is necessary in drag–and–drop scripts. Typically a?mousedown?event on a layer selects this layer and makes it respond to the?mousemove?event. Though the?mousedown?is usually registered on the layer to avoid browser bugs, both other event handlers must be document–wide.

    Remember the First Law of Browserology: anything can happen, and it usually does when you’re least prepared for it. So it may happen that the user moves his mouse very wildly and the script doesn’t keep up so that the mouse is not over the layer any more.

    • If the?onmousemove?event handler is registered to the layer, the layer doesn’t react to the mouse movement any more, causing confusion.
    • If the?onmouseup?event handler is registered on the layer, this event isn’t caught either so that the layer keeps reacting to the mouse movements even after the user thinks he dropped the layer. This causes even more confusion.

    So in this case event bubbling is very useful because registering your event handlers on document level makes sure they’re always executed.

    Turning it off

    But usually you want to turn all capturing and bubbling off to keep functions from interfering with each other. Besides, if your document structure is very complex (lots of nested tables and such) you may save system resources by turning off bubbling. The browser has to go through every single ancestor element of the event target to see if it has an event handler. Even if none are found, the search still takes time.

    In the Microsoft model you must set the event’s?cancelBubble?property to true.

    window.event.cancelBubble = true

    In the W3C model you must call the event’s?stopPropagation()?method.

    e.stopPropagation()

    This stops all propagation of the event in the bubbling phase. For a complete cross-browser experience do

    function doSomething(e) {if (!e) var e = window.event;e.cancelBubble = true;if (e.stopPropagation) e.stopPropagation(); }

    Setting the?cancelBubble?property in browsers that don’t support it doesn’t hurt. The browser shrugs and creates the property. Of course it doesn’t actually cancel the bubbling, but the assignment itself is safe.

    currentTarget

    As we’ve seen earlier, an event has a?target?or?srcElement?that contains a reference to the element the event happened on. In our example this is element2, since the user clicked on it.

    It is very important to understand that during the capturing and bubbling phases (if any) this target does not change: it always remains a reference to element2.

    But suppose we register these event handlers:

    element1.onclick = doSomething; element2.onclick = doSomething;

    If the user clicks on element2?doSomething()?is executed twice. But how do you know which HTML element is currently handling the event?target/srcElement?don’t give a clue, they always refer to element2 since it is the original source of the event.

    To solve this problem W3C has added the?currentTarget?property. It contains a reference to the HTML element the event is currently being handled by: exactly what we need. Unfortunately the Microsoft model doesn’t contain a similar property.

    You can also use?the?this?keyword. In the example above it refers to the HTML element the event is handled on, just like?currentTarget.

    Problems of the Microsoft model

    But when you use the Microsoft event registration model the?thiskeyword doesn’t refer to the HTML element. Combined with the lack of acurrentTarget–like property in the Microsoft model, this means that if you do

    element1.attachEvent('onclick',doSomething) element2.attachEvent('onclick',doSomething)

    you?cannot?know which HTML element currently handles the event. This is the most serious problem with the Microsoft event registration model and for me it’s reason enough never to use it, not even in IE/Win only applications.

    I hope Microsoft will soon add a?currentTarget–like property — or maybe even follow the standard? Web developers need this information.

    Continue

    If you wish to go through all event pages in order, you should now continue with the?Mouse events?page.

    聲明:如有轉(zhuǎn)載本博文章,請注明出處。您的支持是我的動力!文章部分內(nèi)容來自互聯(lián)網(wǎng),本人不負任何法律責任。
    本文轉(zhuǎn)自bourneli博客園博客,原文鏈接:http://www.cnblogs.com/bourneli/articles/2746553.html,如需轉(zhuǎn)載請自行聯(lián)系原作者

    總結(jié)

    以上是生活随笔為你收集整理的【转】JavaScript事件顺序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。