Notas del día 3 sobre las API web de JavaScript

Insertar descripción de la imagen aquí

API web: día 3

Obtenga más información sobre el avance de eventos, logre efectos especiales de páginas web más interactivas y optimice la eficiencia de la ejecución de eventos combinando las características de los flujos de eventos.

  • Aprenda cómo evitar que los eventos surjan
  • Comprender los principios de implementación de la delegación de eventos.

flujo de eventos

El flujo de eventos es una descripción del proceso de ejecución de eventos. Comprender el proceso de ejecución de eventos puede ayudar a profundizar la comprensión de los eventos y mejorar la flexibilidad del uso de eventos en la práctica de desarrollo.

La transferencia de la imagen del enlace externo falló. El sitio de origen puede tener un mecanismo anti-leeching. Se recomienda guardar la imagen y cargarla directamente.

Como se muestra en la figura anterior, cualquier evento siempre pasará por dos etapas cuando se activa: [etapa de captura] y [etapa de burbujeo].

En resumen, la etapa de captura es el proceso de transmisión [de padre a hijo] y la etapa de burbujeo es el proceso de transmisión [de hijo a padre].

capturar y burbujear

Después de comprender qué es el flujo de eventos, veamos cómo el flujo de eventos afecta la ejecución del evento:

<body>
  <h3>事件流</h3>
  <p>事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上。</p>
  <div class="outer">
    <div class="inner">
      <div class="child"></div>
    </div>
  </div>
  <script>
    // 获取嵌套的3个节点
    const outer = document.querySelector('.outer');
    const inner = document.querySelector('.inner');
    const child = document.querySelector('.child');
		
    // html 元素添加事件
    document.documentElement.addEventListener('click', function () {
      
      
      console.log('html...')
    })
		
    // body 元素添加事件
    document.body.addEventListener('click', function () {
      
      
      console.log('body...')
    })

    // 外层的盒子添加事件
    outer.addEventListener('click', function () {
      
      
      console.log('outer...')
    })
    
    // 中间的盒子添加事件
    outer.addEventListener('click', function () {
      
      
      console.log('inner...')
    })
    
    // 内层的盒子添加事件
    outer.addEventListener('click', function () {
      
      
      console.log('child...')
    })
  </script>
</body>

Después de ejecutar el código anterior, encontramos que cuando se activa el evento de clic, los eventos de clic de sus elementos ancestros también se activan uno tras otro.

Combinado con las características del flujo de eventos, sabemos que cuando se activa el evento de un elemento, el evento siempre pasará por sus ancestros antes de llegar al elemento actual, y luego pasará del elemento actual a los ancestros. evento durante el proceso de flujo. El evento se activará.

Otro detalle al que debemos prestar atención es el [orden de ejecución] en el que se disparan los eventos uno tras otro, el orden de ejecución de los eventos es controlable, es decir, se puede ejecutar en la fase de captura o en la fase de burbujeo.

Si el evento se ejecuta en la etapa de burbujeo, lo llamamos modo burbujeante. Primero ejecutará el evento del cuadro secundario y luego el evento del cuadro principal. El valor predeterminado es el modo burbujeante.

Si el evento se ejecuta en la fase de captura, lo llamamos modo de captura: primero ejecutará el evento del cuadro principal y luego ejecutará el evento del cuadro secundario.

<body>
  <h3>事件流</h3>
  <p>事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上。</p>
  <div class="outer">
    <div class="inner"></div>
  </div>
  <script>
    // 获取嵌套的3个节点
    const outer = document.querySelector('.outer')
    const inner = document.querySelector('.inner')

    // 外层的盒子
    outer.addEventListener('click', function () {
      
      
      console.log('outer...')
    }, true) // true 表示在捕获阶段执行事件
    
    // 中间的盒子
    outer.addEventListener('click', function () {
      
      
      console.log('inner...')
    }, true)
  </script>
</body>

en conclusión:

  1. addEventListenerEl tercer parámetro determina si el evento se activa en la fase de captura o en la fase de burbujeo.
  2. addEventListenerEl tercer parámetro es, trueque indica el disparador de la fase de captura, falseque indica el disparador de la fase de burbujeo. El valor predeterminado esfalse
  3. El flujo de eventos solo tendrá efecto si los elementos padre e hijo tienen el mismo tipo de evento
  4. La mayoría de las escenas utilizan el modo burbujeante predeterminado (una de las razones es que los primeros IE no admitían la captura)

deja de burbujear

Prevenir la propagación significa bloquear el flujo de eventos para garantizar que los eventos solo se ejecuten en el elemento actual y ya no afecten a sus elementos ancestros correspondientes.

<body>
  <h3>阻止冒泡</h3>
  <p>阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响到其对应的祖先元素。</p>
  <div class="outer">
    <div class="inner">
      <div class="child"></div>
    </div>
  </div>
  <script>
    // 获取嵌套的3个节点
    const outer = document.querySelector('.outer')
    const inner = document.querySelector('.inner')
    const child = document.querySelector('.child')

    // 外层的盒子
    outer.addEventListener('click', function () {
      
      
      console.log('outer...')
    })

    // 中间的盒子
    inner.addEventListener('click', function (ev) {
      
      
      console.log('inner...')

      // 阻止事件冒泡
      ev.stopPropagation()
    })

    // 内层的盒子
    child.addEventListener('click', function (ev) {
      
      
      console.log('child...')

      // 借助事件对象,阻止事件向上冒泡
      ev.stopPropagation()
    })
  </script>
</body>

Conclusión: el método en el objeto de evento ev.stopPropagationse usa específicamente para evitar que los eventos se propaguen.

Pase el mouse sobre el evento:

mouseover y mouseout tendrán un efecto burbujeante

mouseenter y mouseleave no tienen efecto burbujeante (recomendado)

delegación de eventos

La delegación de eventos es un conocimiento y habilidad que utiliza las características del flujo de eventos para resolver algunas necesidades prácticas de desarrollo y su función principal es mejorar la eficiencia del programa.

Una gran cantidad de monitoreo de eventos requiere relativamente mucho rendimiento, como se muestra en el siguiente código

<script>
  // 假设页面中有 10000 个 button 元素
  const buttons = document.querySelectorAll('table button');

  for(let i = 0; i <= buttons.length; i++) {
      
      
    // 为 10000 个 button 元素添加了事件
    buttons.addEventListener('click', function () {
      
      
      // 省略具体执行逻辑...
    })
  }
</script>

Utilizando las características del flujo de eventos, el código anterior se puede optimizar. El modo de difusión del evento siempre hará fluir el evento a su elemento principal. Si el elemento principal escucha el mismo tipo de evento, entonces el evento del elemento principal ser activado Y ejecutar, es esta característica la que se utiliza para optimizar el código anterior, como se muestra en el siguiente código:

<script>
  // 假设页面中有 10000 个 button 元素
  let buttons = document.querySelectorAll('table button');
  
  // 假设上述的 10000 个 buttom 元素共同的祖先元素是 table
  let parents = document.querySelector('table');
  parents.addEventListener('click', function () {
      
      
    console.log('点击任意子元素都会触发事件...');
  })
</script>

Nuestro objetivo final es garantizar que la función de devolución de llamada del evento se ejecute solo cuando se hace clic en el subelemento del botón ¿Cómo determinar en qué subelemento hace clic el usuario?

La transferencia de la imagen del enlace externo falló. El sitio de origen puede tener un mecanismo anti-leeching. Se recomienda guardar la imagen y cargarla directamente.

targetEl atributo o atributo en el objeto del evento srcElementrepresenta el elemento que realmente desencadenó el evento, que es un nodo de tipo elemento.

<script>
  // 假设页面中有 10000 个 button 元素
  const buttons = document.querySelectorAll('table button')
  
  // 假设上述的 10000 个 buttom 元素共同的祖先元素是 table
  const parents = document.querySelector('table')
  parents.addEventListener('click', function (ev) {
      
      
    // console.log(ev.target);
    // 只有 button 元素才会真正去执行逻辑
    if(ev.target.tagName === 'BUTTON') {
      
      
      // 执行的逻辑
    }
  })
</script>

El código optimizado solo agrega detectores de eventos a elementos ancestros, lo cual es mucho más eficiente que agregar detectores de eventos a 10,000 elementos. ! !

Otros eventos

evento de carga de página

Evento que se activa cuando se cargan recursos externos (como imágenes, CSS y JavaScript externos, etc.).

A veces es necesario esperar a que se procesen todos los recursos de la página para hacer algo.

Nombre del evento: cargar

Se han cargado todos los recursos de la página de seguimiento:

window.addEventListener('load', function() {
    
    
    // xxxxx
})

evento de desplazamiento de elemento

Eventos que se activan continuamente cuando la barra de desplazamiento se desplaza

window.addEventListener('scroll', function() {
    
    
    // xxxxx
})

evento de tamaño de página

Los eventos se activarán cuando cambie el tamaño de la ventana:

window.addEventListener('resize', function() {
    
    
    // xxxxx
})

Tamaño y posición del elemento

Obtenga el ancho y alto del propio elemento, incluido el ancho y alto, el relleno y el borde establecidos por el propio elemento.

offsetWidth和offsetHeight

Lo que se obtiene es un valor numérico, que es conveniente para el cálculo.

Nota: Lo que se obtiene es el ancho y alto visible, si el cuadro está oculto el resultado obtenido es 0.

incidente de pulgadas

Los eventos se activarán cuando cambie el tamaño de la ventana:

window.addEventListener('resize', function() {
    
    
    // xxxxx
})

Tamaño y posición del elemento

Obtenga el ancho y alto del propio elemento, incluido el ancho y alto, el relleno y el borde establecidos por el propio elemento.

offsetWidth和offsetHeight

Lo que se obtiene es un valor numérico, que es conveniente para el cálculo.

Nota: Lo que se obtiene es el ancho y alto visible, si el cuadro está oculto el resultado obtenido es 0.

Supongo que te gusta

Origin blog.csdn.net/upgrade_bro/article/details/133462834
Recomendado
Clasificación