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 mouseenter
encontent
activarsepointer-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: none
a los anteriores, echemos un vistazo al orden de impresión:
// container mouseenter
// content mouseenter
复制代码
¿Por qué? Echemos un vistazo a pointer-events:none
la 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 .mask
agregamos 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 .mask
agregamos un niño .mask-child
y luego escuchamos sus mouseenter
eventos, echemos un vistazo al efecto:
// container mouseenter
// mask mouseenter
// maskChild mouseenter
复制代码
Como era de esperar, sigue siendo el mismo mask
evento 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-events
volver a especificar atributos, de lo contrario, seguirá fallando.
Ejemplo
- 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.
- Además, si se establece
:hover
, la:active
pseudoclase no se activará.
Como antes, si quisiéramos cancelar el hover
efecto 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 .disable
ponerlo 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.