Dachang technology adhere to the week more selected good articlesCopy the code

Why use frames?

Understanding the framework

As a modern front-end developer, embracing frameworks is a must for survival. Some of you jumped right in, and some of you have been lucky enough to see the evolution, from native, to JQ, to frameworks today. At present, vue, React and Angular occupy the largest market share in China. They all have their own characteristics, which are the basis of their foothold along the way.

As users, we need a certain degree of understanding of the framework itself while using it to efficiently deal with business, so as to help us better learn, understand and apply the framework. Here is a table from Yu’s own comparison of the three frameworks, which may improve our understanding of them to some extent.

Meaning of areas of responsibility:

  • The large scope of responsibility makes it easy for developers to dump problems on the framework,
  • The small scope of responsibility makes it customary for developers to dump problems on the community.

Advantages of frameworks

Based on the differences between the frameworks mentioned above, we can see that the different design, development, and derived ecology of each framework are actually derived from the original definition of the scope of responsibility of each. But despite their differences, they still have commonalities, and commonalities come from the meaning and purpose of the framework itself.

If you look back, you will see that all frameworks have the same characteristics and goals, which are based on native features, and then higher efficiency, better performance, and better differentiation.

But we need to correctly understand the words, this does not mean that the framework of the indicators are better than the native, but said that because of the framework, we don’t need handwritten don’t rely on data from the business scenario – view of binding, don’t have to manually wipe flat or the difference between the browser and no longer in operation of the dom performance even at the same time. It can be said that the framework raises the bar for developers to develop and implement features, allowing for a better balance between rapid development and basic performance. Take React and VUE as examples. The advantages brought by these two frameworks include but are not limited to:

  • Data binding (single/bidirectional)
  • Componentized development (various hooks/lifecycle/scope isolation)
  • Virtual DOM (DIff algorithm) and routing, etc.
  • .

But these advantages don’t come out of nowhere, like vue’s bidirectional binding, such as switching from Object.defineProperty to proxy, which requires JS syntax and browser native support at its core. Because web applications ultimately run on the host, the browser, it is the specification of major browser vendors and browser environments that provide native API support, not the framework. The reason why we need to introduce various frameworks and tool libraries to realize various excellent designs and ideas, such as componentization, is that the original does not directly provide corresponding methods or APIS, so we need the framework to build another layer of rules system on the board to realize the demands of developers.

Framework, a higher level of encapsulation on top of the browser’s native rules, brings convenience and efficiency, but inevitably brings two defects:

  • Performance degradation, which is why I mentioned above that sometimes native direct action metrics are better than frameworks. Here are some comparisons of react vs JS handling the DOM:

Figure 1: Desktop Chrome; Figure 2: Chrome tablet; Figure 3: chrome on mobile;)React VS JS memory on Chrome

  • The isolation of the framework environment, such as vue’s component library, did not mesh well with the React project (you might say Vuera or microfront-end, but the reality is that ROI and performance are not good and development and maintenance costs are high).

So if native can provide some API, can it replace some functions of the framework to a certain extent? While having convenience and efficiency, cross-platform and cross-framework use can also maintain the performance of native to a greater extent?

That’s where the next thing to talk about is Web Components and what they can possibly even revolutionize.

Understanding the web component

web component

In a narrow sense, Web Components are new natively supported apis and templates provided by the browser environment. Broadly speaking, it is a set of technologies that enable componentization of native implementations. As can be seen from the description of MDN, The birth of Web Component is to solve the problems of code reuse, component customization, reuse management and so on.

The solution to these development pain points already exists, namely, componentization in the corresponding framework advantage. So according to the above analysis, now that native support, does that mean we can subvert the framework? This is a bit of an impulse. It is unrealistic to subvert a framework solely by relying on native apis, and it has to be a framework that can subvert a framework, because each framework implies a corresponding ecology (routing management, state management, DOM performance optimization management, etc.). If, one day, most of the best design and ideas in the current framework are absorbed and supported by the native environment, then the framework derived from this foundation can truly replace the current three frameworks and become the only type of framework on the front end.

Now, while we still can’t get rid of frameworks to embrace the original, we can replace some of them with the advantages provided by frameworks without the drawbacks caused by frameworks.

Can native componentization replace framework componentization?

Let’s first look at the characteristics of componentization:

  • High cohesion, low coupling
  • Marked and easy to maintain
  • Block interfaces are easy to expand

Looking at the componentized specification, framework componentization provides us with the most intuitive experience:

  • Efficient reuse
  • Scope and style isolation
  • Custom development
  • Hook functions (lifecycle)
  • .

Finally, let’s look at what the Web Component gives us:

  • Custom Elements: Custom elements. By using the corresponding API, users can develop Custom elements at the native level without relying on the framework. Most importantly, it will have a separate lifecycle and provides listeners for Custom attributes. This means it is also highly maneuverable.
  • Shadow DOM: The Shadow DOM is not globally exposed. You can use the corresponding API to attach the Shadow DOM to your custom elements and control their functions. Use the features of shadow DOM to isolate features and keep them secret, so you don’t have to worry about writing scripts and styles that conflict with other parts of the document.
  • The HTML templateThrough:<template/>,<slot/>To implement content distribution. Or you can recall vue slots and React props. Children. But did Vue actually create slot in the first place? See below ~

The features provided by these native apis suggest that Web Components can also be used for component customization and reuse, isolation from the rest of the document, lifecycle hook functions, and even content distribution. At least in theory, Web Components are capable of replacing framework componentization, meaning that developers can componentize without using a framework and that components can be seamlessly embedded in projects that use the framework. Interestingly, the use of web component was also introduced in the latest release of vue3.2:

compatibility

As a developer, you need to be enthusiastic about new and powerful apis, but also pay attention to their availability and reach. Can I use to check its compatibility: caniuse.com/?search=web… . We can see from it:

1. Custom Elements compatibility

2. Shadow DOM compatibility

3. HTML Templates Compatibility

Custom elements and custom built-in elements

In the description of Custom Elements compatibility, we see two concepts as follows:

  • Custom elements: independent elements; They do not inherit from built-in HTML elements.
  • Custom built-in elements: These elements inherit and extend the built-in HTML elements.

So how do you understand custom elements and custom built-in elements here? We can observe this from a specific code implementation:

  • Custom elements
js: 
... 
customElements.define('custom-elements'.class); .html: 
<body>.<custom-elements></custom-elements>.</body> 
Copy the code
  • Custom built-in elements
js:
...
customElements.define('custom-elements'.class.{ extends: 'p'}); .html:
<body>.<p is="custom-elements"></p>.</body>
Copy the code

You can see that there is not much difference in the declaration. The declaration is defined by customElements. Define, and a class is required to build the internal lifecycle and attribute listening. The difference is that custom built-in elements need to set the built-in HTML elements (i.e. native elements) to inherit in a later configuration item.

The biggest difference is in use. A custom element is a complete custom component that allows you to componentize without relying on any framework. The custom built-in component can be understood as the modification of the inherited native element (such as the above code presentation, when declaring a custom component, specify the inherited native element, and when using the native element later, the native element can be modified by referring to the declared custom component through the IS attribute. Life cycle, custom components, and scope isolation capabilities).

Use of the Web Component API

Custom component declaration and use

The main interface relied on is CustomElementRegistry, which is provided to support the use and declaration of custom components:

  • Window. CustomElements. Define.

    This method is used to declare a custom component that takes three parameters and returns no value:

    1. Name: Custom component name (must be underlined) to be registered globally.
    2. Constructor: a class that must inherit from HTMLElement if it declares custom elements; If you declare a custom built-in element, you must inherit from the class of the native element it is extending (HTMLDivElement must be inherited to extend div, for example). And in the constructor of the class, you must execute super.
    3. Options: An optional configuration object that is only used when declaring custom built-in elements. Currently there is only one configuration item extends, and the value is the label name of the native element to be extended.

Example declaration:

// Custom elements
class CustomEle extends HTMLElement { 
  constructor() { 
    super(a); . } } customElements.define('custom-ele', CustomEle); 
 
// Customize the built-in element if you want to extend div
class CustomEleBuiltIn extends HTMLDivElement { 
  constructor() { 
    super(a); . } } customElements.define('custom-ele-build-in', CustomEleBuiltIn, { extends: 'div' }); 
Copy the code

There are many ways to use it. It can be used as document.createElement or written directly in HTML. Example:

// Custom elements
const customEle = document.createElement('custom-ele'); 
customEle.setAttribute('img'.'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201409%2F06%2F20140906020558_h 4VfY.png'); 
customEle.setAttribute('text'.'I'm a hover note'); 
document.querySelector('#app').appendChild(customEle); 
customElements.define('custom-ele', CustomEle); 
/ / or
customElements.define('custom-ele', CustomEle); 
const customEle = new CustomEle(); 
customEle.setAttribute('img'.'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201409%2F06%2F20140906020558_h 4VfY.png'); 
customEle.setAttribute('text'.'I'm a hover note'); 
document.querySelector('#app').appendChild(customEle); 
/ / or
<custom-ele img="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201409%2F06%2F20140906020558_h 4VfY.png" text="I am a hover instruction.">CustomElements. Define ('custom-ele-build-in', CustomEleBuiltIn, {extends: 'div'}); const div = document.createElement('div', { is: 'custom-ele-build-in' }); div.setAttribute('img', 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201409%2F06%2F20140906020558_h 4VfY.png'); Div. SetAttribute ('text', 'I am a hover statement '); document.querySelector('#app').appNode.appendChild(div); / / or<div is="custom-ele-build-in" img="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201409%2F06%2F20140906020558_h 4VfY.png" text="I am a hover instruction." /> 
Copy the code

There are some differences in the use of these methods. During initialization, the direct reference method can get the mounted properties at the construction stage. However, with create, the construction phase does not get the properties in the first place. Of course, the lifecycle hook function is also used to solve this problem.

  • Window. CustomElements. Get.

This method is used to get the constructor of a custom component, taking one parameter, the declared name of the custom component, and returning the constructor.

const getCustomConstructorBefore = customElements.get('custom-ele'); 
console.log('getCustomConstructor-before', getCustomConstructorBefore);//undefined 
customElements.define('custom-ele', CustomEle); 
const getCustomConstructorAfter = customElements.get('custom-ele'); 
console.log('getCustomConstructor-after', getCustomConstructorAfter);//CustomEle 
Copy the code
  • Window. CustomElements. Upgrade.

This method is used to update the custom component containing the Shadow DOM before the main document is mounted. It takes one parameter, the custom component node containing the Shadow DOM, and returns no value. Custom components trigger automatic updates when they are appended to the main document.

// Create a custom element first
const customEle = document.createElement('custom-ele'); 
customEle.setAttribute('img'.'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201409%2F06%2F20140906020558_h 4VfY.png'); 
customEle.setAttribute('text'.'I'm a hover note'); 
// Declare the custom element
customElements.define('custom-ele', CustomEle); 
// Result is false, null
console.log(customEle instanceof CustomEle, customEle.shadowRoot); 
// Update the node
customElements.upgrade(customEle);/ / or document. QuerySelector (' # app). The appendChild (customEle);
/ / true, # document - fragments
console.log(customEle instanceof CustomEle, customEle.shadowRoot); 
Copy the code

  • Window. CustomElements. WhenDefined.

This method is used to detect and provide a time when the custom component has been declared. It accepts a parameter, the name of the custom element, and returns a promise(only to detect whether the custom component has been defined, not whether it is mounted in the main document). If the supplied name is invalid, a catch of the promise is triggered.

// create the custom element DOM
const customEle = document.createElement('custom-ele'); 
customEle.setAttribute('img'.'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201409%2F06%2F20140906020558_h 4VfY.png'); 
customEle.setAttribute('text'.'I'm a hover note'); 
// Stop timer
let isStop = false; 
// Get the time when the custom component is defined
customElements.whenDefined('custom-ele').then(() = > { 
  console.log('Defined'); 
  isStop = true; 
}); 
// A timer for observation
const timer = setInterval(() = > { 
  if (isStop) { 
    clearInterval(timer); 
    return; 
  } 
  console.log(Math.floor(Date.now() / 1000)); 
}, 1000); 
// Delay 3 seconds for the definition and declaration of custom components
setTimeout(() = > { 
  customElements.define('custom-ele', CustomEle); 
}, 3000) 
Copy the code

Customize the component lifecycle

  • constructor

The first life cycle of a custom component, used to initialize the custom component itself. This is triggered when the custom component is defined by document.createElement (if the component has been defined by customElements. Define). Constructor is executed when append is in the main document.

class CustomEle extends HTMLElement { 
  constructor() { 
    super(a);console.log('Constructor executed'); . } } customElements.define('custom-ele', CustomEle); 
const customEle = document.createElement('custom-ele'); 
Copy the code

  • connectedCallback

The lifecycle that is triggered when a component is successfully added to the main document, after Constructor.

class CustomEle extends HTMLElement { 
  constructor() { 
    super(a);console.log('Constructor executed'); . } connectedCallback () {console.log('connectedCallback executed '); 
  } 
} 
 
customElements.define('custom-ele', CustomEle); 
const customEle = document.createElement('custom-ele'); 
document.querySelector('#app').appendChild(customEle); 
Copy the code

  • attributeChangedCallback

One of the most critical life cycles for customizing components. Trigger time is when component properties are added, deleted, or modified. If you set the property before the component is append, it will fire before connectedCallback; Otherwise, it is fired after connectedCallback. This is done in conjunction with the static observedAttributes method, where only attributes registered in observedAttributes are listened on.

class CustomEle extends HTMLElement { 
  constructor() { 
    super(a);console.log('Constructor executed'); . } connectedCallback () {console.log('connectedCallback executed '); 
  } 
  static get observedAttributes () { return [ 'img'.'text' ]; } 
  attributeChangedCallback (name, oldValue, newValue) { 
    console.log('attributeChangedCallback', name) 
    if (name === 'img') { 
      this.shadowRoot.querySelector('img').src = this.getAttribute('img'); 
    } 
    if (name === 'text') { 
      this.shadowRoot.querySelector('.info').textContent = this.getAttribute('text'); 
    } 
  } 
} 
 
customElements.define('custom-ele', CustomEle); 
customEle.setAttribute('img'.'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201409%2F06%2F20140906020558_h 4VfY.png'); 
customEle.setAttribute('text'.'I'm a hover note'); 
const customEle = document.createElement('custom-ele'); 
document.querySelector('#app').appendChild(customEle); 
Copy the code

  • adoptedCallback

Called when an element is moved to a new document. That is, the element is an element of another document, and adoptedCallback is a callback to a custom component under the new document.

// Declare a custom component class
class CustomEle extends HTMLElement { 
  constructor() { 
    super(a); . } adoptedCallback () {console.log('adoptedCallback executed '); }}// Create the scene and add the iframe, which is the old document
appNode.innerHTML = '<iframe></iframe>'; 
const p = document.createElement('p'); 
p.innerHTML = 'iframe'; 
appNode.querySelector('iframe').contentWindow.document.body.appendChild(p); 
 
// Create a custom component in a new document
const customEle = document.createElement('custom-ele'); 
customEle.setAttribute('img'.'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201409%2F06%2F20140906020558_h 4VfY.png'); 
customEle.setAttribute('text'.'I'm a hover note'); 
customElements.define('custom-ele', CustomEle); 
appNode.appendChild(customEle); 
 
// Migrate elements from the old document to the new document
setTimeout(() = > { 
  console.log('Start the adoptNode operation on the element') 
  const node = appNode.querySelector('iframe').contentWindow.document.body.firstElementChild; 
  appNode.appendChild(document.adoptNode(node)) 
}, 2000); 
Copy the code

This callback function is not often used, so understand.

  • disconnectedCallback

The last life cycle of a custom component, triggered when the component is successfully removed from the master document.

class CustomEle extends HTMLElement { 
  constructor() { 
    super(a); . } disconnectedCallback () {console.log('disconnectedCallback executed '); 
  } 
} 
 
customElements.define('custom-ele', CustomEle); 
const customEle = document.createElement('custom-ele'); 
document.querySelector('#app').appendChild(customEle); 
setTimeout(() = > { 
  appNode.removeChild(customEle); 
}, 2000) 
Copy the code

Note: disconnectedCallback is not triggered when the browser is closed or tabs are closed.

Use of Shadow DOM

The purpose is to hide markup structure, style, and behavior from the rest of the code on the page. Shadow DOM is not new. Browsers have used it for a long time to encapsulate the inner structure of elements. Recall the hidden control buttons inside the video tag.

  • AttachShadow DOM to the element: el.attachshadow

AttachShadow takes an object parameter. Just look at the configuration attribute mode. If it is set to open, it means that elements inside the Shadow DOM can be obtained from outside. If set to Closed, the interior of the Shadow DOM is hidden, for example.

class CustomEle extends HTMLElement { 
  constructor() { 
    super(a);const shadow = this.attachShadow({ mode: 'open'}); . } } customElements.define('custom-ele', CustomEle); 
const customEle = document.createElement('custom-ele'); 
document.querySelector('#app').appendChild(customEle); 
console.log(customEle.shadowRoot) 
Copy the code

If mode is set to Closed:

  • Manipulate the element’s Shadow DOM and add styles

    When you attach a Shadow DOM to an element, you can manipulate it in the same way you would a normal DOM. The following is an example:

class CustomEle extends HTMLElement { 
  constructor() { 
    super(a);const shadow = this.attachShadow({ mode: 'open' }); 
 
    const wrapper = document.createElement('span'); 
    wrapper.setAttribute('class'.'wrapper'); 
 
    const icon = document.createElement('span'); 
    icon.setAttribute('class'.'icon'); 
 
    const info = document.createElement('span'); 
    info.setAttribute('class'.'info'); 
 
    const text = this.getAttribute('text'); 
    info.textContent = text; 
 
    const img = document.createElement('img'); 
    img.src = this.getAttribute('img'); 
    icon.appendChild(img); 
 
    const style = document.createElement('style'); 
    // console.log('CustomEle', style.isConnected); 
    style.textContent = ` .wrapper { position: relative; }.info {font-size: 0.8rem; width: 200px; display: inline-block; border: 1px solid black; padding: 10px; background: white; border-radius: 10px; opacity: 0; The transition: 0.6 s all; position: absolute; bottom: 20px; left: 10px; z-index: 3; } img {width: 1.2rem; } .icon:hover + .info, .icon:focus + .info { opacity: 1; } `; 
    shadow.appendChild(style); 
    // console.log('CustomEle', style.isConnected); shadow.appendChild(wrapper); wrapper.appendChild(icon); wrapper.appendChild(info); }}const customEle = document.createElement('custom-ele'); 
customEle.setAttribute('img'.'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201409%2F06%2F20140906020558_h 4VfY.png'); 
customEle.setAttribute('text'.'I'm a hover note'); 
customElements.define('custom-ele', CustomEle); 
document.querySelector('#app').appendChild(customEle); 
Copy the code

If you want to add a style sheet, you can add the code in the above code:

const style = document.createElement('style'); 
    // console.log('CustomEle', style.isConnected); 
    style.textContent = ` .wrapper { position: relative; }.info {font-size: 0.8rem; width: 200px; display: inline-block; border: 1px solid black; padding: 10px; background: white; border-radius: 10px; opacity: 0; The transition: 0.6 s all; position: absolute; bottom: 20px; left: 10px; z-index: 3; } img {width: 1.2rem; } .icon:hover + .info, .icon:focus + .info { opacity: 1; } `; 
    shadow.appendChild(style); 
Copy the code

Replace with:

const linkElem = document.createElement('link'); 
linkElem.setAttribute('rel'.'stylesheet'); 
linkElem.setAttribute('href'.'style.css');// The address of the style
 
shadow.appendChild(linkElem); 
Copy the code

Note that since the link element does not interrupt shadow root’s drawing, unstyled content (FOUC) may appear when the stylesheet is loaded, causing flickering.

template

  • template

Content that uses a wrapper is not displayed on the page, but can be referenced by JS. This means that instead of building something over and over again, use a build once and reference it multiple times.

class CustomEle extends HTMLElement { 
  constructor() { 
    super(a);console.log('Constructor executed'); 
    const shadow = this.attachShadow({ mode: 'open' }); 
 
    let template = document.getElementById('my-paragraph'); 
    if (template) { 
      let templateContent = template.content; 
      shadow.appendChild(templateContent.cloneNode(true)); }... } } appNode.innerHTML ='
      '; 
const customEle = document.createElement('custom-ele'); 
customEle.setAttribute('img'.'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201409%2F06%2F20140906020558_h 4VfY.png'); 
customEle.setAttribute('text'.'I'm a hover note'); 
customElements.define('custom-ele', CustomEle); 
appNode.appendChild(customEle); 
Copy the code

  • slot
    • More flexible content distribution, based on template, can be used with Template (define placeholders in template, then clone the content of template into shadow DOM). You can also add placeholders directly to the Shadow DOM.

You can then use it in innerHTML of your custom component.

class CustomEle extends HTMLElement { 
  constructor() { 
    super(a);console.log('Constructor executed'); 
    const shadow = this.attachShadow({ mode: 'open' }); 
 
    let template = document.getElementById('my-paragraph'); 
    if (template) { 
      let templateContent = template.content; 
      shadow.appendChild(templateContent.cloneNode(true)); 
    } 
    const slot2 = document.createElement('slot'); 
    slot2.setAttribute('name'.'newText2'); shadow.appendChild(slot2); . } } appNode.innerHTML ='
      
      
       

newText1

'
; const customEle = document.createElement('custom-ele'); customEle.innerHTML = '<p slot="newText2">newText2</p>'; customElements.define('custom-ele', CustomEle); appNode.appendChild(customEle); Copy the code

  • Slotchange: Listens for slot insertion or removal events in the Shadow DOM.
class CustomEle extends HTMLElement { 
  constructor() { 
    super(a);let template = document.getElementById('my-paragraph'); 
    if (template) { 
      let templateContent = template.content; 
      shadow.appendChild(templateContent.cloneNode(true)); 
    } 
    const slots = shadow.querySelectorAll('slot'); 
    slots.forEach(slot= > { 
      slot.addEventListener('slotchange'.function (e) { 
        console.log('slotchange', slot.name, e); }); }); . } } appNode.innerHTML ='<template id="my-paragraph">' + 
  '' + 
  '<slot name="newText1"></slot>' + 
  '<slot name="spanText"></slot>' + 
  '</template>' + 
  '<h3>' + 
  '<custom-ele class="newText1Box">' + 
  '<p slot="newText1">newText1</p>' + 
  '<span slot="spanText">spanText</span>' + 
  '</custom-ele>' + 
  '</h3>'; 
setTimeout(() = > { 
  document.querySelector('.newText1Box').removeChild(document.querySelector('.newText1Box p')); 
  / / or
  document.querySelector('.newText1Box p').removeAttribute('slot'); 
}, 2000The SlotChange event is raised when a slot is added (insert elements with slot attributes or add slot attributes to inserted elements) or when a slot is removed (remove elements with slot attributes or removeAttribute slot attributes to inserted elements).Copy the code

Other related apis

  • Element. attachShadow(opt) : Used to attach the shadow DOM to the specified element.

    Opt configuration items:

    • Mode: If it is open, the shadow DOM node can be obtained externally through Element. shadowRoot. And the method returns a shadow DOM object. Closed indicates that external access to the Shadow DOM node is not allowed, and the method returns NULL.
    • DelegatesFocus: Indicates whether to alleviate the focus performance problem of a custom element. When the non-focusable part of the Shadow DOM is clicked, make the first focusable part of the Shadow DOM focus, and shadow Host will provide all available :focus styles.
  • CSS pseudo-classes are:

    • Defined: indicates all built-in elements and those registered with customElements. Define: indicates all built-in elements and those registered with customElements.
    • :host: can only be written in the shadow DOM style sheet. Represents all instances of the current custom component and all elements under shadow DOM.
    • :host([selector]) : can only be written in the shadow DOM style sheet. Is an enhancement to :host, which represents all instances of the custom component in which :host() is located that have selectors matching the names in parentheses and all elements under the shadow DOM they contain.
    • :host-context([selector]) : can only be written in the shadow DOM style sheet. Is an enhancement to host, which means :host()-context is the parent element of all instances of the custom component in which the selector matches the name in parentheses and all elements under the shadow DOM it contains.
    • : Slotted ([selector]): Is written only in the Shadow DOM style sheet. Represents: All instances of the custom component slotted() where selectors match the slot element named in parentheses, or if the selectors are *, all slots are hit.
  • Node dependent expansion

    • GetRootNode: the use mode is ele.getrootNode (opt), which contains an attribute composed. When it is true, the retrieved root element is document. When false, if ele belongs to the Shadow DOM, then the shadow DOM is retrieved, otherwise document is retrieved.
    • IsConnected: is a read-only attribute interface to the element. Returns a Boolean value that indicates whether the element is connected to the DOM tree. That is, whether to append to the main document.
  • The event extension

    • Composed property: Indicates whether the event can be passed from the Shadow DOM to the normal DOM(true for both the normal and Shadow DOM after testing).
    • Path property: Returns the path of the event. If shadow root is created using mode closed, then nodes in the shadow tree are not included. (Shadowdom can still get the full path even though mode closed is set.)
  • About the slot

    • Ele. AssignedSlot: Get the element representing the insert slot on the ele element. However, if mode in ele.attachShadow is closed, null is returned.
    • Ele. slot: Used to get the name value of the slot on the element.
  • .

Related libraries and websites

  • Webcomponents.org — Site featuring Web Components examples, tutorials, and Other information.
  • Hybrids — Open source web components library, which favors plain objects and pure functions over class and this syntax. It provides a simple and functional API for creating custom elements.
  • Polymer — Google’s web components framework — a set of polyfills, enhancements, and examples. Currently the easiest way to use web components cross-browser.
  • Snuggsi.es- Easy Web Components in ~1kBIncluding polyfill— All you need is a browser and basic understanding of HTML, CSS, and JavaScript classes to be productive.
  • Slim. Js — Open Source Web Components Library — a high-performant library for Rapid and easy Component authoring; extensible and pluggable and cross-framework compatible.
  • Smart.js – Web Components Library with Simple API for Creating cross-Browser custom Elements
  • Stencil — Toolchain for Building Reusable, Scalable design Systems in Web Components.

reference

Developer.mozilla.org/zh-CN/docs/… Medium.com/jspoint/the… www.ruanyifeng.com/blog/2019/0… Html.spec.whatwg.org/multipage/c… Developers. Google. Cn/web/fundame… Objectpartners.com/2015/11/19/… Bugs.webkit.org/show_bug.cg…

❤️ Thank you

That is all the content of this sharing. I hope it will help you

Don’t forget to share, like and bookmark your favorite things.

Welcome to pay attention to the public number ELab team receiving factory good article ~

We are from the front end department of Bytedance, responsible for the front end development of all bytedance education products.

We focus on product quality improvement, development efficiency, creativity and cutting-edge technology and other aspects of precipitation and dissemination of professional knowledge and cases, to contribute experience value to the industry. Including but not limited to performance monitoring, component library, multi-terminal technology, Serverless, visual construction, audio and video, artificial intelligence, product design and marketing, etc.

Interested students are welcome to post in the comments section or use the internal tweet code to the author’s section at 🤪

Bytedance calibration/social recruitment internal promotion code: QF2RCT8

Delivery link: jobs.toutiao.com/