学习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处理的流程。
说的比较模糊,仅作为自己日后参考,同时欢迎讨论。