This series will take a step-by-step look at the html5 specifications and technologies involved in order to improve our knowledge base. It is divided into three parts (recommended to read in order)

  • The HTML standard
  • Dom Standards (this article)
  • Other web API

The Document Object Model (DOM) associates a Web page with a Script or program language by representing an in-memory document structure. Note that using HTML, XML, and SVG as objects is not part of the core of the JS language. The DOM represents a document with a logical tree, each branch of which ends in a node, and each node contains an object. You can access the tree using DOM methods to modify document structure, style, or content. Nodes can also bind event handlers, which execute once an event is fired.

This specification defines a model for platform-independent events, cancellations, and tree of nodes.

1 Infrastructure

1.1 Trees

A tree is a tree structure with a finite hierarchy. The traversal order is depth-first traversal. An object participating in the tree has a parent, either null or another object; There are children, which are ordered objects. When an object and another object share the same parent, they are siblings.

2 Events

2.1 Introduction to DOM Events

Events across the Web platform are sent to all objects to indicate that an event has occurred, such as network activity or user interaction. Objects that implement the EventTarget interface can use addEventListener to add event listeners to monitor events. Event listeners can also be removed using removeEventListener() by passing the same parameter. Alternatively, event listeners can be AbortSignal and call abort(). Although events are basically triggered by user agents as a result of user interaction or completion of some task, programs can also use composite events to send events themselves

// add an appropriate event listener
obj.addEventListener("cat", function(e) { process(e.detail) })

// create and dispatch the event
var event = new CustomEvent("cat", {"detail":{"hazcheeseburger":true}})
obj.dispatchEvent(event)
Copy the code

In addition to signaling, events are sometimes used to allow the application to control what happens next after an action, such as if the event preventDefault() is called after a form submission and the form preventDefault is canceled.

When an event is sent to an object that participates in a tree (such as Element), it can reach the ancestor of that object. There are two phases: capture and bubble (for example, an event whose bubbles are true).

2.2 the Event interface

An Event object is called an Event and is used to indicate that something has happened, such as the completion of an image download. An event can be user behavior triggers, such as mouse clicks or said asynchronous behavior formation, the progress of the API can also be triggered by the program, such as call HTMLElement. Click () or a custom event EventTarget. DispatchEvent (). There are many types of events, including some that use other interfaces based on events, and events themselves that are used by properties and methods for all events

The constructor

new Event(typeArg[, eventInit])
Copy the code

Can be used to create an event instance, where typeArg represents the event name and the second represents the associated configuration (both Boolean values), including

  • The default value is false
  • Cancelable Specifies whether to cancel. The default value is false
  • Composed whether the composed triggers listeners outside of shadow root. The default is false
// create a look event that bubbles up and cannot be canceled

const evt = new Event("look", {"bubbles":true, "cancelable":false});
document.dispatchEvent(evt);

// event can be dispatched from any element, not only the document
myDiv.dispatchEvent(evt);
Copy the code

attribute

  • Event.bubbles Indicates whether bubbles can occur
  • CancelBubble Whether read/write bubbles? YesEvent.stopPropagation()Historical alias of
  • Event.cancelable Whether the Event can be cancelled
  • Event.composed event whether the bubble can cross the shadow DOM and regular DOM boundary
  • Event.currenttarget points to the current passing target
  • Whether event.defaultprevented has been calledevent.preventDefault()Cancel the event
  • EventPhase Indicates the phase of the Event flow. 0 to 4 indicates no Event, capture phase, Target, and bubbling phase, respectively
  • Event.returnValue Whether read and write is cancelled, introduced by IE for compatibility purposes, this standard is introduced but not recommended
  • Event.target The target from which the Event is originally sent
  • Event.timeStamp indicates the timeStamp when the Event was created
  • Event.type Indicates the Event type, case insensitive
  • Event.istrusted indicates whether the Event is triggered by the browser (true) or the script (false)

methods

  • Event.composedPath() returns a list of objects listening for the event
  • Cancel the Event. The preventDefault ()
  • Event. StopImmediatePropagation () to cancel other listening to the same Event listener
  • Event.stoppropagation () Cancels further propagation of events

2.3 Legacy extensions on the Window interface

An event attribute on the Window represents the current event object and is not recommended

2.4 CustomEvent interface

Based on the Event interface, it is used to create a custom Event. The content introduced on the Event interface refer to the corresponding part

// add an appropriate event listener
obj.addEventListener("cat", function(e) { process(e.detail) });

// create and dispatch the event
var event = new CustomEvent("cat", {
  detail: {
    hazcheeseburger: true
  }
});
obj.dispatchEvent(event);
Copy the code

The constructor has an extra detail configuration

 event = new CustomEvent(typeArg, customEventInit);
Copy the code

The second parameter has an additional configuration item detail, which represents the event-related value and defaults to NULL

2.5 the EventTarget interface

Implemented by an object that accepts events and may have listeners for the event. Element,Document, and Window are the most common event targets, but other objects can also be, such as XMLHttpRequest, AudioNode, and AudioContext. Many EventTargets also support setting event handlers through onEvent.

2.5.1 Constructors

var myEventTarget = new EventTarget();
Copy the code

You can create a new target with extends

class MyEventTarget extends EventTarget { constructor(mySecret) { super(); this._secret = mySecret; } get secret() { return this._secret; }}; let myEventTarget = new MyEventTarget(5); let value = myEventTarget.secret; // == 5 myEventTarget.addEventListener("foo", function(e) { this._secret = e.detail; }); let event = new CustomEvent("foo", { detail: 7 }); myEventTarget.dispatchEvent(event); let newValue = myEventTarget.secret; / / = = 7Copy the code

2.5.2 method

2.5.2.1 EventTarget. AddEventListener ()

Add a listener that performs a callback when a specific event is propagated to target

1) usage
target.addEventListener(type, listener, options);
target.addEventListener(type, listener, useCapture);
Copy the code

Type is the event type, listener is the callback (event is the parameter), and the third parameter has two types

  • Capture A Boolean value that indicates whether to fire during the capture phase
  • Once Specifies a Boolean value that indicates whether to execute only once
  • Passive Boolean: if it is true, the callback will not be invokedpreventDefault()Warning is reported if the user agent is actually invoked

When Boolean indicates whether to use it during the capture phase. This type parameter is reserved for compatibility with older browsers.

Note that the introduction refers to MDN, which is also currently implemented, and that the latest specification introduced another attribute of the third parameter, Signal, which is of type AbortSignal and is used to cancel listening callbacks, and is currently implemented in Node.js. Reference Feature: AbortSignal in addEventListener

2) Other listener registration methods

This method is introduced by Dom2, and there is another way for registered listeners to be introduced by Dom0

// Passing a function reference -- do not add '()' after it, which would call the function! el.onclick = modifyText; // Using a function expression element.onclick = function() { // ... function logic ... };Copy the code

This replaces event listening directly as an element attribute, which is compatible

3) why addEventListener
  • Allows multiple listeners to be registered
  • Fine control with the third parameter
  • Not only for Element, but for other targets as well
4) Improved scrolling performance with passive

Passive defaults to false according to the third parameter in the code. However, when scrolling is handled with touch or related events, the page will freeze because you need to check whether the default behavior has been canceled before scrolling. Therefore, some browsers will set passive to true by default. In addition, the Scroll event cannot cancel the default behavior, so it is not affected.

2.5.2.2 EventTarget. RemoveEventListener ()

Removing Event Listening

target.removeEventListener(type, listener[, options]);
target.removeEventListener(type, listener[, useCapture]);
Copy the code

Note that when matching the removed listener, the second and third parameters indicate the same captured parameters.

2.5.2.3 EventTarget. DispatchEvent ()

Used to dispatch a custom event, synchronously, while the browser dispatches the event asynchronously via the EventLoop

const event = new Event('build');

// Listen for the event.
elem.addEventListener('build', function (e) { /* ... */ }, false);

// Dispatch the event.
elem.dispatchEvent(event);
Copy the code

3 Aborting ongoing activities

Although Promises do not provide a built-in cancellation mechanism, many apis that use them require cancellation semantics. AbortController implements this requirement by providing abort methods. The API simply accepts an AbortSignal parameter and uses its state to decide what to do next. For example, if there’s doAmazingness({… }) methods have this requirement

const controller = new AbortController(); const signal = controller.signal; startSpinner(); doAmazingness({ ... , signal }) .then(result => ...) .catch(err => { if (err.name == 'AbortError') return; showUserErrorMessage(); }) .then(() => stopSpinner()); / /... controller.abort();Copy the code

To be able to cancel, doAmazingness can be done this way

function doAmazingness({signal}) {
  if (signal.aborted) {
    return Promise.reject(new DOMException('Aborted', 'AbortError'));
  }

  return new Promise((resolve, reject) => {
    // Begin doing amazingness, and call resolve(result) when done.
    // But also, watch for signals:
    signal.addEventListener('abort', () => {
      // Stop doing amazingness, and:
      reject(new DOMException('Aborted', 'AbortError'));
    });
  });
}
Copy the code

The Fetch method already implements this function

3.1 AbortController interface

You can instantiate a controller that has

  • An instance attribute, signal, which represents the current state and is passed to the relevant API, is an AbortSignal instance that contains the attribute aborTED and event Abort
  • An instance method abort is used to modify the signal attribute and fire the ABORT event

3.2 AbortSignal

That is the type of the signal property

4 Nodes

4.1 the dom is introduced

Dom refers to an API used to access and manipulate documents. Each document is represented by a node tree. Some nodes in the tree can have children, but others can only be leaves.

4.2 the Node tree

Document, DocumentType, DocumentFragment, Element, Text, ProcessingInstruction, and Comment object or Nodes all participate in a tree, This tree is called a Node tree

2 the document tree

Is a node tree whose root is document

4.2.2 Shadow tree

Root is a node tree for shadow root, related to Web Components, which we will discuss in §7.

Holdings Mutation algorithms

Here is the algorithm for inserting nodes

4.2.4 Mixin NonElementParentNode

Provides the ability to call getElementById on a parent element to find the corresponding element

4.2.5 DocumentOrShadowRoot

Used to define the API used by Documents and Shadow Roots

4.2.6 Mixin ParentNode

For all nodes that can contain children. Contains properties

  • ParentNode. ChildElementCount chidren
  • Parentnode. children A living HTMLCollection containing all child elements
  • ParentNode. FirstElementChild the first child
  • ParentNode. LastElementChild last child elements

Contains methods

  • ParentNode.append(… NodesOrDOMStrings) adds a series of nodes or strings to the end of the last child node, the string equivalent to the text node
  • ParentNode.prepend(… NodesOrDOMStrings inserts a series of nodes or strings before the first child
  • ParentNode.querySelector()
  • ParentNode.querySelectorAll()
  • ParentNode.replaceChildren()

4.2.7 Mixin NonDocumentTypeChildNode

Provide two properties for nodes that have a parent node

  • NonDocumentTypeChildNode previousElementSibling previous element at the same level
  • NonDocumentTypeChildNode. NextElementSibling after an element at the same level

4.2.8 Mixin ChildNode

Provides several methods for nodes that have parent nodes

  • ChildNode.remove()
  • ChildNode.before()
  • ChildNode.after()
  • ChildNode.replaceWith()

4.2.9 Old-style collections: NodeList and HTMLCollection

A collection represents a node list, the attention is just kind of array The NodeList is a collection of nodes, such as Node. The.childnodes or by the document. The querySelectorAll () returns, has a length attribute and several methods

  • Nodelist.item () returns index
  • NodeList.entries()
  • NodeList.forEach()
  • NodeList.keys()
  • NodeList.values()

HTMLCollection contains only HTML elements, such as Node.children, with a length attribute and two methods

  • HTMLCollection.item()
  • Htmlcollection.nameditem () is retrieved using the node ID or name attribute

4.3 Mutation observers

The Mutation Observer callback is a microtask

4.3.1 Interface MutationObserver

Provides the ability to monitor changes in the DOM tree by instantiating a MutationObserver to create a monitor that triggers a callback when the DOM changes. The callback contains two parameters: an array of mutationRecords that change, and a detector that calls the callback

const observer = new MutationObserver(callback)
Copy the code

The observe method that calls the monitor to configure which nodes to monitor and which changes to monitor is a MutationObserverInit object

mutationObserver.observe(target[, options])
Copy the code

The takeRecords() method returns changes that have been detected but not called back, in the form of a MutationRecord array

const mutationRecords = mutationObserver.takeRecords()
Copy the code

You can also call Disconnect () to stop monitoring

mutationObserver.disconnect()
Copy the code

Such as

// Select the node that will be observed for mutations const targetNode = document.getElementById('some-id'); // Options for the observer (which mutations to observe) const config = { attributes: true, childList: true, subtree: true }; // Callback function to execute when mutations are observed const callback = function(mutationsList, observer) { // Use traditional 'for loops' for IE 11 for(const mutation of mutationsList) { if (mutation.type === 'childList') { console.log('A child node has been added or removed.'); } else if (mutation.type === 'attributes') { console.log('The ' + mutation.attributeName + ' attribute was modified.'); }}}; // Create an observer instance linked to the callback function const observer = new MutationObserver(callback); // Start observing the target node for configured mutations observer.observe(targetNode, config); // Later, you can stop observing observer.disconnect();Copy the code

4.3.2 Interface MutationRecord

An object representing a single DOM variation that contains these properties

4.3.3 MutationObserverInit dictionary

Describes a monitoring configuration, and at least childList, Attributes, and/or characterData must be true, including

  • Subtree subtree
  • childList
  • attributes
  • attributeFilter
  • attributeOldValue
  • characterData
  • characterDataOldValue

4.4 Interface Node

Node is an abstract interface. The actual nodes used include Document, DocumentType, DocumentFragment, Element, Text, ProcessingInstruction, and Comment. Node is an EventTarget that contains properties and methods common to all nodes

4.4.1 properties

  • Node.nodeType Indicates the Node type
    • ELEMENT_NODE (1)
    • ATTRIBUTE_NODE (2);
    • TEXT_NODE (3)
    • CDATA_SECTION_NODE (4)
    • PROCESSING_INSTRUCTION_NODE (7)
    • COMMENT_NODE (8)
    • DOCUMENT_NODE (9)
    • DOCUMENT_TYPE_NODE (10)
    • DOCUMENT_FRAGMENT_NODE (11)
  • NodeName Specifies the Node name as a string
    • Element
    • Attr
    • Text
    • CDATASection
    • ProcessingInstruction
    • Comment
    • Document
    • DocumentType
    • DocumentFragment
  • Node.baseURI
  • Node.childNodes a NodeList containing all childNodes
  • Node.firstChild
  • Node.isConnected Specifies whether to connect to a context
  • Node.lastChild
  • Node.nextSibling
  • Node.nodeValue
  • Node.ownerDocument returns the corresponding document
  • Node.parentNode
  • Node.parentElement
  • Node.previousSibling
  • Node.textContent

4.4.2 method

  • Node.appendChild(childNode)
  • Node.cloneNode()
  • Node.compareDocumentPosition()
  • Node.contains()
  • Node.getBoxQuads()
  • Node.getRootNode()
  • Node.hasChildNodes()
  • Node.insertBefore()
  • Node.isDefaultNamespace()
  • Node.isEqualNode()
  • Node.isSameNode()
  • Node.lookupPrefix()
  • Node.lookupNamespaceURI()
  • Node.normalize()
  • Node.removeChild()
  • Node.replaceChild()

4.5 Interface Document

Document represents a DOM tree and provides a variety of properties and methods for Document

4.5.1 properties

Inherits and implements attributes on Node and EventTarget and ParentNode

  • Document.body returns the or node of the current Document
  • Document. The characterSet character set
  • Document.compatMode Specifies the strict mode or hybrid mode
  • Document.contentType minetype
  • Document.doctype Returns the Document Type Definition (DTD) of the current Document.
  • Document. The documentElement HTML elements
  • Document.documentURI
  • Document.embeds
  • Document.fonts
  • Document.forms
  • Document.head
  • Document.hidden
  • Document.images
  • Document.implementation
  • Document.lastStyleSheetSet
  • Document.links
  • Document. PictureInPictureEnabled picture in picture is available
  • Document.featurePolicy
  • Document.preferredStyleSheetSet
  • Document.scripts
  • Document.scrollingElement
  • Document.selectedStyleSheetSet
  • Document.styleSheetSets
  • Document.timeline
  • Document.visibilityState The visible state

For HTMLDocument extension

  • Document.cookie
  • Document.defaultView
  • Document.designMode
  • Document.dir
  • Document.domain
  • Document.lastModified
  • Document.location
  • Document.readyState
  • Document.referrer
  • Document.title
  • Document.URL

Defined from DocumentOrShadowRoot

  • DocumentOrShadowRoot.activeElement
  • Document.fullscreenElement
  • DocumentOrShadowRoot.pointerLockElement
  • DocumentOrShadowRoot.styleSheets

4.5.2 method

Methods on Node and EventTarget and ParentNode are inherited and implemented

  • Document.adoptNode()
  • Document.createAttribute()
  • Document.createAttributeNS()
  • Document.createCDATASection()
  • Document.createComment()
  • Document.createDocumentFragment()
  • Document.createElement()
  • Document.createElementNS()
  • Document.createEvent()
  • Document.createNodeIterator()
  • Document.createProcessingInstruction()
  • Document.createRange()
  • Document.createTextNode()
  • Document.createTouchList()
  • Document.createTreeWalker()
  • Document.enableStyleSheetsForSet()
  • Document.exitPictureInPicture()
  • Document.getElementsByClassName()
  • Document.getElementsByTagName()
  • Document.getElementsByTagNameNS()
  • Document.hasStorageAccess()
  • Document.importNode()
  • Document.requestStorageAccess()

For HTMLDocument extension

  • Document.close()
  • Document.execCommand()
  • Document.getElementsByName()
  • Document.hasFocus()
  • Document.open()
  • Document.queryCommandEnabled()
  • Document.queryCommandIndeterm()
  • Document.queryCommandState()
  • Document.queryCommandSupported()
  • Document.queryCommandValue()
  • Document.write()
  • Document.writeln()

Defined in DocumentOrShadowRoot

  • DocumentOrShadowRoot.caretPositionFromPoint()
  • DocumentOrShadowRoot.elementFromPoint()
  • DocumentOrShadowRoot.elementsFromPoint()
  • DocumentOrShadowRoot.getSelection()

4.5.3 event

Refer to the MDN for corresponding events

4.6 Interface DocumentType

Represents a node that contains a DOCType

4.7 Interface DocumentFragment

Document fragment, which can be used to batch insert nodes, inherits Node, and implements ParentNode

const list = document.querySelector('#list');
const fruits = ['Apple', 'Orange', 'Banana', 'Melon'];

const fragment = document.createDocumentFragment();

fruits.forEach(fruit => {
  const li = document.createElement('li');
  li.innerHTML = fruit;
  fragment.appendChild(li);
});

list.appendChild(fragment);
Copy the code

4.8 Interface ShadowRoot

Refer to the web component

4.9 Interface Element

Element is the base class for all Element objects, providing them with many attributes and methods. HTMLElement is the base class for HTML elements. Inheriting EventTarget,Node, implements ParentNode, ChildNode, NonDocumentTypeChildNode

4.9.1 NamedNodeMap

Represents a collection of Attr objects in no particular order

4.9.2 Attr

An object representing an attribute of a DOM Element can be obtained using element.getAttributenode (), and element.getAttribute () is a string.

4.9.3 properties

  • Element.attributes returns a NamedNodeMap of all attributes
  • ClassList A list of the element. classList class attributes
  • Element.className
  • Element.clientHeight can be calculated as CSS height + CSS padding-height of horizontal scrollbar (if present), if used on the root Element, The viewport height (not including the scrollbar) is returned and rounded to an integer for accurate data referenceelement.getBoundingClientRect()

  • Element.clientWidth
  • Element.clientLeft Width of the left border, if there is a scroll bar to the left.display:inlineIs always 0
  • Element.clientTop
  • Element.scrollHeight Height occupied without a scrollbar, including padding,::before and ::after, excluding margin and border

  • Element.scrollWidth
  • Element.scrollLeft takes advantage of how far the scroll bar scrolls to the left
  • Element.scrollTop
  • Element.computedName
  • Element.computedRole
  • Element.id
  • Element.innerHTML
  • Element.localName
  • Element.namespaceURI
  • Element.outerHTML
  • Element.part
  • Element.prefix
  • Element.shadowRoot
  • Element.tagName

4.9.4 method

  • Element.attachShadow()
  • Element.animate()
  • Element.closest()
  • Element.computedStyleMap()
  • EventTarget.dispatchEvent()
  • Element.getAnimations()
  • Element.getAttribute()
  • Element.getAttributeNames()
  • Element.getAttributeNS()
  • Element. GetBoundingClientRect () returns a DOMRect object, contains the Element size and relative to the distance of the viewport, Width or height property of the element + padding + border-width if it is a standard boxbox-sizing: border-boxIt’s equal to width or height

  • Element.getclientrects () returns a collection of DOMRect objects, usually only one, but multiple objects for multi-line inline elements
  • Element.getElementsByClassName()
  • Element.getElementsByTagName()
  • Element.getElementsByTagNameNS()
  • Element.hasAttribute()
  • Element.hasAttributeNS()
  • Element.hasAttributes()
  • Element.hasPointerCapture()
  • Element.insertAdjacentElement()
  • Element.insertAdjacentHTML()
  • Element.insertAdjacentText()
  • Element.matches()
  • Element.pseudo()
  • Element.querySelector()
  • Element.querySelectorAll()
  • Element.releasePointerCapture()
  • Element.removeAttribute()
  • Element.removeAttributeNS()
  • Element.requestFullscreen()
  • Element.requestPointerLock()
  • Element.scroll()
  • Element.scrollBy()
  • Element.scrollintoview () moves to the viewport
  • Element.scrollTo()
  • Element.setAttribute()
  • Element.setAttributeNS()
  • Element.setPointerCapture()
  • Element.toggleattribute () toggles the attribute

4.10 Interface CharacterData

An abstract interface to represent characters, implemented by Text, Comment, or ProcessingInstruction. Inheriting Node, implements ChildNode and NonDocumentTypeChildNode

4.10.1 properties

  • CharacterData.data
  • CharacterData.length

4.10.2 method

  • CharacterData.appendData()
  • CharacterData.deleteData()
  • CharacterData.insertData()
  • CharacterData.replaceData()
  • CharacterData.substringData()

4.11 Interface Text

Represents the text content of Element or Attr, inherited from CharacterData

4.11.1 properties

  • Text.wholeText
  • Text.assignedSlot

4.11.2 method

  • Text.splitText

4.12 Interface CDATASection

CDATA fragment, used in XML

4.13 Interface ProcessingInstruction

In the XML

4.14 Interface Comment

annotation

5 Ranges

StaticRange and Range both represent parts of a node tree. Batch Selection and modification can be performed in combination with Selection. Refer to MDN

6 Traversal

NodeIterator, NodeFilter, and TreeWalker can be used to iterate over and filter node trees

7 Sets

7.1 DOMTokenList

DOMTokenList is an interface that represents a set of tags separated by Spaces. Such as Element. The classList, HTMLLinkElement relList, HTMLAnchorElement. RelList, HTMLAreaElement. RelList, HTMLIframeElement sandbox, or HTMLOutputElement. HtmlFor return values, can be treated like an array from the subscript 0, for case sensitive

7.1.1 properties

  • DOMTokenList.length
  • DOMTokenList.value

7.1.2 method

  • DOMTokenList.item(index)
  • DOMTokenList.contains(token)
  • DOMTokenList.add(token1[, token2[, …tokenN]])
  • DOMTokenList.remove(token1[, token2[, …tokenN]])
  • DOMTokenList.replace(oldToken, newToken)
  • DOMTokenList.supports(token)
  • DOMTokenList.toggle(token [, force])
  • DOMTokenList.entries()
  • DOMTokenList.forEach(callback [, thisArg])
  • DOMTokenList.keys()
  • DOMTokenList.values()

7.1.3 the use case

For example, to add className

<p class="a b c"></p>
Copy the code
let para = document.querySelector("p");
let classes = para.classList;
para.classList.add("d");
para.textContent = `paragraph classList is "${classes}"`;
Copy the code

8 Web Components

MDN Web Components is a set of technical solutions for creating reusable custom elements. The corresponding techniques include

  • Custom elements. There are a number of apis that allow you to customize elements and their appearance. See Using Custom Elements
  • Shadow DOM: Bind an encapsulated shadow DOM tree to an element, which can be handled separately from the main Document tree. See Using shadow DOM
  • HTML templates,

The basic steps for implementing Web Components include

  1. Create a class to specify the functionality of the Web component
  2. useCustomElementRegistry.define()Registers a new custom element and passes it the name of the custom element, the class specifying the functionality of the element, and optionally the inherited element
  3. Use if neededElement.attachShadow()The shadow DOM method binds a shadow DOM to the custom element and then adds child elements, event listeners, and so on just as you would with a regular DOM
  4. If necessary, define the template with two corresponding elements, then clone the template again using normal DOM methods and bind it into the Shadow DOM
  5. Use custom elements anywhere on the page, just like regular HTML elements

This is the end of flower sprinkling