1. 程式人生 > >AS3 event flow 事件冒泡機制

AS3 event flow 事件冒泡機制

=思路大綱=

  1. ActionScript 2的問題
  2. AS3解決問題
  3. 結合問題,說明“冒泡”
  4. 冒泡的問題所在以及解決方法


1 - ActionScript 2的問題

stage裡有一個mc,mc裡有一個btn
點選mc實現拖動mc,滑鼠鬆開停止拖動
點選mc實現mc隱藏。
最容易想到的方法,程式碼如下:

mc.onPress = function() {
        this.startDrag();
};
mc.onRelease = function() {
        this.stopDrag();
};
mc.btn.onPress = function() {
        mc._visible=false
};

表面來看,這個思路是正確的。(實際上沒什麼思路可言,很簡單的方法。)
實際怎麼樣?當然是不能實現。
問題:點選btn,不能觸發btn的動作!!!!
解釋: 因為btn處於mc內部,mc被加上了事件以後,按照as2的事件機制,mc內部的btn甚至是其他的元件都不能接受事件。或者可以認為mc的事件覆蓋了mc中其他元件的事件。
從非冒泡機制來說,在btn上點選滑鼠,首先接受到點選事件的自然是btn的上一層(也就是mc),然後才是btn元件。Mc先接受到點選事件,觸發相關的函式。然後呢?我們要實現的點選btn的效果沒了。我們可以認為mc把我們的滑鼠點選事件據為私有了,不再往下傳遞。(如果是冒泡機制的話,這個動作就回繼續往下傳遞到btn,然後btn會執行。)那麼這種效果在as2中還能實現麼?答案自然是肯定的,不過方法就複雜了。
這裡就不討論了。As3已經成為主流。
但是as3中的冒泡機制,讓我們可以簡單的解決這樣的難題。

2 - AS3解決問題

下面來看as3中怎麼實現。
程式碼如下:

import flash.events.*;
mc.addEventListener(MouseEvent.CLICK,mcfunction);
mc.btn.addEventListener(MouseEvent.CLICK,btnfucntion);

function mcfunction(event:MouseEvent) {
        trace("mc click");
}
function btnfucntion(event:MouseEvent) {
        trace("btn click");
}

看看程式碼就覺得,好像沒用什麼特別的解決方法,就加兩個偵聽函式,就搞定了。
這個程式碼自然的不能再自然了,就好像做flash 先的安裝軟體一樣。
但是如此自然的程式碼下面,使AS3的冒泡機制在提供支援。

3 - 結合問題,說明冒泡機制:
Help中有一個冒泡機制的圖,相信大家都已經看過了
這裡我聯絡例項,另外做一個圖,幫助各位理解。

2D2D13C9009ACC1FF3AADD80E5C4FB85 

上圖為as2中的執行原理
下圖為as3中的執行原理
2D8D966808DAEEA2C9701B5E09B334FE 
上圖也就是在as3中實現我們文章開始提出的例子的工作原理。
下面詳細描述一下

捕獲階段: 
滑鼠在btn上發出點選事件,首先捕捉到該事件的事stage.,然後事件往下傳遞到mc,再到btn..(如果滑鼠事件發生在btn按鈕中的一個 label上,那麼該事件還會繼續向下傳遞,直到找到label元件。)AS2中,一旦找到了可以相應事件的函式,就停止了,不會往下傳遞。這個道理應該說明白了
目標階段 :
找到我們的滑鼠最底層的目標,也就是btn以後,那麼就開始執行btn的偵聽函數了。
    如果滑鼠事件發生的所在位置,是mc中的btn中的一個label。那麼將先執行label的偵聽函式。(當然我們的例子中沒有label)
冒泡階段:
執行了目標階段的偵聽函式以後,開始冒泡。
換一個說法是,返回btn的父級元件mc,如果能找到相關的偵聽函式,那麼就執行,如果沒有,就繼續往上冒泡到btn的父級元件mc的父級元件stage。看能不能找到相關的偵聽函式。

注意一個:首先執行的函式一定是目標物件的偵聽函式。就像我們上面的例子一樣,點選btn會先trace(“btn click”),然後冒泡到mc,執行trace(“mc click”)..然後繼續往上,如果stage我們也加一個偵聽函式,執行語句,那麼還會繼續執行 trace(“stage click”).
到達stage頂層了,冒泡結束。
說到這裡,各位看官也應該明白了as3的冒泡究竟是幹什麼用的了

4 - 冒泡的問題所在以及解決方法 
冒泡也有問題,並不是說它有缺陷,因為出現問題無法避免。
問題在於,
假如在上面的例子中,我們不想在點選btn冒泡階段中執行mc的偵聽函式,我們只想執行btn的偵聽函式。怎麼解決?
同樣的問題延伸出去,可以得到很多擴充套件和應用。
那麼我們需要阻止他的冒泡的時候執行相關的偵聽函式。
Chm中的方法有

stopImmediatePropagation():void
防止對事件流中當前節點中和所有後續節點中的事件偵聽器進行處理。
stopPropagation():void
防止對事件流中當前節點的後續節點中的所有事件偵聽器進行處理。

用來修改我們上面的例子
程式碼如下:

import flash.events.*;
mc.addEventListener(MouseEvent.CLICK,mcfunction);
mc.btn.addEventListener(MouseEvent.CLICK,btnfucntion);
function mcfunction(event:MouseEvent) {
        trace("mc click");
}
function btnfucntion(event:MouseEvent) {
        trace("btn click");
        event.stopPropagation();//修改在此處。簡單一句,解決問題
}

現在可以試試,點選btn執行得到的結果就是

程式碼:
btn click

說明,已經防止了冒泡階段中對mc偵聽函式的處理。也就沒有trace(“mc click”)了
As3事件機制遠遠不像這裡寫的那麼簡單,還有很多東西需要研究。

總結:as2的事件分發機制是 從上根容器一直往下找 找到了可以響應事件的容器就停止 然後觸發事件響應。

  as3分為兩個過程  先從上根容器一直往下找 找到最底層的控制元件,然後依次向上觸發事件  

相關推薦

AS3 event flow 事件冒泡機制

=思路大綱= ActionScript 2的問題AS3解決問題結合問題,說明“冒泡”冒泡的問題所在以及解決方法1 - ActionScript 2的問題 stage裡有一個mc,mc裡有一個btn 點選mc實現拖動mc,滑鼠鬆開停止拖動 點選mc實現mc隱藏。 最容易想到的

這可能是最簡明扼要的 js事件冒泡機制+阻止默認事件 講解了

不支持 自身 eve font def back 綁定 向上 版本 哎 js事件冒泡機制和阻止冒泡 阻止默認行為好像永遠也整不清楚,記了忘 忘了記。。。醉了 這篇文章寫完以後下次再忘記 就呼自己一巴掌,忘一次一巴掌   首先要明白兩個概念——事件和事件流   事件指的

Event flow(事件流)

例子:<div> <button id="btn">Click Me!</button> </div>對於上面例子,如果想知道點選後例子的執行順序,此時就與Event flow(事件流動)相關了。 事件流動 DOM事件不單單隻會在一個Element上觸發

js事件冒泡機制簡述

定義:JavaSciprt事件中有兩個很重要的特性:事件冒泡 以及目標元素 。 事件冒泡: 當一個元素上的事件被觸發的時候,比如說滑鼠點選了一個按鈕,同樣的事件將會在那個元素的所有祖先元素中被觸發。這一過程被稱為事件冒泡;這個事件從原始元素開始一直冒泡到DOM樹的最上層

js 事件流,事件冒泡機制

事件冒泡:當一個元素接收到事件的時候,會把他接收到的所有傳播給他的父級,一直到頂層window, <!DOCTYPE html> <html>     <head>     &nb

Vue中的event阻止事件冒泡、預設事件

vue的事件物件: @dragstart=’drag(event)′,在函式中傳evevt ,函式中接收一下,事件物件就有了。 <div class="select-item" draggable='true' @dragstart='drag($event)' v

Flex事件冒泡機制

在網上瀏覽了幾篇文章,大體總結了一下,簡單說明如下: 事件的傳遞分為三個階段,如圖:捕獲階段(Capture Phase)、目標階段、冒泡階段,比如當你點選了一下Child1 Node時,事件會從Stage->Parent Node->Child1 Node一路

JavaScript 事件冒泡機制

       html的DOM是層級包含關係的,比如巢狀的DIV,如果三個DIV都綁定了事件的話,最內層的DIV的事件觸發會導致父級DIV所繫結的事件的觸發,就像湖水裡面底層的氣泡在從底部到湖面會觸發各個深度的事件一樣。html的DOM的這種機制有時候會給我們帶來麻煩,因為

js事件基礎(事件event物件,事件冒泡,滑鼠鍵盤事件

事件物件(獲取事件的詳細資訊)和事件冒泡: 什麼是event物件:獲取事件的詳細資訊:滑鼠位置、鍵盤按鍵。                    document本質:document.childNodes[0].tagName 獲取event物件(相容性寫法):var

阻止事件冒泡,阻止默認事件event.stopPropagation()和event.preventDefault(),return false的區別

attr htm pre 點擊 操作 連接 com spa ati 1.event.stopPropagation()方法 這是阻止事件的冒泡方法,不讓事件向documen上蔓延,但是默認事件任然會執行,當你掉用這個方法的時候,如果點擊一個連接,這個連接仍然會被打開, 2.

DOM事件機制(事件捕獲和事件冒泡事件委托)

使用 tar web strong 事件 所有 span click ner 內容: 1.事件復習 2.事件冒泡與事件捕獲 3.事件委托 1.事件復習 (1)事件 事件是用來處理響應的一個機制,這個響應可以來自於用戶(點擊, 鼠標移動, 滾動), 也可以來自於瀏

Event Flow事件流)

DOM Event:事件流動(Event Flow): 定義:          DOM(文件物件模型)結構是一個樹型結構,當一個HTML元素產生一個事件時,該事件會在元素節點與根結點之間的路徑傳播,路徑所經過的結點都會收到該事件,這個傳播過程可稱為D

DOM Event事件流動(Event Flow

哪怕一個web開發的初學者都會知道,當我們滑鼠在button上點選時,會在button上觸發一個click事件。但是: button是div的一個子Node;從介面上來看,在button裡點選相當於在div裡點選;那click事件也會觸發在div上嗎? 如果click事件也觸發在div

egret.Event觸控事件事件機制

事件機制包含4個步驟:註冊偵聽器,傳送事件,偵聽事件,移除偵聽器。這四個步驟是按照順序來執行的。 egret.TouchEvent.TOUCH_TAP //觸控事件 //註冊偵聽函式的定義 public addEventListener(typ

Qt中的事件處理機制event

Qt事件也就是Qt程式中出現的一系列“事情”,包括對使用者操作做出反應時發出的滑鼠或鍵盤事件等;以及系統內部自動發出的定時器事件等。總之,出現了這些事件後就需要對這些事件進行處理,處理的方法便是“事件處理機制”。 圖1 Qt事件產生 以

關於js中return false、event.preventDefault()和event.stopPropagation()區別,以及阻止事件冒泡和阻止預設事件

在平時專案中,如果遇到需要阻止瀏覽器預設行為,大家經常會用return false;和event.preventDefault()來阻止,但對它倆的區別還是模糊,這裡順便帶上event.stopPropagation()一起區分下。 事件處理程式的返回值只對通過屬性註冊的處理程式才有意義,如果我

setTimeOut引發的思考——初步理解JS事件迴圈機制 Event Loop

JS是單執行緒引擎,線上程中擁有唯一一個事件迴圈(web workder涉及到了多執行緒,再做補充) JS程式碼執行過程中,除了依靠函式呼叫棧順序執行JS程式碼,還依靠任務佇列(task queue)執行一些程式碼。 一個執行緒中,事件迴圈是唯一的,但是任務佇列

JS事件迴圈機制event loop)

一 前言 相信所有學過 JavaScript 都知道它是一門單執行緒的語言,這也就意味著 JS 無法進行多執行緒程式設計,但是 JS 當中卻有著無處不在的非同步概念 。在初期許多人會把非同步理解成類似多執行緒的程式設計模式,其實他們中有著很大的差別,要完全理解非

event loop到async await來了解事件迴圈機制

JS為什麼是單執行緒的? 最初設計JS是用來在瀏覽器驗證表單操控DOM元素的是一門指令碼語言,如果js是多執行緒的那麼兩個執行緒同時對一個DOM元素進行了相互衝突的操作,那麼瀏覽器的解析器是無法執行的。 JS為什麼需要非同步? 如果JS中不存在非同步,只能自上而下執行,如果上一行解析時間很長,那麼下面的

Js高階event事件冒泡

面向物件 單列模式 工廠模式 建構函式 (1) 類 Js天生自帶的類 Object 基類 Function Array Number Math Boolean Date Regexp String 1.事件 瀏覽器客戶端上客戶觸發的行為都稱為事件 所有的事件都