Reputation: 5071
I am wondering why e.offsetX
and e.offsetY
are different for clicking in the same place.
For the first click in a button e.offsetX
and e.offsetY
are correct but if you click a button before old ripple effect diapers than received event has incorrect e.offsetX
and e.offsetY
(always around 0). Because of this behavior my ripple effect has incorrect position if I click a button quickly many times.
e.offsetX
and e.offsetY
?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>
for those who prefer more JSFiddle
Upvotes: 1
Views: 1426
Reputation: 1326
I think it's because you end up getting the offset
of the ripple span, rather than the button. Adding a containing div like the below fixes it:
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>
Upvotes: 1
Reputation: 24671
offsetX
and offsetY
returns the position of event on the currentTarget
not target. So when you click for the second time you are targeting the span you've just created.
What I would have do is add pointer-events: none
to the span css.
Ther other way is to use offsetX
Wrong offsetX and offsetY on mousedown event of parent element
Upvotes: 2