La position actuelle:Accueil du site>Composants web - cycle de vie des éléments personnalisés

Composants web - cycle de vie des éléments personnalisés

2022-07-23 11:21:53Pyjama oriental

J'ai dû comprendre Web Component,Savoir jouer,Mais il y a eu quelques erreurs avant de les trouver après avoir consulté les données

Node.cloneNode Les limites de

Avant,Utilisétemplate.content.cloneNode(true);Pour créer un nouveau noeud,Cette approche comporte certaines limites:Tous les attributs et valeurs d'attribut du noeud original sont copiés,Cela inclutid,De cette façon, il y a plusieursidLes mêmes éléments

Copiez toutes ses propriétés et leurs valeurs,Bien sûr, cela inclut les événements liés aux propriétés(Par exemple, οnclick=“alert(1)”),Mais ne copiez pas ces utilisations addEventListener()Méthode ou node.onclick = fn Cette utilisation JavaScript Événements liés dynamiquement. --mdn

MDN Il y a aussi des avertissements

Attention!:Pour éviter l'apparition de deux ID Éléments répétitifs,Utiliser cloneNode()Le noeud cloné par la méthode doit spécifier un autre noeud avec l'original si nécessaire ID Valeurs différentes ID

Et,Du noeud généréownerDocumentToujours pointant vers le noeud sourceownerDocument

Puisque cette méthode a certaines limites,Y a - t - il un meilleur moyen?Oui.!

document.importNode

document.importNodeCopie d'un noeud d'un document externe,Vous pouvez ensuite insérer le noeud de cette copie dans le document actif

Comment utiliser

// deep Le paramètre indique si tous les noeuds enfants du noeud source sont répliqués Récursivement 
const node = document.importNode(externalNode, deep); 

Attention!:

Nouveau noeud de construction parentNode - Oui. null, Parce qu'il n'a pas été inséré dans l'arborescence des documents du document actif , Appartient à l'état libre , Il ne peut donc pas être utilisé

De cette façon, nous pouvons facilement modifier le nouveau noeud ownerDocument(Inappend Pointez automatiquement vers le courant après document

Essayez le nouveau. api Pour créer_Components_

<script> class MHeader extends HTMLElement {
    constructor() {
      super();
      // ...
      const content = document.importNode(template.content, true);
      /**
       * Attention!, Pour insérer un noeud dans shadowRoot Avant de pouvoir l'utiliser 
       */
      shadowRoot.appendChild(content);
      // ...
    }
  } </script> 

HTMLElement Le cycle de vie de

Avant, Nous écrivons toutes sortes d'opérations directement dans le constructeur , C'est un peu gonflé , Y a - t - il un moyen de distribuer cette logique ?Oui.!

InHTMLElementIntérieur,Un peu.Cycle de vie

  • connectedCallback,Quand custom element Inséré pour la première fois dans le document DOM Appelé quand

  • disconnectedCallback,Quand custom elementDu document DOM Appelé lors de la suppression de

  • adoptedCallback, Quand custom element Appelé lorsqu'il est déplacé vers un nouveau document

  • attributeChangedCallback,Quand custom elementAjouter、Supprimer、 Appelé lors de la modification de ses propres propriétés

En conséquence, On peut reconstruire l'ancien _Components_

<script> class MHeader extends HTMLElement {
    static get observedAttributes() {
      return ["title"];
    }
    constructor() {
      super();
      // Va automatiquementthisMonter unshadowRoot
      this.attachShadow({ mode: "open" });
      const template = document.querySelector("#mHeaderTemplate");
      // const content = template.content.cloneNode(true);
      const content = document.importNode(template.content, true);
      this.shadowRoot.appendChild(content);
    }

    connectedCallback() {
      const loginBtn = this.shadowRoot.querySelector("#login");
      loginBtn.addEventListener("click", () => {
        this.setAttribute("title", "Connexion réussie");
      });
    }

    attributeChangedCallback(name, oldValue, newValue) {
      if (name === "title") {
        this.shadowRoot.querySelector("#content").innerText = newValue;
      }
    }
  } </script> 

Ici,Nous utilisonsattributeChangedCallbackPour écouter_Components_Modification des attributs,IntitleLorsque les attributs changent, Mettre à jour la valeur de l'élément . Ce rappel renvoie trois paramètres :

  • name, Nom de l'attribut modifié

  • oldValue, Valeur avant la propriété

  • newValue,Valeur à définir

(react C'est beaucoup plus écrit,Un peu de rêve vue Le sentiment de )

En plus, il y a une chose à noter :

Besoin destatic get observedAttributes Déclarez le nom de la propriété à écouter dans la fonction

static get observedAttributes() {
  return ["title"];
} 

Code complet

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <template id="mHeaderTemplate">
      <style> :host {
          font-size: 32px;
        }

        .content {
          color: #f00;
        } </style>
      <div>
        <span class="content" id="content">Je suis la tête</span>
        <button id="login">login</button>
      </div>
    </template>

    <m-header id="mHeader" title="hello" />

    <script> class MHeader extends HTMLElement {
        static get observedAttributes() {
          return ["title"];
        }
        constructor() {
          super();
          // Va automatiquementthisMonter unshadowRoot
          this.attachShadow({ mode: "open" });
          const template = document.querySelector("#mHeaderTemplate");
          // const content = template.content.cloneNode(true);
          const content = document.importNode(template.content, true);
          this.shadowRoot.appendChild(content);
        }

        connectedCallback() {
          const loginBtn = this.shadowRoot.querySelector("#login");
          loginBtn.addEventListener("click", () => {
            this.setAttribute("title", "Connexion réussie");
          });
        }

        attributeChangedCallback(name, oldValue, newValue) {
          if (name === "title") {
            this.shadowRoot.querySelector("#content").innerText = newValue;
          }
        }
      }

      window.customElements.define("m-header", MHeader);

      const mHeader = document.querySelector("#mHeader"); </script>
  </body>
</html> 

Résumé

Parce queNode.cloneNode Le nouveau noeud reste par défaut ownerDocument, Il n'y a donc aucun moyen de libérer ,Il y a des choses à noter,Mais nous pouvons utiliserdocument.importNodePour réaliser la même fonctionnalité,LeAPI Le noeud créé est libre ,En coursappend Correction automatique après l'opération ownerDocumentDirection de

En utilisantcustom elements Fonctions du cycle de vie fournies , Nous pouvons facilement écouter les changements d'attributs pour faire une certaine logique , Mais cette phrase n'est toujours pas assez facile à écrire ,Besoin d'utiliser native dom Fonctionnement api,C'est possible. jQuery J'emprunterai Web Components Pour reprendre vie

Mentions de copyright
Auteur de cet article [Pyjama oriental],Réimpression s’il vous plaît apporter le lien vers l’original, merci
https://fra.chowdera.com/2022/204/202207230538008292.html

Recommandé au hasard