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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WebKit DOM Event (一)

發(fā)布時間:2024/4/15 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WebKit DOM Event (一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

DOM Event 規(guī)范

DOM Event 主要定義了三類接口:

EventTarget, 所有DOM節(jié)點和XMLHttpRequest?都實現EventTarget接口

? ? class EventTarget? {

? ? ? ? void addEventListener(in DOMString type,inEventListener listener, in boolean useCapture);

? ? ? ? void removeEventListener(in DOMString type,in EventListener listener, in boolean useCapture);

? ? ? ? boolean dispatchEvent(in Event event)

? ? };

這個類是一個純虛基類,因此是一個接口類

1.添加和刪除Listener,這些是虛函數,子類中可以重新實現

2.分發(fā)Event,有一個虛函數,和一個函數,這樣子類可以有自己的個性

3.添加,刪除和獲取屬性Listener

4.fire觸發(fā)Listener函數,這個函數不需要有子類的實現


EventListener, 用戶實現該接口,并且在一個EventTarget上注冊,使用addEventListener 完成注冊;

void?handleEvent(in Event evt);

EventListener::Type {
? ? ? ? ? ? JSEventListenerType,?
? ? ? ? ? ? ImageEventListenerType,?
? ? ? ? ? ? InspectorDOMAgentType,
? ? ? ? ? ? InspectorDOMStorageResourceType,
? ? ? ? ? ? ObjCEventListenerType,
? ? ? ? ? ? CPPEventListenerType,
? ? ? ? ? ? ConditionEventListenerType,
? ? ? ? ? ? GObjectEventListenerType,
? ? ? ? ? ? NativeEventListenerType
? ? ? ? };

Event 給EventHandle提供上下文信息

readonly attribute DOMString??????? type;

readonly attribute EventTarget????? target;

readonly attribute EventTarget????? currentTarget;

readonly attribute unsigned short?? eventPhase;

readonly attribute boolean????????? bubbles;

readonly attribute boolean????????? cancelable;

readonly attribute DOMTimeStamp???? timeStamp;

?

void?????????????? stopPropagation();

void?????????????? preventDefault();

[OldStyleObjC] void initEvent(in DOMStringeventTypeArg,

in boolean canBubbleArg,

in boolean cancelableArg);

?

// DOM Level 3 Additions.

readonly attribute boolean defaultPrevented;

void stopImmediatePropagation();

?

// IE Extensions

readonly attribute EventTarget????? srcElement;

attribute boolean????????? returnValue;

attribute boolean????????? cancelBubble;

?

#if defined(LANGUAGE_JAVASCRIPT) &&LANGUAGE_JAVASCRIPT

readonly attribute [Custom] Clipboard??????? clipboardData;

#endif


事件流

  • 基本事件流

    每個事件都對應一個事件目標(EventTarget)(也是一個node 節(jié)點),EventTarget 有event 的target 屬性指定。 每個事件目標注冊有若干事件監(jiān)聽者(EventListerner), 這些監(jiān)聽者在事件到達后激活,激活的順序在DOM規(guī)范中沒有定義。如果沒有定義事件capture或者bubbling,則當事件目標上的所有事件監(jiān)聽者響應完畢后,則這個事件處理完畢。

  • 事件捕獲

    事件捕獲發(fā)生在如下情況下: 一個事件監(jiān)聽者注冊在某個事件的目標節(jié)點的祖先節(jié)點上,當該事件發(fā)生后,在其到達目標節(jié)點之前,祖先節(jié)點的事件監(jiān)聽者首先捕獲并處理,然后將事件逐級下傳,直到目標節(jié)點。

  • 事件冒泡

    事件冒泡初始階段同基本事件流相同,然而在事件的目標節(jié)點所有事件監(jiān)聽者響應完畢后,是將將會沿著節(jié)點向其祖先方向上傳,直到document點,上傳過程中將會逐級激發(fā)在遇到節(jié)點上注冊的的所有事件監(jiān)聽者(捕獲事件除外)。

  • 事件取消

    一些事件可以規(guī)定為可取消的,這些事件一般都會應有一個缺省的動作。當此類事件發(fā)生時,首先傳遞給目標節(jié)點上的事件監(jiān)聽者,事件監(jiān)聽者可以選擇是否取消該事件的缺省動作。

下面兩圖為事件流圖:

WebKit DOM Event 類圖

WebKit 實現邏輯

實現邏輯(以鼠標事件為例):

  • 鼠標事件發(fā)生
  • 根據鼠標事件發(fā)生的位置, 找到對應的EventTarget 節(jié)點
  • 在EventTarget的 dispatchGenericEvent函數中,獲取到所有的父節(jié)點,保存到list中;
  • 進入事件捕獲階段
  • 觸發(fā)當前EventTarget的當前事件的EventListen
  • 進入事件冒泡階段

bool EventTargetNode::dispatchGenericEvent(PassRefPtr<Event>e, ExceptionCode&, bool tempEvent)

{

??? RefPtr<Event>evt(e);

???ASSERT(!eventDispatchForbidden());

???ASSERT(evt->target());

???ASSERT(!evt->type().isNull()); // JavaScript code could create anevent with an empty name

??? //work out what nodes to send event to

???DeprecatedPtrList<Node> nodeChain;

?

??? if(inDocument()) {

???????for (Node* n = this; n; n = n->eventParentNode()) {

???????????n->ref();

???????????nodeChain.prepend(n);

???????}

??? }else {

???????// if node is not in the document just send event to itself

???????ref();

???????nodeChain.prepend(this);

??? }

?

???DeprecatedPtrListIterator<Node> it(nodeChain);

???? //Before we begin dispatching events, give the target node a chance to do somework prior

??? //to the DOM event handlers getting a crack.

??? void*data = preDispatchEventHandler(evt.get());

??? //trigger any capturing event handlers on our way down

???evt->setEventPhase(Event::CAPTURING_PHASE);

???it.toFirst();

??? //Handle window events for capture phase, except load events, this quirk isneeded

??? //because Mozilla used to never propagate load events to the window object

??? if(evt->type() != loadEvent && it.current()->isDocumentNode() &&!evt->propagationStopped())

???????static_cast<Document*>(it.current())->handleWindowEvent(evt.get(),true);

??? for(; it.current() && it.current() != this && !evt->propagationStopped();++it) {

???????evt->setCurrentTarget(EventTargetNodeCast(it.current()));

??????EventTargetNodeCast(it.current())->handleLocalEvents(evt.get(), true);

??? }??

?

??? //dispatch to the actual target node

???it.toLast();

??? if(!evt->propagationStopped()) {

???????evt->setEventPhase(Event::AT_TARGET);

???????evt->setCurrentTarget(EventTargetNodeCast(it.current()));

???????// We do want capturing event listeners to be invoked here, even though

???????// that violates the specification since Mozilla does it.

???????EventTargetNodeCast(it.current())->handleLocalEvents(evt.get(), true);

???????EventTargetNodeCast(it.current())->handleLocalEvents(evt.get(), false);

??? }

??? --it;

?? //ok, now bubble up again (only non-capturing event handlers will be called)

??? //### recalculate the node chain here? (e.g. if target node moved in document byprevious event handlers)

??? //no. the DOM specs says:

??? //The chain of EventTargets from the event target to the top of the tree

??? //is determined before the initial dispatch of the event.

??? //If modifications occur to the tree during event processing,

??? //event flow will proceed based on the initial state of the tree.

??? //

??? //since the initial dispatch is before the capturing phase,

??? //there's no need to recalculate the node chain.

??? //(tobias)

??? if(evt->bubbles()) {

???????evt->setEventPhase(Event::BUBBLING_PHASE);

???????for (; it.current() && !evt->propagationStopped() && !evt->cancelBubble();--it) {

???????????evt->setCurrentTarget(EventTargetNodeCast(it.current()));

???????????EventTargetNodeCast(it.current())->handleLocalEvents(evt.get(), false);

???????}

???????// Handle window events for bubbling phase, except load events, thisquirk is needed

???????// because Mozilla used to never propagate load events at all

???????it.toFirst();

???????if (evt->type() != loadEvent && it.current()->isDocumentNode()&& !evt->propagationStopped() && !evt->cancelBubble()) {

???????????evt->setCurrentTarget(EventTargetNodeCast(it.current()));

???????????static_cast<Document*>(it.current())->handleWindowEvent(evt.get(),false);

???????}

??? }

???evt->setCurrentTarget(0);

???evt->setEventPhase(0); // I guess this is correct, the spec does notseem to say

?????????????????????????? // anything aboutthe default event handler phase.

??? //Now call the post dispatch.

???postDispatchEventHandler(evt.get(), data);

? //now we call all default event handlers (this is not part of DOM - it isinternal to khtml)

???it.toLast();

??? if(evt->bubbles())

???????for (; it.current() && !evt->defaultPrevented() && !evt->defaultHandled();--it)

???????????EventTargetNodeCast(it.current())->defaultEventHandler(evt.get());

??? elseif (!evt->defaultPrevented() && !evt->defaultHandled())

???????EventTargetNodeCast(it.current())->defaultEventHandler(evt.get());

??? //deref all nodes in chain

???it.toFirst();

??? for(; it.current(); ++it)

???????it.current()->deref(); // this may delete us

???Document::updateDocumentsRendering();

??? //If tempEvent is true, this means that the DOM implementation

??? //will not be storing a reference to the event, i.e.? there is no

??? //way to retrieve it from javascript if a script does not already

??? //have a reference to it in a variable.? Sothere is no need for

??? //the interpreter to keep the event in it's cache

???Frame *frame = document()->frame();

??? if(tempEvent && frame && frame->scriptProxy())

???????frame->scriptProxy()->finishedWithEvent(evt.get());

??? return!evt->defaultPrevented(); // ### what if defaultPrevented was called beforedispatchEvent?

}
Event::Type {

? ???abort ??

??? ?beforecopy ??

??? ?beforecut ??

??? ?beforeload ??

??? ?beforepaste ??

??? ?beforeprocess ??

??? ?beforeunload ??

??? ?blocked ??

??? ?blur ??

??? ?cached ??

??? ?change ??

??? ?checking ??

??? ?click ??

??? ?close ??

??? ?complete ??

??? ?compositionend ??

??? ?compositionstart ??

??? ?compositionupdate ??

??? ?connect ??

??? ?contextmenu ??

??? ?copy ??

??? ?cut ??

??? ?dblclick ??

??? ?devicemotion ??

??? ?deviceorientation ??

??? ?display ??

??? ?downloading ??

??? ?drag ??

??? ?dragend ??

??? ?dragenter ??

??? ?dragleave ??

??? ?dragover ??

??? ?dragstart ??

??? ?drop ??

??? ?error ??

??? ?focus ??

??? ?focusin ??

??? ?focusout ??

??? ?hashchange ??

??? ?input ??

??? ?invalid ??

??? ?keydown ??

??? ?keypress ??

??? ?keyup ??

??? ?load ??

??? ?loadstart ??

??? ?message ??

??? ?mousedown ??

??? ?mousemove ??

??? ?mouseout ??

??? ?mouseover ??

??? ?mouseup ??

??? ?mousewheel ??

??? ?noupdate ??

??? ?obsolete ??

??? ?offline ??

??? ?online ??

??? ?open ??

??? ?overflowchanged ??

??? ?pagehide ??

??? ?pageshow ??

??? ?paste ??

??? ?popstate ??

??? ?readystatechange ??

??? ?reset ??

??? ?resize ??

??? ?scroll ??

??? ?search ??

??? ?select ??

??? ?selectstart ??

??? ?selectionchange ??

??? ?storage ??

??? ?submit ??

??? ?textInput ??

??? ?unload ??

??? ?updateready ??

??? ?versionchange ??

??? ?write ??

??? ?writeend ??

??? ?writestart ??

??? ?zoom ??

??? ?

??? ?DOMActivate ??

??? ?DOMFocusIn ??

??? ?DOMFocusOut ??

??? ?DOMAttrModified ??

??? ?DOMCharacterDataModified ??

??? ?DOMNodeInserted ??

??? ?DOMNodeInsertedIntoDocument ??

??? ?DOMNodeRemoved ??

??? ?DOMNodeRemovedFromDocument ??

??? ?DOMSubtreeModified ??

??? ?DOMContentLoaded ??

??? ?

??? ?webkitBeforeTextInserted ??

??? ?webkitEditableContentChanged ??

??? ?

??? ?canplay ??

??? ?canplaythrough ??

??? ?durationchange ??

??? ?emptied ??

??? ?ended ??

??? ?loadeddata ??

??? ?loadedmetadata ??

??? ?pause ??

??? ?play ??

??? ?playing ??

??? ?ratechange ??

??? ?seeked ??

??? ?seeking ??

??? ?timeupdate ??

??? ?volumechange ??

??? ?waiting ??

??? ?

??? ?webkitbeginfullscreen ??

??? ?webkitendfullscreen ??

??? ?

??? ?progress ??

??? ?stalled ??

??? ?suspend ??

??? ?

??? ?webkitAnimationEnd ??

??? ?webkitAnimationStart ??

??? ?webkitAnimationIteration ??

??? ?

??? ?webkitTransitionEnd ??

??? ?

??? ?orientationchange ??

??? ?

??? ?timeout ??

??? ?

??? ?touchstart ??

??? ?touchmove ??

??? ?touchend ??

??? ?touchcancel ??

?*#if PLATFORM(ANDROID)

??? ?touchlongpress ??

??? ?touchdoubletap ??

?*#endif * ??

??? ?

??? ?success ??

??? ?

??? ?loadend ??

??? ?

??? ?webkitfullscreenchange ??

??? ?

??? ?webkitspeechchange ??

??? ?

??? ?webglcontextlost ??

??? ?webglcontextrestored ??

??? ?webglcontextcreationerror ??

??? ?

??? ?audioprocess
}

總結

以上是生活随笔為你收集整理的WebKit DOM Event (一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。