23
loading...
This website collects cookies to deliver better user experience
const clickEvent = new Event('click')
document.querySelector('button').dispatchEvent(clickEvent)
Event
recebe dois parâmetros, sendo o primeiro o nome do evento e o segundo sendo um objeto de configuração para o evento, em que podemos configurar coisas como bubbles
, cancelable
, composed
. Para saber mais olhe: https://developer.mozilla.org/en-US/docs/Web/API/Event/EventCustomEvent
para criar um evento customizado.const formErrorEvent = new CustomEvent('form-error', {
detail: new Error('Form Error')
})
detail
em que podemos passar qualquer valor que queremos propagar a outros elementos.<!-- HTML -->
<app-root></app-root>
// Javascript
class AppForm extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
this.shadowRoot.innerHTML = `
<form>
<input placeholder="Name" />
<button>Submit</button>
</form>
`
}
connectedCallback() {
const input = this.shadowRoot.querySelector('input')
const form = this.shadowRoot.querySelector('form')
form.addEventListener('submit', ev => {
ev.preventDefault()
if(!input.value) {
const formErrorEvent = new CustomEvent('form-error', {
detail: new Error('Empty name field')
})
this.dispatchEvent(formErrorEvent)
}
})
}
}
customElements.define('app-form', AppForm)
class AppRoot extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
this.shadowRoot.innerHTML = '<app-form></app-form>'
}
connectedCallback() {
this.shadowRoot
.querySelector('app-form')
.addEventListener('form-error', ev => {
console.log(ev.detail.message)
})
}
}
customElements.define('app-root', AppRoot)
<!-- HTML -->
<app-root></app-root>
// Javascript
class LightSwitch extends HTMLElement {
// Estado do elemento
#isOn = false
constructor() {
super()
this.attachShadow({ mode: 'open' })
this.shadowRoot.innerHTML = `
<style>
div {
width: max-content;
padding: 14px;
border-radius: 6px;
}
.off {
background-color: #ddd;
}
.on {
background-color: #08c;
}
</style>
<div class="off">
<button>Toggle</button>
</div>
`
}
connectedCallback() {
this.shadowRoot
.querySelector('button')
.addEventListener('click', () => {
this.toggle()
})
}
/*
Método público que pode ser usado
para mudar o estado do elemento
*/
toggle() {
this.#isOn = !this.#isOn
const className = this.#isOn ? 'on' : 'off'
this.shadowRoot.querySelector('div').className = className
}
}
customElements.define('light-switch', LightSwitch)
class AppRoot extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
this.shadowRoot.innerHTML = `
<light-switch></light-switch>
<button>
Toggle from outside
</button>
`
}
connectedCallback() {
const lightSwitch = this.shadowRoot
.querySelector('light-switch')
this.shadowRoot
.querySelector('button')
.addEventListener('click', () => {
// Chamando o método para alterar o estado do elemento
lightSwitch.toggle()
})
}
}
customElements.define('app-root', AppRoot)
<!-- HTML -->
<app-root></app-root>
// Javascript
class CounterStore {
count = 0
#events = {
onCountChange: []
}
increment() {
this.count++
for(const event of this.#events.onCountChange) {
event()
}
}
onCountChange(listener) {
this.#events.onCountChange.push(listener)
}
}
const counterStore = new CounterStore()
class AppRoot extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
this.shadowRoot.innerHTML = `
<div>Count: ${counterStore.count}</div>
<button>Increment</button>
`
}
connectedCallback() {
this.shadowRoot
.querySelector('button')
.addEventListener('click', () => {
counterStore.increment()
})
counterStore.onCountChange(() => {
this.shadowRoot
.querySelector('div')
.innerText = `Count: ${counterStore.count}`
})
}
}
customElements.define('app-root', AppRoot)