Je me demande pourquoi e.offsetX et e.offsetY sont différents pour cliquer au même endroit. Pour le premier clic dans un bouton e.offsetX et e.offsetY sont corrects, mais si vous cliquez sur un bouton avant les anciennes couches à effet ondulation , l'événement reçu est incorrect e.offsetX et { {X5}} (toujours autour de 0). En raison de ce comportement, mon effet d'entraînement a une position incorrecte si je clique rapidement plusieurs fois sur un bouton.

  • Pourquoi cet événement a de tels e.offsetX et e.offsetY?
  • Comment puis-je corriger la position de mon effet d'entraînement sans utiliser e.target?
const button = document.querySelector('button');

button.addEventListener('click', (e) => {
    const ripple = document.createElement('span');
    ripple.style.left = `${e.offsetX}px`;
    ripple.style.top = `${e.offsetY}px`;
    button.appendChild(ripple);
    window.setTimeout(() => {
        ripple.remove();
    }, 1000);
});
button {
  overflow: hidden;
    position: relative;
    width: 200px;
    height: 200px;
    border: 2px solid black;
}

button > span {
    position: absolute;
    background-color: green;
    border-radius: 50%;
    width: 1px;
    height: 1px;
    animation: ripple 1.0s linear infinite;
}
    
@keyframes ripple {
    0% {
        opacity: 0.7;
    }
    100% {
        opacity: 0;
        transform: scale(1000);
    }
}
<button>Test</button>

Pour ceux qui préfèrent plus JSFiddle

0
Krzysztof Kaczyński 22 août 2020 à 01:08

2 réponses

Meilleure réponse

offsetX et offsetY renvoie la position de l'événement sur le currentTarget non cible. Ainsi, lorsque vous cliquez pour la deuxième fois, vous ciblez la plage que vous venez de créer. Ce que j'aurais fait, c'est ajouter pointer-events: none au css span.

L'autre moyen consiste à utiliser offsetX Mauvais offsetX et offsetY sur l'événement mousedown de l'élément parent

1
Konrad Linkowski 21 août 2020 à 22:42

Je pense que c'est parce que vous obtenez le offset de la plage d'ondulation, plutôt que le bouton. L'ajout d'un div contenant comme ci-dessous le corrige:

const button = document.querySelector('button');
const div = document.querySelector('div');
button.addEventListener('click', (e) => {
    const ripple = document.createElement('span');
    ripple.style.left = `${e.offsetX}px`;
    ripple.style.top = `${e.offsetY}px`;
    div.appendChild(ripple);
    window.setTimeout(() => {
        ripple.remove();
    }, 1000);
});
div {
  overflow: hidden;
    position: relative;
    width: 200px;
    height: 200px;
    border: 2px solid black;
}

button {
    width: 100%;
    height: 100%;
}

span {
    position: absolute;
    background-color: green;
    border-radius: 50%;
    width: 1px;
    height: 1px;
    animation: ripple 0.6s linear infinite;
}
    
@keyframes ripple {
    0% {
        opacity: 0.7;
    }
    100% {
        opacity: 0;
        transform: scale(1000);
    }
}
<div>
<button>Test</button>
</div>
1
dbramwell 21 août 2020 à 22:48