제퍼넷 로고

컨텍스트 인식 웹 구성 요소는 생각보다 쉽습니다.

시간

아직 언급하지 않은 웹 구성 요소의 또 다른 측면은 웹 구성 요소가 페이지에서 추가되거나 제거될 때마다 JavaScript 함수가 호출된다는 것입니다. 이러한 수명 주기 콜백은 요소가 해당 컨텍스트를 인식하도록 만드는 것을 포함하여 많은 용도로 사용할 수 있습니다.

기사 시리즈

웹 구성 요소의 네 가지 수명 주기 콜백

다음의 네 가지 수명 주기 콜백 웹 구성 요소와 함께 사용할 수 있습니다.

  • connectedCallback: 이 콜백은 맞춤 요소가 붙여진 요소에.
  • disconnectedCallback: 이 콜백은 요소가 제거 문서에서.
  • adoptedCallback: 이 콜백은 요소가 추가 새 문서로.
  • attributeChangedCallback: 이 콜백은 속성 해당 속성이 관찰되는 한 변경, 추가 또는 제거됩니다.

각각의 작동 방식을 살펴보겠습니다.

포스트 아포칼립스 인물 구성 요소

나란히 놓인 웹 구성 요소의 두 렌더링, 왼쪽은 인간이고 오른쪽은 좀비입니다.

라는 웹 구성 요소를 만드는 것으로 시작하겠습니다. <postapocalyptic-person>. 대재앙 이후의 모든 사람은 인간이거나 좀비이며 클래스에 따라 어느 쪽인지 알 수 있습니다. .human or .zombie — 상위 요소에 적용됩니다. <postapocalyptic-person> 요소. 우리는 (아직) 그것으로 멋진 일을 하지 않을 것이지만, shadowRoot 해당 분류를 기반으로 해당 이미지를 첨부하는 데 사용할 수 있습니다.

customElements.define( "postapocalyptic-person", class extends HTMLElement { constructor() { super(); const shadowRoot = this.attachShadow({ mode: "open" }); }
}

HTML은 다음과 같습니다.

<div class="humans"> <postapocalyptic-person></postapocalyptic-person>
</div>
<div class="zombies"> <postapocalyptic-person></postapocalyptic-person>
</div>

사람 삽입 connectedCallback

<postapocalyptic-person> 페이지에 로드되며, connectedCallback() 함수가 호출됩니다.

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); }
}

이것은 사람의 이미지가 출력되는 것을 확인합니다. <postapocalyptic-person> 는 사람이고 구성요소가 좀비일 때 좀비 이미지입니다.

조심해서 작업하세요 connectedCallback. 그것은 당신이 생각하는 것보다 더 자주 실행되며 요소가 움직일 때마다 실행되고 (당황스럽게도) 실행될 수도 있습니다. 시간 내에 노드가 더 이상 연결되지 않아 성능 비용이 많이 들 수 있습니다. 당신이 사용할 수있는 this.isConnected 요소가 연결되어 있는지 여부를 알 수 있습니다.

로 사람 세기 connectedCallback() 그들이 추가될 때

믹스에 몇 개의 버튼을 추가하여 좀 더 복잡해 봅시다. 하나는 <postapocalyptic-person>, "동전 던지기" 접근 방식을 사용하여 인간인지 좀비인지 결정합니다. 다른 버튼은 반대로 작동하여 <postapocalyptic-person> 무작위. 우리는 우리가 그것에 있는 동안 얼마나 많은 인간과 좀비가 시야에 있는지 추적할 것입니다.

<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>

버튼의 기능은 다음과 같습니다.

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"); } }
});

다음은 코드입니다. connectedCallback() 추가되는 인간과 좀비 수를 계산합니다.

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; }
}

카운트 업데이트 disconnectedCallback

다음으로 사용할 수 있습니다. disconnectedCallback() 인간과 좀비가 제거됨에 따라 숫자가 감소합니다. 그러나 해당 클래스를 가진 부모 요소가 시간에 의해 이미 사라져버렸기 때문에 부모 요소의 클래스를 확인할 수 없습니다. disconnectedCallback 호출됩니다. 요소에 속성을 설정하거나 객체에 속성을 추가할 수 있지만 이미지의 src 속성은 이미 부모 요소에 의해 결정되므로 제거되는 웹 구성 요소가 사람인지 좀비인지 알기 위한 프록시로 사용할 수 있습니다.

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 }
}

광대를 조심하세요!

이제 (물론 여기서 경험을 통해 말하고 있습니다) 당신의 위치를 ​​견고하는 좀비 무리보다 무서운 유일한 것은 광대입니다. 필요한 것은 하나뿐입니다! 그래서 우리는 이미 무시무시한 포스트 아포칼립스 좀비를 다루고 있지만, 더 많은 공포를 위해 광대가 등장할 가능성을 추가해 봅시다. 사실, 우리는 화면에 있는 인간이나 좀비가 비밀리에 변장한 광대일 가능성이 있는 방식으로 할 것입니다!

나는 이전에 말한 것을 철회합니다. 단일 좀비 광대는 "정상적인"광대 그룹보다 무섭습니다. 어떤 종류의 광대가 발견되면 — 인간이든 좀비이든 — 완전히 다른 문서로 전송하여 인간과 좀비 집단에서 그들을 분리한다고 가정해 봅시다. <iframe> 당신이 원한다면 감옥. (저는 "광대"가 좀비 전염보다 더 전염성이 높다고 들었습니다.)

그리고 의심되는 광대를 현재 문서에서 <iframe>, 원래 노드를 파괴하고 재생성하지 않습니다. 오히려 해당 노드를 채택하고 연결하여 먼저 호출합니다. adoptedCallback 그때 connectedCallback.

우리는 아무것도 필요하지 않습니다 <iframe> 본문을 제외한 문서 .clowns 수업. 이 문서가 기본 문서의 iframe에 있는 한(별도로 표시되지 않음) <postapocalyptic-person> 인스턴스화 코드. 우리는 인간을 위한 공간 하나, 좀비를 위한 또 다른 공간, 그리고 광대의 감옥을 포함할 것입니다… <iframe> ...의 재미.

<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="adoptedCallback-iframe.html">
</iframe>

"사람 추가" 버튼은 마지막 예에서와 동일하게 작동합니다. 디지털 동전을 뒤집어 사람이나 좀비를 무작위로 삽입합니다. 우리가 "감옥 가능성 있는 광대" 버튼을 누르면 또 다른 동전이 뒤집어지고 좀비나 인간을 잡아서 <iframe> 교도소.

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"); } }
});

광대 공개 adoptedCallback

. adoptedCallback 해당 이미지를 기반으로 광대가 인간 좀비인지 판단한 다음 그에 따라 이미지를 변경합니다. connectedCallback 그 후에 호출되지만 수행해야 할 작업이 없으며 수행하는 작업이 변경 사항을 방해하지 않습니다. 따라서 그대로 둘 수 있습니다.

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 = "ladyc.png"; this.shadowRoot.appendChild(image); } else if (image.src.indexOf("ladyz.png") != -1) { image.src = "ladyzc.png"; this.shadowRoot.appendChild(image); } }
}

숨은 광대 찾기 attributeChangedCallback

마지막으로, 우리는 attributeChangedCallback. 다른 세 가지 수명 주기 콜백과 달리 콜백이 실행되려면 웹 구성 요소의 속성을 관찰해야 합니다. 우리는 이것을 추가함으로써 할 수 있습니다 observedAttributes() 함수를 사용자 정의 요소의 클래스에 전달하고 해당 함수가 속성 이름의 배열을 반환하도록 합니다.

static get observedAttributes() { return [“attribute-name”];
}

그런 다음 해당 속성이 변경되면(추가 또는 제거 포함) attributeChangedCallback 화재.

이제 광대에 대해 걱정해야 하는 것은 당신이 알고 사랑하는 인간(또는 좀비로 변하기 전에 알고 사랑했던 인간) 중 일부가 몰래 광대가 될 수 있다는 것입니다. 나는 인간과 좀비 그룹을 보는 광대 탐지기를 설정했으며 "광대 공개" 버튼을 클릭하면 탐지기가 (완전히 과학적이고 완전히 신뢰할 수 있는 수단을 통해 지원 인덱스를 선택하는 임의의 숫자를 기반으로) 적용 data-clown="true" 구성 요소에. 그리고 이 속성이 적용되면 attributeChangedCallback 구성 요소의 이미지를 실행하고 업데이트하여 광대한 색상을 드러냅니다.

나는 또한 attributeChangedCallback 다음 세 가지 매개변수를 사용합니다.

  • 속성의 이름
  • 속성의 이전 값
  • 속성의 새 값

또한 콜백을 사용하면 속성이 변경된 정도 또는 두 상태 간의 전환을 기반으로 변경할 수 있습니다.

여기 우리의 attributeChangedCallback 암호:

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; } }
}

그리고 당신은 그것을 가지고 있습니다! 우리는 웹 구성 요소 콜백과 컨텍스트 인식 사용자 정의 요소 생성이 생각보다 쉽다는 사실을 알게 되었을 뿐만 아니라 포스트 아포칼립스 광대를 탐지하는 것도 생각보다 쉽다는 사실을 알게 되었습니다. 이러한 웹 구성 요소 콜백 함수로 어떤 종류의 교활하고 포스트 아포칼립스 광대를 감지할 수 있습니까?

출처: https://css-tricks.com/context-aware-web-components/

spot_img

최신 인텔리전스

spot_img

우리와 함께 채팅

안녕하세요! 어떻게 도와 드릴까요?