Registrar un uso de eventos de puntero

puntero-eventos

Artículo publicado por primera vez en blog personal

Escenas

Encontré una escena de este tipo en un proyecto de empresa: hay un producto (con información como icono, precio, etc.), cuando se pasa el icono por encima, debería haber información sobre herramientas flotante para mostrar su información detallada, cuando el producto está deshabilitado , habrá un negro La máscara está cubierta en la parte superior, y no se puede seleccionar en este momento. Luego viene el problema. Quiero pasar el cursor sobre el icono para mostrar la información sobre herramientas, pero hay una máscara negra en él. ¿Qué tengo que hacer?

El código es el siguiente (se han eliminado algunas etiquetas para evitar que el código sea demasiado largo):

<style>
  .container {
    width: 500px;
    height: 300px;
    background: red;
    position: relative;
  }
  .mask {
    width: 100%;
    height: 100%;
    background: green;
    position: absolute;
    z-index: 2;
  }
  .content {
    width: 500px;
    height: 300px;
    background: blue;
  }
</style>
<body>
  <div class="container">
    <div class="mask"></div>
    <p class="content">我是内容</p>
  </div>

  <script>
    const mask = document.querySelector('.mask');
    const container = document.querySelector('.container');
    const content = document.querySelector('.content');

    content.addEventListener('mouseenter', () => {
      console.log('content mouseenter');
    });
    mask.addEventListener('mouseenter', () => {
      console.log('mask mouseenter');
    });
    container.addEventListener('mouseenter', () => {
      console.log('container mouseenter');
    });
  </script>
</body>
复制代码

Sin embargo, su efecto ahora es que cuando paso el mouse hacia arriba, el orden de impresión es el siguiente:

// container mouseenter
// mask mouseenter
复制代码

En ese momento, después de pensarlo, seguí pensando en cómo resolver este problema. Tiene una máscara, pero necesita mouseenterencontentactivarsepointer-events

¿Qué son los eventos de puntero?

Echemos un vistazo a su definición en Mdn

La propiedad CSS pointer-events especifica bajo qué circunstancias (si las hay) un elemento gráfico en particular puede ser el desencadenante de eventos del mouse.

Tiene muchos valores:

/* Global values */
pointer-events: inherit;
pointer-events: initial;
pointer-events: unset;

/* Keyword values */
pointer-events: auto;
pointer-events: none;
/* 以下的属性仅适用于SVG */
pointer-events: visiblePainted;
pointer-events: visibleFill;
pointer-events: visibleStroke;
pointer-events: visible;
pointer-events: painted;
pointer-events: fill;
pointer-events: stroke;
pointer-events: all;
复制代码

Para resolver el problema anterior, solo necesita <div class='mask'>agregar uno pointer-events: nonea los anteriores, echemos un vistazo al orden de impresión:

// container mouseenter
// content mouseenter
复制代码

¿Por qué? Echemos un vistazo a pointer-events:nonela explicación en la documentación de Mdn:

Los elementos nunca se convierten en activadores de eventos del mouse. Sin embargo, un evento de mouse puede apuntar a un elemento descendiente cuando la propiedad pointer-events de su elemento descendiente especifica un valor diferente, en cuyo caso el evento de mouse activará el detector de eventos del elemento principal durante la fase de captura o propagación.

Así que .maskagregamos este atributo a lo anterior, no se convertirá en el desencadenante del evento del mouse, por lo que el desencadenante del evento del mouse se convertirá con éxito .content, y este problema se resolvió con éxito.

Pero vemos esta definición, pero cuando su elemento descendiente también especifica este atributo, y no es ninguno, el evento del mouse puede apuntar al elemento descendiente, y el resto se omite... Intentemos escribir una demostración nuevamente:

<style>
  .mask-child {
    width: 200px;
    height: 300px;
    background: yellow;
    pointer-events: auto;
  }
</style>
<body>
  <div class="container">
    <div class="mask">
      <div class="mask-child"></div>
    </div>
    <p class="content">我是内容</p>
  </div>

  <script>
    const maskChild = document.querySelector('.mask-child');

    maskChild.addEventListener('mouseenter', () => {
      console.log('maskChild mouseenter');
    });
  </script>
</body>
复制代码

Agregue esta parte al código ahora mismo, echemos un vistazo nuevamente, debe tenerse en cuenta que .maskagregamos un niño .mask-childy luego escuchamos sus mouseentereventos, echemos un vistazo al efecto:

// container mouseenter
// mask mouseenter
// maskChild mouseenter
复制代码

Como era de esperar, sigue siendo el mismo maskevento que se activará mouseenter, por lo que sabemos que si desea omitir el evento especificado de un elemento, podemos establecer uno en él pointer-events:none, pero debe tenerse en cuenta que sus descendientes no deben pointer-eventsvolver a especificar atributos, de lo contrario, seguirá fallando.

Ejemplo

  1. No desencadena eventos del mouse (arrastrar, pasar el mouse, hacer clic, etc.).
<style>
  button {
    pointer-events: none;
  }
</style>
<button onclick="handleClick()">测试</button>
<script>
  function handleClick() {
    console.log('handleClick');
  }
</script>
复制代码

no imprime handleClick.

  1. Además, si se establece :hover, la :activepseudoclase no se activará.

Como antes, si quisiéramos cancelar el hoverefecto de un elemento deshabilitado, podríamos escribirlo así:

<p class="content disable"></p>

<style>
  .content:not(disable):hover {
  }
</style>
复制代码

Y ahora podemos escribirlo así, ¿es más sencillo?

<p class="content disable"></p>

<style>
  .content.disable {
    pointer-events: none;
  }
  .content:hover {
  }
</style>
复制代码

De hecho, hay un método más sencillo, que es .disableponerlo abajo, por la prioridad de css.

<p class="content disable"></p>

<style>
  .content:hover {
    background: black;
  }
  .content.disable {
    background: yellow;
  }
</style>
复制代码

Resumir

Lo anterior es todo el contenido de este artículo, es un pequeño registro para mí, espero que pueda ayudarlo.

Supongo que te gusta

Origin juejin.im/post/7079688237035290654
Recomendado
Clasificación