JavaScript:代码移动得太快,我应该写一个Promise吗?

时间:2018-01-27 16:23:25

标签: javascript asynchronous promise settimeout

我正在尝试使我的网络应用程序更加用户友好,而不是立即删除一个元素,我希望它在实际删除之前逐渐消失。问题是我的代码运行得太快了。虽然我理解一切正常,但我需要等待元素在实际删除之前“消失”。这是何时使用Promise或我应该使用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

正如您所看到的,我甚至将我的伪代码写为承诺then.. then..

具体来说,从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

修改

JS

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

CSS

.row {
      opacity: 1;
      transition: opacity 5s;
    }

1 个答案:

答案 0 :(得分:1)

您可以设置listener using the transitionend event,告诉您何时完成不透明度转换,然后您可以删除元素。

row.addEventListener("transitionend", function(event) {
  console.log("transition completed, removing row");
  row.remove();
}, false);

您可以在更改触发淡出开始的不透明度之前添加此侦听器。

这是一个简单的工作示例,您可以运行它以查看它是否有效。



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>
&#13;
&#13;
&#13;