web components hooks - garevna/js-course GitHub Wiki
:mortar_board: Custom elements
:mortar_board: lifecycle hooks
Кастомные элементы имеют хуки жизненного цикла
:pushpin: connectedCallback()
Срабатывает каждый раз при вставке кастомного элемента в DOM
:pushpin: disconnectedCallback()
Срабатывает при удалении кастомного элемента
:warning: не сработает при закрытии пользователем вкладки
:pushpin: attributeChangedCallback()
Срабатывает каждый раз при изменении значений отслеживаемых html-атрибутов элемента
attributeChangedCallback( attrName, oldVal, newVal )
Чтобы указать, какие html-атрибуты нужно отслеживать, используется геттер статического свойства observedAttributes
имена отслеживаемых атрибутов передаются массивом:
static get observedAttributes() {
return [ 'size', 'color']
}
Браузер вызывает attributeChangedCallback() при изменении значения любого атрибута, включенного в массив отслеживаемых атрибутов observedAttributes
:coffee: :one:
class CircleElement extends HTMLElement {
constructor() {
super()
this.shadow = this.attachShadow ( { mode: 'open' } )
this.shadow.appendChild (
document.createElement ( "div" )
)
}
connectedCallback() {
this.createStyle ()
}
static get observedAttributes() {
return [ 'size', 'color']
}
attributeChangedCallback( attrName, oldVal, newVal ) {
this.setStyle ()
}
createStyle () {
this.shadowStyles = document.createElement ( "style" )
this.shadow.appendChild ( this.shadowStyles )
this.shadowStyles.appendChild ( document.createTextNode ( `` ) )
}
setStyle () {
this.shadowStyles.textContent = `
div {
width: ${this.getAttribute("size")}px;
height: ${this.getAttribute("size")}px;
border: inset 1px;
border-radius: 50%;
box-shadow: 3px 3px 5px #00000090;
background-color: ${this.getAttribute("color")};
}
div:hover {
box-shadow: inset 3px 3px 5px #00000090;
}
`
}
}
customElements.define ( "circle-element", CircleElement )
Благодаря хукам connectedCallback и attributeChangedCallback теперь абсолютно все равно, когда будут вставлены кастомные элементы на страницу
for ( var x of [ "blue", "red", "green", "yellow" ] ) {
let elem = document.body.appendChild (
document.createElement ( 'circle-element' )
)
elem.setAttribute ( "color", x )
elem.setAttribute ( "size", Math.round ( Math.random() * 200 ) )
}
Но это не главное
Важный момент заключается в том, что при динамическом изменении значений атрибутов без хука attributeChangedCallback внешний вид кастомного элемента не изменится
Однако если такой хук есть в определении класса, то результатом выполнения кода
document.getElementsByTagName ( "circle-element" )
.setAttribute ( "color", "magenta" )
будет изменение внешнего вида ( цвета фона ) элемента
Аналогично кастомный элемент отреагирует на изменение значения атрибута во вкладке Elements
| :coffee: Пример в песочнице |
|---|