Reputation: 1672
I'm trying to make my web app a little more user friendly, and instead of instantly removing an element I want it to fade away before actually being removed. The problem is my code is running too quickly. While I understand everything is working correctly, I need it to wait for the element to "disappear" before actually being removed. Is this a good example of when to use a Promise
or should I use setTimeout()
?
check if variables exist
if button is clicked change element opacity (transition: opacity 1s;)
then call deletePostPromise()
then remove the element from the dom
As you can see, I'm even writing my pseudocode as a promise, then.. then..
.
Specifically, start at row.style.opacity = '0';
if (displayPostWrapper && submitPostBtn) {
displayPostWrapper.addEventListener('click', e => {
if (e.target && e.target.nodeName == 'BUTTON') {
e.preventDefault();
const { parentElement } = e.target;
const row = parentElement.parentElement.parentElement;
const form = parentElement;
const postID = parentElement.childNodes[3].value;;
row.style.opacity = '0';
deletePostPromise('http://localhost/mouthblog/ajax/delete_post.ajax.php', `id=${postID}`)
.then(() => {
row.remove();
});
// row.remove();
} // if
}); // click event
const deletePostPromise = (url, postID) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.onload = () => {
if (xhr.status == 200) {
console.log('if (xhr.status == 200)');
resolve();
} else {
reject(xhr.statusText);
}
};
xhr.onerror = () => {
reject(xhr.statusText);
};
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(postID);
});
}
if (displayPostWrapper && submitPostBtn) {
displayPostWrapper.addEventListener('click', e => {
if (e.target && e.target.nodeName == 'BUTTON') {
e.preventDefault();
const { parentElement } = e.target;
const row = parentElement.parentElement.parentElement;
const form = parentElement;
const postID = parentElement.childNodes[3].value;;
row.style.opacity = '0';
deletePostPromise('http://localhost/mouthblog/ajax/delete_post.ajax.php', `id=${postID}`);
row.addEventListener("transitionend", function(event) {
// alert('Done!');
row.remove();
}, false);
} // if
}); // click event
.row {
opacity: 1;
transition: opacity 5s;
}
Upvotes: 0
Views: 97
Reputation: 707376
You can set a listener using the transitionend
event that will tell you when the opacity transition has completed and then you can remove the element then.
row.addEventListener("transitionend", function(event) {
console.log("transition completed, removing row");
row.remove();
}, false);
You would add this listener right before you change the opacity which triggers the start of the fadeout.
Here's a simple working example that you can run to see it work.
function log(msg) {
let div = document.createElement("div");
div.innerHTML = msg;
document.getElementById("log").appendChild(div);
}
document.getElementById("run").addEventListener("click", function() {
document.getElementById("test").style.opacity = 0;
});
let test = document.getElementById("test");
test.addEventListener("transitionend", function(e) {
log(`transitionend for ${e.propertyName}, removing DOM element`)
test.remove();
});
.fade {
opacity: 1;
transition: opacity 2s;
}
<button id="run">
Start Animation
</button>
<div class="fade" id="test">
Some content that will fade out
</div>
<div id="log">
</div>
Upvotes: 1