學習event對象:
Event是在WebCore/dom/Event.h中定義,比較關注的是成員變量EventTarget類型的指針target,根據target調用每個event的handle處理。在應用中設計一個子類繼承EventTarget,並在其中添加一個成員變量m_result,可以完成Event傳遞參數的使命。在每個event被create出來後,一般情況下都會設置把target變量初始化一下(包括把m_result初始化),然丟到一個eventqueue中等待處理。
對於Event類型中的其他變量還沒有學習到,目前還沒有用到。
JavaScript運行過程中event流程:
我們知道html中的JavaScript的運行其實是通過Frame類中的ScriptController接口完成的。而實際運行的代碼是WebCore目錄中的cpp代碼(這個過程以後會介紹),而在JavaScript中應用Eevnt對象,也就是在WebCore中的對應cpp代碼中使用Event對象。比如,在html文件中對一個button定義onclick處理,這裏就牽扯到Event的處理過程。在JavaScript運行過程也會涉及到很多Event處理,比如,在JS中對localStorage的操作,都是由Event完成。由於最近在學習IndexDB相關,所以就以這個爲例子,介紹一下JS後臺程序如何使用Event對象。
Frame類中包含了一個Document指針,而Document是ScriptExecutionContext的子類,它保存了一個DocumentEventQueue類型的指針。而DocumentEventQueue又是EventQueue的子類,EventQueue中有一個Event對象的hash表。DocumentEventQueue定義如下:
class DocumentEventQueue : public RefCounted<DocumentEventQueue>, public EventQueue {
public:
enum ScrollEventTargetType {
ScrollEventDocumentTarget,
ScrollEventElementTarget
};
static Pa***efPtr<DocumentEventQueue> create(ScriptExecutionContext*);
virtual ~DocumentEventQueue();
// EventQueue
virtual bool enqueueEvent(Pa***efPtr<Event>) OVERRIDE;
virtual bool cancelEvent(Event*) OVERRIDE;
virtual void close() OVERRIDE;
void enqueueOrDispatchScrollEvent(Pa***efPtr<Node>, ScrollEventTargetType);
private:
explicit DocumentEventQueue(ScriptExecutionContext*);
void pendingEventTimerFired();
void dispatchEvent(Pa***efPtr<Event>);
OwnPtr<DocumentEventQueueTimer> m_pendingEventTimer;
ListHashSet<RefPtr<Event> > m_queuedEvents;
HashSet<Node*> m_nodesWithQueuedScrollEvents;
bool m_isClosed;
friend class DocumentEventQueueTimer;
};
通過調用enqueueEvent接口把Event放進queuedEvents中,同時也會通過pendingEventTimer運行pendingEventTimerFired函數,調用dispatchEvent函數,調用EventTarget的dispatchEvent函數,所有的Event都會走這麼一個流程。
對IndexDB來講,所有對DB的操作都會轉化成一個Request對象,這個對象繼承於EventTarget。當JS中執行了一個DB的操作,發起一個request,執行成功(可以理解爲是允許執行),調用request的onSuccess,在這個函數裏會首先創建一個Event,然後把target設置爲自己,然後調用把context轉換爲Document對象,調用document的Enqueue函數,然後走上述的Document對應的Event流程,最終調到request的dispatchEvent函數,這個函數中調用EventDispatcher::dispatch去fire這個event的listener,然後完成應該做的工作。這樣就走完了一套JS發起一個請求,最終到event處理的流程。
說的比較模糊,僅作爲自己日後參考,同時歡迎討論。