hand Inicio

SERVICIOS

Salir

nochedía

DESARROLLO WEB con
GATSBY y WORDPRESS

emoji Cursos [24]
emoji Themes Gatsby [5]
emoji Themes WordPress [2]
emoji Blog [83]
emoji Herramientas [11]

Event Bubbling y el descontrol en JavaScript

200 palabras
1 minutos
July 24, 2020
blogjavascript

El event bubbling y event capturing se refiere a cuando un evento se propaga hacia sus elementos padre, o al revés y hacia sus elementos hijo

Eventos

Los eventos son la manera que tenemos de monitorizar el comportamiento de nuestros usuarios

Por ejemplo, detectar cuando se hace click en un botón

Y para implementar este control sobre los eventos, utilizamos los listeners

Por ejemplo

js
el.addEventListener(event, () => {})

Donde event será algo tipo click

js
const el = document.getElementById('mi_boton')
el.addEventListener('click', () => {
console.log('elemento clicado!')
})

Bubbling y Capturing

Entendido esto, el bubbling y el capturing ocurren cuando tenemos listeners dentro de listeners

html
<div id="mi_div">
<button id="mi_boton_1">
Boton 1
<button id="mi_boton_2">Boton 2</button>
</button>
</div>
js
document.getElementById('mi_boton_1').addEventListener('click', () => console.log('boton 1 clicado!'))
document.getElementById('mi_boton_2').addEventListener('click', () => console.log('boton 2 clicado!'))
document.getElementById('mi_div').addEventListener('click', () => console.log('div clicado!'))

En este ejemplo, cuando clicamos el botón 1 o el botón 2 tenemos dos mensajes, el del button y el del div

Y por qué no tenemos bubbling dentro de los botones? Porque en html no puedes meter un botón dentro de otro botón, por lo que el bubbling ni está ni se le espera

Y si esto es el bubbling, el capturing es a la inversa

html
<div id="mi_div">
<button id="mi_boton_1">
Boton 1
<button id="mi_boton_2">Boton 2</button>
</button>
</div>
js
document.getElementById('mi_boton_1').addEventListener('click', () => console.log('boton1 clicado!'), { capture: true })
document.getElementById('mi_boton_2').addEventListener('click', () => console.log('boton2 clicado!'), { capture: true })
document.getElementById('mi_div').addEventListener('click', () => console.log('div clicado!'), { capture: true })

Y lo que hace es invertir el orden de los eventos (y en la práctica el de los console.log)

  • Antes, teníamos primero el click del botón, y luego el del div

  • Ahora, tenemos primero el click del div, y luego el del button

Cómo los paro? (React)

Y para pararlo?

Esto es algo que normalmente querremos hacer para evitar eventos descontrolados

Es tan sencillo como añadir un stopPropagation()

Pero mejor lo vemos en React

Aquí, en lugar de acceder al DOM con el addEventListener, utilizaremos la manera React a través del Virtual DOM

js
import React, { useRef } from 'react'
export const App = () => {
const divRef = useRef()
const buttonRef = useRef()
return (
<div ref={divRef} onClick={() => console.log('yo también!')}>
<h1>Hola</h1>
<button ref={buttonRef} onClick={() => console.log('clicando!')}>
clica!
</button>
</div>
)
}
export default App
Ver en CodeSandBox

Si queremos la versión capturing en lugar de la bubbling, en lugar de utilizar onClick utilizaremos onClickCapture

Y si queremos evitarlo?

Añadimos el stopPropagation(), un método del evento que recibimos por defecto en la función onClick

js
import React, { useRef } from 'react'
const log = (e, msg) => {
e.stopPropagation()
console.log(msg)
}
export const App = () => {
const div = useRef()
const button = useRef()
return (
<div ref={div} onClick={e => log(e, 'yo también!')}>
<h1>Hola</h1>
<button ref={button} onClick={e => log(e, 'clicando!')}>
clica!
</button>
</div>
)
}
export default App
Ver en CodeSandBox

Listos!

Qué tal la entrada?
👌 Bien 🙌🙌
👍 Bien, pero algunas cosas podrían explicarse mejor 😬
🤷‍♂️ Da por sentadas demasiadas cosas 😒
🤷‍♂️ A ver, hay poca chicha 😬
🤷‍♂️ Los ejemplos no son muy claros 🙇‍♂️
🤷‍♂️ No se entiende, está mal escrito 👎
✍️ Hay errores, revísalo en cuanto puedas 🙏

Quizá te interese

Privacidad
by kuworking.com
[ 2020 >> kuworking ]