DOM

DOM

Source

Unfortunately, some event APIs have been designed such that implementing them efficiently
requires observing event listeners. This can make the presence of listeners observable in
that even empty listeners can have a dramatic performance impact on the behavior of the application.
For example, touch and wheel events which can be used to block asynchronous scrolling. In some cases
this problem can be mitigated by specifying the event to be cancelable only when there is
at least one non-passive listener. For example,
non-passive TouchEvent listeners must block scrolling, but if all
listeners are passive then scrolling can be allowed to start in parallel by making the TouchEvent uncancelable (so that calls to preventDefault() are ignored). So code dispatching an event is able to observe the absence
of non-passive listeners, and use that to clear the cancelable property of the event being dispatched.

Ideally, any new event APIs are defined such that they do not need this property (use public-script-coord@w3.org for discussion).

To dispatch an event to a target, with an optional legacy target override flag and an optional legacyOutputDidListenersThrowFlag, run these steps:

  1. Set event’s dispatch flag.

  2. Let targetOverride be target, if legacy target override flag is not given, and target’s associated Document otherwise. [HTML]

    legacy target override flag is only used by HTML and only when target is a Window object.

  3. Let activationTarget be null.

  4. Let relatedTarget be the result of retargeting event’s relatedTarget against target.

  5. If target is not relatedTarget or target is event’s relatedTarget, then:

    1. Let touchTargets be a new list.

    2. For each touchTarget of event’s touch target list, append the result of retargeting touchTarget against target to touchTargets.

    3. Append to an event path with event, target, targetOverride, relatedTarget, touchTargets, and false.

    4. Let isActivationEvent be true, if event is a MouseEvent object and event’s type attribute is "click"; otherwise false.

    5. If isActivationEvent is true and target has activation behavior, then set activationTarget to target.

    6. Let slottable be target, if target is a slottable and is assigned, and null otherwise.

    7. Let slot-in-closed-tree be false.

    8. Let parent be the result of invoking target’s get the parent with event.

    9. While parent is non-null:

      1. If slottable is non-null:

        1. Assert: parent is a slot.

        2. Set slottable to null.

        3. If parent’s root is a shadow root whose mode is "closed", then set slot-in-closed-tree to true.

      2. If parent is a slottable and is assigned, then set slottable to parent.

      3. Let relatedTarget be the result of retargeting event’s relatedTarget against parent.

      4. Let touchTargets be a new list.

      5. For each touchTarget of event’s touch target list, append the result of retargeting touchTarget against parent to touchTargets.

      6. If parent is a Window object, or parent is a node and target’s root is a shadow-including inclusive ancestor of parent, then:

        1. If isActivationEvent is true, event’s bubbles attribute is true, activationTarget is null, and parent has activation behavior, then set activationTarget to parent.

        2. Append to an event path with event, parent, null, relatedTarget, touchTargets, and slot-in-closed-tree.

      7. Otherwise, if parent is relatedTarget, then set parent to null.

      8. Otherwise, set target to parent and then:

        1. If isActivationEvent is true, activationTarget is null, and target has activation behavior, then set activationTarget to target.

        2. Append to an event path with event, parent, target, relatedTarget, touchTargets, and slot-in-closed-tree.

      9. If parent is non-null, then set parent to the result of invoking parent’s get the parent with event.

      10. Set slot-in-closed-tree to false.

    10. Let clearTargetsStruct be the last struct in event’s path whose shadow-adjusted target is non-null.

    11. Let clearTargets be true if clearTargetsStruct’s shadow-adjusted target, clearTargetsStruct’s relatedTarget, or an EventTarget object in clearTargetsStruct’s touch target list is a node and its root is a shadow root; otherwise false.

    12. If activationTarget is non-null and activationTarget has legacy-pre-activation behavior, then run activationTarget’s legacy-pre-activation behavior.

    13. For each struct in event’s path, in reverse order:

    14. For each struct in event’s path:

  6. Set event’s eventPhase attribute to NONE.

  7. Set event’s currentTarget attribute to null.

  8. Set event’s path to the empty list.

  9. Unset event’s dispatch flag, stop propagation flag, and stop immediate propagation flag.

  10. If clearTargets, then:

  11. If activationTarget is non-null, then:

  12. Return false if event’s canceled flag is set; otherwise true.

To append to an event path, given an event, invocationTarget, shadowAdjustedTarget, relatedTarget, touchTargets, and a slot-in-closed-tree, run these
steps:

To invoke, given a struct, event, phase, and an optional legacyOutputDidListenersThrowFlag,
run these steps:

  1. Set event’s target to the shadow-adjusted target of the last struct in event’s path, that is either struct or preceding struct, whose shadow-adjusted target is non-null.

  2. Set event’s relatedTarget to struct’s relatedTarget.

  3. Set event’s touch target list to struct’s touch target list.

  4. If event’s stop propagation flag is set, then return.

  5. Initialize event’s currentTarget attribute to struct’s invocation target.

  6. Let listeners be a clone of event’s currentTarget attribute value’s event listener list.

    This avoids event listeners added after this point from being run. Note that removal still has an effect due to the removed field.

  7. Let invocationTargetInShadowTree be struct’s invocation-target-in-shadow-tree.

  8. Let found be the result of running inner invoke with event, listeners, phase, invocationTargetInShadowTree, and legacyOutputDidListenersThrowFlag if given.

  9. If found is false and event’s isTrusted attribute is true, then:

    1. Let originalEventType be event’s type attribute value.

    2. If event’s type attribute value is a match for any of the strings in the first column in the following table, set event’s type attribute value to the string in the second column on the same row as the matching string, and return otherwise.

      Event type Legacy event type "animationend" "webkitAnimationEnd" "animationiteration" "webkitAnimationIteration" "animationstart" "webkitAnimationStart" "transitionend" "webkitTransitionEnd"
    3. Inner invoke with event, listeners, phase, invocationTargetInShadowTree, and legacyOutputDidListenersThrowFlag if given.

    4. Set event’s type attribute value to originalEventType.

To inner invoke, given an event, listeners, phase, invocationTargetInShadowTree,
and an optional legacyOutputDidListenersThrowFlag, run these steps:

  1. Let found be false.

  2. For each listener in listeners, whose removed is false:

    1. If event’s type attribute value is not listener’s type, then continue.

    2. Set found to true.

    3. If phase is "capturing" and listener’s capture is false, then continue.

    4. If phase is "bubbling" and listener’s capture is true, then continue.

    5. If listener’s once is true, then remove listener from event’s currentTarget attribute value’s event listener list.

    6. Let global be listener callback’s associated Realm’s global object.

    7. Let currentEvent be undefined.

    8. If global is a Window object, then:

    9. If listener’s passive is true, then set event’s in passive listener flag.

    10. Call a user object’s operation with listener’s callback, "handleEvent", « event », and event’s currentTarget attribute value. If this throws an exception, then:

      1. Report the exception.

      2. Set legacyOutputDidListenersThrowFlag if given.

        The legacyOutputDidListenersThrowFlag is only used by Indexed Database API. [INDEXEDDB]

    11. Unset event’s in passive listener flag.

    12. If global is a Window object, then set global’s current event to currentEvent.

    13. If event’s stop immediate propagation flag is set, then return found.

  3. Return found.

To fire an event named e at target,
optionally using an eventConstructor, with a description of how IDL attributes are to be
initialized, and a legacy target override flag, run these steps:



Read Next page

Report Page