Los componentes web orientados al contexto son más fáciles de lo que piensa trucos CSS
Otro aspecto de los componentes web del que aún no hemos hablado es que se llama a la función de JavaScript cada vez que se agrega o elimina un componente web de una página. Estos comentarios del ciclo de vida se pueden usar para muchas cosas, incluida la información del elemento sobre su contexto.
Una serie de artículos
Las cuatro devoluciones de llamada del ciclo de vida del componente web
Hay retroalimentación de cuatro ciclos de vida que se puede utilizar con componentes web:
connectedCallback
: Esta devolución de llamada se activa cuando el artículo personalizado es adjunto al elemento.disconnectedCallback
: Esta devolución de llamada se activa cuando el elemento es remoto del documentoadoptedCallback
: Esta devolución de llamada se activa cuando el elemento es adicional a un nuevo documento.attributeChangedCallback
: Esta devolución de llamada se activa cuando un atributo cambia, agrega o quita, siempre que se respete este atributo.
Veamos cada uno de ellos en acción.
Nuestro componente post-apocalíptico de la personalidad
Comenzaremos creando un componente web llamado <postapocalyptic-person>
Después del apocalipsis, todos son humanos o zombis y sabremos quién según la clase, o .human
o .zombie
- esto se aplica al elemento padre de <postapocalyptic-person>
componente. No haremos nada fantástico con él (todavía), pero agregaremos un shadowRoot
podemos utilizar para adjuntar una imagen apropiada en base a esta clasificación.
customElements.define(
"postapocalyptic-person",
class extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: "open" });
}
}
Nuestro HTML se ve así:
<div class="humans">
<postapocalyptic-person></postapocalyptic-person>
</div>
<div class="zombies">
<postapocalyptic-person></postapocalyptic-person>
</div>
Insertar personas con connectedCallback
Cuándo <postapocalyptic-person>
cargas en la página, connectedCallback()
se llama la función.
connectedCallback() {
let image = document.createElement("img");
if (this.parentNode.classList.contains("humans")) {
image.src = "https://assets.codepen.io/1804713/lady.png";
this.shadowRoot.appendChild(image);
} else if (this.parentNode.classList.contains("zombies")) {
image.src = "https://assets.codepen.io/1804713/ladyz.png";
this.shadowRoot.appendChild(image);
}
}
Esto asegura que la imagen de la persona se muestre cuando <postapocalyptic-person>
es un humano y una imagen de un zombi cuando el componente es un zombi.
Tenga cuidado al trabajar con connectedCallback
Funciona con más frecuencia de lo que puede imaginar, se activa cada vez que se mueve el elemento e incluso puede funcionar (confundido) después el nodo ya no está conectado, lo que puede resultar costoso. Puedes usar this.isConnected
para saber si el artículo está conectado o no.
contar personas con connectedCallback()
cuando se agrega
Pongámonos un poco más sofisticados agregando algunos botones a la mezcla. Uno agregará un <postapocalyptic-person>
utilizando el enfoque de lanzamiento de moneda para decidir si es un humano o un zombi. El otro botón hará lo contrario eliminando <postapocalyptic-person>
al azar Realizaremos un seguimiento de cuántas personas y zombis se ven mientras lo hacemos.
<div class="btns">
<button id="addbtn">Add Person</button>
<button id="rmvbtn">Remove Person</button>
<span class="counts">
Humans: <span id="human-count">0</span>
Zombies: <span id="zombie-count">0</span>
</span>
</div>
Esto es lo que harán nuestros botones:
let zombienest = document.querySelector(".zombies"),
humancamp = document.querySelector(".humans");
document.getElementById("addbtn").addEventListener("click", function () {
// Flips a "coin" and adds either a zombie or a human
if (Math.random() > 0.5) {
zombienest.appendChild(document.createElement("postapocalyptic-person"));
} else {
humancamp.appendChild(document.createElement("postapocalyptic-person"));
}
});
document.getElementById("rmvbtn").addEventListener("click", function () {
// Flips a "coin" and removes either a zombie or a human
// A console message is logged if no more are available to remove.
if (Math.random() > 0.5) {
if (zombienest.lastElementChild) {
zombienest.lastElementChild.remove();
} else {
console.log("No more zombies to remove");
}
} else {
if (humancamp.lastElementChild) {
humancamp.lastElementChild.remove();
} else {
console.log("No more humans to remove");
}
}
});
Aquí está el código en connectedCallback()
quien cuenta personas y zombis cuando agregan:
connectedCallback() {
let image = document.createElement("img");
if (this.parentNode.classList.contains("humans")) {
image.src = "https://assets.codepen.io/1804713/lady.png";
this.shadowRoot.appendChild(image);
// Get the existing human count.
let humancount = document.getElementById("human-count");
// Increment it
humancount.innerHTML = parseInt(humancount.textContent) + 1;
} else if (this.parentNode.classList.contains("zombies")) {
image.src = "https://assets.codepen.io/1804713/ladyz.png";
this.shadowRoot.appendChild(image);
// Get the existing zombie count.
let zombiecount = document.getElementById("zombie-count");
// Increment it
zombiecount.innerHTML = parseInt(zombiecount.textContent) + 1;
}
}
Actualizar número con disconnectedCallback
Entonces podemos usar disconnectedCallback()
para reducir el número a medida que se eliminan humanos y zombis. Sin embargo, no podemos verificar la clase del elemento principal porque ya falta el elemento principal con esa clase. disconnectedCallback
Podemos establecer un atributo del elemento o agregar una propiedad al objeto, pero debido a que la imagen es src
el atributo ya está definido por su elemento principal, podemos usarlo como un proxy para averiguar si el componente web que se eliminará es humano o zombi.
disconnectedCallback() {
let image = this.shadowRoot.querySelector('img');
// Test for the human image
if (image.src == "https://assets.codepen.io/1804713/lady.png") {
let humancount = document.getElementById("human-count");
humancount.innerHTML = parseInt(humancount.textContent) - 1; // Decrement count
// Test for the zombie image
} else if (image.src == "https://assets.codepen.io/1804713/ladyz.png") {
let zombiecount = document.getElementById("zombie-count");
zombiecount.innerHTML = parseInt(zombiecount.textContent) - 1; // Decrement count
}
}
¡Cuidado con los payasos!
Ahora (y hablo por experiencia, por supuesto) lo único que da más miedo que una horda de zombis atacando tu posición es un payaso, ¡todo lo que se necesita es uno! Entonces, aunque ya estamos frente a un post aterrador: zombis apocalípticos, agreguemos la posibilidad de que un payaso entre en escena para un horror aún mayor. De hecho, lo haremos de tal manera que todos o los zombis en la pantalla puedan ser payaso disfrazado en secreto!
Vuelvo a lo dicho anteriormente: un payaso zombi da más miedo incluso que un grupo de payasos "normales". Digamos que si se encuentra algún tipo de payaso, ya sea un humano o un zombi, los separamos de las poblaciones de humanos y zombis enviándolos a un documento completamente diferente: un <iframe>
prisión si se quiere. (Escuché que "hacer el payaso" puede ser incluso más contagioso que la infección de zombies).
Y cuando movemos un presunto payaso del documento actual a un <iframe>
, no destruye ni recrea el nodo original; más bien, recibe y conecta dicho nodo, llamando primero adoptedCallback
entonces connectedCallback
.
No necesitamos nada en <iframe>
un documento que no sea un cuerpo con un .clowns
clase. Mientras este documento esté en el iframe del documento principal, no considerado por separado, ni siquiera lo necesitamos. <postapocalyptic-person>
código de instancia. Incluiremos un espacio para personas, otro para zombis y sí, la prisión de los payasos... <iframe>
en... entretenimiento.
<div class="btns">
<button id="addbtn">Add Person</button>
<button id="jailbtn">Jail Potential Clown</button>
</div>
<div class="humans">
<postapocalyptic-person></postapocalyptic-person>
</div>
<div class="zombies">
<postapocalyptic-person></postapocalyptic-person>
</div>
<iframe class="clowniframeoffun” src="https://css-tricks.com/context-aware-web-components/adoptedCallback-iframe.html">
</iframe>
Nuestro botón Add Man funciona de la misma manera que en el último ejemplo aleatorio: lanza una moneda digital para insertar un hombre o un zombi. Cuando presionas el botón "Payaso potencial en la cárcel", otra moneda se da la vuelta y se lleva a un zombi o a un humano, y se los entrega a <iframe>
prisión.
document.getElementById("jailbtn").addEventListener("click", function () {
if (Math.random() > 0.5) {
let human = humancamp.querySelector('postapocalyptic-person');
if (human) {
clowncollege.contentDocument.querySelector('body').appendChild(document.adoptNode(human));
} else {
console.log("No more potential clowns at the human camp");
}
} else {
let zombie = zombienest.querySelector('postapocalyptic-person');
if (zombie) {
clowncollege.contentDocument.querySelector('body').appendChild(document.adoptNode(zombie));
} else {
console.log("No more potential clowns at the zombie nest");
}
}
});
Revelando payasos con adoptedCallback
EN adoptedCallback
determinaremos si el payaso es de la especie zombie humana en función de su imagen respectiva y luego cambiaremos la imagen en consecuencia. connectedCallback
será llamado después de eso, pero no tenemos nada que hacer, y lo que haga no impedirá nuestros cambios. Así que podemos dejarlo como está.
adoptedCallback() {
let image = this.shadowRoot.querySelector("img");
if (this.parentNode.dataset.type == "clowns") {
if (image.src.indexOf("lady.png") != -1) {
// Sometimes, the full URL path including the domain is saved in `image.src`.
// Using `indexOf` allows us to skip the unnecessary bits.
image.src = "https://css-tricks.com/context-aware-web-components/ladyc.png";
this.shadowRoot.appendChild(image);
} else if (image.src.indexOf("ladyz.png") != -1) {
image.src = "ladyzc.png";
this.shadowRoot.appendChild(image);
}
}
}
Detecta payasos ocultos con attributeChangedCallback
finalmente tenemos attributeChangedCallback
A diferencia de las otras tres devoluciones de llamada del ciclo de vida, necesitamos monitorear los atributos de nuestro componente web para activar la devolución de llamada. Podemos hacer esto agregando observedAttributes()
función a la clase de elemento personalizado y esta función para devolver una matriz de nombres de atributos.
static get observedAttributes() {
return [“attribute-name”];
}
Entonces, si este atributo cambia, incluyendo agregar o eliminar, attributeChangedCallback
incendios
Ahora, lo que debe preocuparte con los payasos es que algunas de las personas que conoces y amas (o aquellas que conoces y amas antes de convertirse en zombis) pueden ser payasos disfrazados en secreto. Creé un detector de payasos que mira a un grupo de personas y zombis, y cuando haces clic en el botón "Descubrir payasos", el detector (a través de medios completamente científicos y completamente confiables que son No basado en números aleatorios al seleccionar un índice). data-clown="true"
al componente. Y cuando se aplica este atributo, attributeChangedCallback
activa y actualiza la imagen del componente para revelar sus colores de payaso.
También debo señalar que attributeChangedCallback
acepta tres parámetros:
- Nombre del Atributo
- el valor anterior del atributo
- el nuevo valor del atributo
Además, la devolución de llamada le permite realizar cambios en función de cuánto ha cambiado el atributo o en función de la transición entre dos estados.
aquí está el nuestro attributeChangedCallback
código:
attributeChangedCallback(name, oldValue, newValue) {
let image = this.shadowRoot.querySelector("img");
// Ensures that `data-clown` was the attribute that changed,
// that its value is true, and that it had an image in its `shadowRoot`
if (name="data-clown" && this.dataset.clown && image) {
// Setting and updating the counts of humans, zombies,
// and clowns on the page
let clowncount = document.getElementById("clown-count"),
humancount = document.getElementById("human-count"),
zombiecount = document.getElementById("zombie-count");
if (image.src.indexOf("lady.png") != -1) {
image.src = "https://assets.codepen.io/1804713/ladyc.png";
this.shadowRoot.appendChild(image);
// Update counts
clowncount.innerHTML = parseInt(clowncount.textContent) + 1;
humancount.innerHTML = parseInt(humancount.textContent) - 1;
} else if (image.src.indexOf("ladyz.png") != -1) {
image.src = "https://assets.codepen.io/1804713/ladyzc.png";
this.shadowRoot.appendChild(image);
// Update counts
clowncount.innerHTML = parseInt(clowncount.textContent) + 1;
zombiecount.innerHTML = parseInt(zombiecount.textContent) - 1;
}
}
}
¡Y aquí está! No solo hemos descubierto que recordar componentes web y crear elementos personalizados conscientes del contexto es más fácil de lo que podría pensar, sino que encontrar payasos postapocalípticos, aunque aterrador, también es más fácil de lo que piensa. ¿Qué tipo de payasos postapocalípticos anteriores puede encontrar con estas funciones de devolución de llamada del componente web?
Deja una respuesta