Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

163
Visualizações
Cómo manejar y pasar eventos al componente iluminado desde la definición del componente

Estoy tratando de diseñar componentes web usando el elemento iluminado y necesito ayuda con respecto a los eventos. Como podemos ver en el fragmento adjunto, podríamos usar @change="${this.handleEvent}" en la plantilla html y manejar la función handleEvent(e){} dentro del componente Element iluminado. Por esto, los eventos están limitados y controlados solo en los componentes web iluminados.

Sin embargo, cuando otras personas usan nuestros componentes web, no tienen mucho control o acceso a los valores sobre estos eventos en el componente de definición. Por ejemplo, si tenemos un archivo index.html y lo uso como <my-element onchange="handleEvent(e)"></my-element> , debería tener acceso al evento onchange y llamar a una función dentro el archivo de índice solamente.

Entonces, ¿hay alguna manera de lograr esto con el comportamiento similar de los eventos html regulares en lugar de escribir los eventos que están limitados en los componentes web de Element iluminados?

 <script src="https://unpkg.com/@webcomponents/webcomponentsjs@latest/webcomponents-loader.js"></script> <script type="module"> import { LitElement, html, css } from 'https://unpkg.com/lit-element/lit-element.js?module'; class MyElement extends LitElement { static get properties() { return { checked: { type: Boolean, attribute: true } }; } static get styles() { return [ css` div { padding: 10px; width: 90px; border: 2px solid orange; } ` ]; } render() { return html` <div> <input @change="${this.handleEvent}" ?checked="${this.checked}" type="checkbox" /> Checkbox </div> `; } handleEvent(e) { console.log(`Checkbox marked as: ${e.target.checked}`); } } customElements.define('my-element', MyElement); </script> // Index.html <my-element></my-element> // I am expecting to pass an event and handle it in the importing component. // Something like: **<my-element onchange="handleEvent(e)"}></my- element>**

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Si desea escuchar eventos fuera de su elemento, debe enviar un evento como este:

 const event = new Event('my-event', {bubbles: true, composed: true}); myElement.dispatchEvent(event);

La documentación de Lit sobre eventos brinda una buena descripción general de cómo y cuándo enviar eventos https://lit.dev/docs/components/events/#dispatching-events

about 4 years ago · Juan Pablo Isaza Relatório

0

Por lo general, con sus propios elementos personalizados, probablemente también desee definir su propia API para ofrecerla a los consumidores de sus componentes. Eso a menudo también viene con la definición de sus propios eventos que emite su componente.

Vea este ejemplo simple (no iluminado, pero entiende la idea):

 customElements.define('foo-bar', class extends HTMLElement { input = document.createElement('input'); constructor() { super(); this.input.type = 'checkbox'; this.attachShadow({ mode: 'open' }); this.shadowRoot.appendChild(this.input); this.input.addEventListener('change', this.handleChange.bind(this)); } // replaces the internal change event with an event you publish to the outside world // this event is part of your defined API. handleChange(e) { e.stopPropagation(); const stateChange = new CustomEvent('state-change', { bubbles: true, composed: true, detail: { checked: this.input.checked } }); this.dispatchEvent(stateChange); } }); document.addEventListener('state-change', (e) => { console.log(e.detail); })
 <foo-bar></foo-bar>

Si también desea admitir el enlace de eventos declarativos como lo hacen los elementos HTML estándar (y su uso se considera una mala práctica), puede lograrlo utilizando los atributos observados:

 customElements.define('foo-bar', class extends HTMLElement { input = document.createElement('input'); constructor() { super(); this.input.type = 'checkbox'; this.attachShadow({ mode: 'open' }); this.shadowRoot.appendChild(this.input); this.input.addEventListener('change', this.handleChange.bind(this)); this.declarativeValueChangeListener = this.declarativeValueChangeListener.bind(this); } // replaces the internal change event with an event you publish to the outside world // this event is part of your defined API. handleChange(e) { e.stopPropagation(); const stateChange = new CustomEvent('state-change', { bubbles: true, composed: true, detail: { value: this.input.value } }); this.dispatchEvent(stateChange); } static get observedAttributes() { return [ 'onstatechange' ]; } attributeChangedCallback(attr, oldVal, newVal) { if (oldVal === newVal) return; // nothing changed, nothing to do here if (newVal === null) { // attribute was removed this.removeEventListener('state-change', this.declarativeValueChangeListener) } else { // attribute was added this.addEventListener('state-change', this.declarativeValueChangeListener) } } declarativeValueChangeListener() { const functionStr = this.getAttribute(this.constructor.observedAttributes[0]); eval(functionStr); } }); function baz() { console.log('baz executed through declarative binding of an outside handler!'); }
 <foo-bar onstatechange="baz()"></foo-bar>

about 4 years ago · Juan Pablo Isaza Relatório

0

No entiendo por qué necesitas Eventos,
cuando un clic en la input puede ejecutar funciones globales o métodos locales.

No hay necesidad de oldskool bind mumbo-jumbo, no hay necesidad de atributos observedAttributes

Puede usar el onchange predeterminado , porque todos los eventos existen en HTMLElement
Solo las entradas como textarea el evento de cambio

Usado en cualquier otro elemento HTML, no sucede nada, debe llamar a this.onchange() o document.querySelector("foo-bar").onchange() usted mismo.
No puede hacer eso con sus propios nombres de atributo, ya que esos valores siempre serán una cadena y el motor del navegador no los analizará como código JS.

Sin embargo, necesita eval(code) para ejecutar el código dentro del alcance del Componente y hacer que onchange="this.baz()" funcione.

 customElements.define('foo-bar', class extends HTMLElement { constructor() { let input = document.createElement("input"); input.type = "checkbox"; super() .attachShadow({mode: 'open'}) .append(input,"click me to execute ", this.getAttribute("onchange")); this.onclick = (evt) => { // maybe you only want input.onclick //evt.stopPropagation(); let code = this.getAttribute("onchange"); try { eval(code); // this.onchange() will only execute global functions } catch (e) { console.error(e,code); } } } baz() { console.log("Executed baz Method"); } }); function baz() { console.log("Executed baz Function"); }
 <foo-bar onchange="baz()"></foo-bar> <foo-bar onchange="this.baz()"></foo-bar> <style> foo-bar { display:block; zoom:2 } </style>

Nota IMPORTANTE

shadowDOM es lo que te salva el culo aquí.

El evento onchange de la input no escapa a shadowDOM
(Al igual que composed:true lo hace en eventos personalizados)

Sin onchange , todas las declaraciones de cambio en los elementos principales se activarán , porque el evento burbujea :

 <div onchange="console.log(666)"> <input onchange="console.log(this)" type="checkbox"> </div> <style> input { zoom:3 } </style>

Este es un buen ejemplo donde un shadowRoot en un HTMLElement regular puede tener valor, sin declarar un elemento personalizado

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda