javascript 如何使所有单击都调用按钮单击函数,以等待上一个事件侦听器在再次执行之前完成

kb5ga3dv  于 2023-01-16  发布在  Java
关注(0)|答案(1)|浏览(162)

我有一个函数slideUp(),它在点击按钮时调用,点击事件调用另一个异步函数removeSlideUp(),它返回一个承诺。但是多次点击按钮会立即调用removeSlideUp(),我希望所有的点击都在"transitionend"事件完成后一个接一个地查询和调用removeSlideUp()。我是javascript的新手,不知道我在哪里卡住了
这是我代码

async function slideUp() {
  await removeSlideUp();
}

function removeSlideUp() {
  return new Promise(function (resolve, reject) {
    //console.log(smartAlert.classList.contains("slideup"));
    if (smartAlert.classList.contains("slideup") === false) {
      smartAlert.classList.add("slideup");
      smartAlert.addEventListener(
        "transitionend",
        function () {
          console.log("completed");
          smartAlert.classList.remove("slideup");
          resolve();
        },
        { once: true }
      );
    } else {
      smartAlert.classList.remove("slideup");
      resolve();
    }
  });
}

$('button[name="btn_show"]').click(function () {
  slideUp();
});

注:需要在纯JavaScript中完成,没有jquery或其他框架,我无法在调用removeSlideUp时逐个执行点击,它确实产生了预期的结果
允许以下代码正确地从transitionend事件获取承诺。代码承诺返回代码取自第二种方法的resolving a promise with EventListener,以供@Volune回答

//lets start playing
const buttonShow = document.getElementById("btn_show");
buttonShow.addEventListener("click", async () => {
  let result;
  switch (smartAlert.classList.contains("slideup")) {
    case true:
      smartAlert.classList.remove("slideup"); //this line triger the transition to happen
      result = await transitoinEnd("Show alert is complete");
      console.log(result);
      break;

    default:
      smartAlert.classList.add("slideup");
      result = await transitoinEnd("Hide alert is complete");
      console.log(result);
      setTimeout(() => {
        smartAlert.classList.remove("slideup");
      }, 1000);
      result = await transitoinEnd("Show alert is complete");
      console.log(result);
  }
});

const buttonHide = document.getElementById("btn_hide");
buttonHide.addEventListener("click", async () => {
  smartAlert.classList.add("slideup"); //this line triger the transition to happen
  const result = await transitoinEnd("Hide alert is complete");
  console.log(result);
});

const smartAlert = document.getElementById("smart-alert");
const transitoinEnd = (message) => {
  return new Promise((resolve) => {
    smartAlert.addEventListener(
      "transitionend",
      (animationendListener = () => {
        smartAlert.removeEventListener(
          "transitionend",
          animationendListener
        );
        //call any handler you want here, if needed
        resolve(message);
      })
    );
  });
};
toe95027

toe950271#

我希望所有的点击一个接一个地查询和调用removeSlideup() *
是的,那么你需要一个队列。目前你的代码中没有队列。最简单的方法就是使用一个承诺链:

let queue = Promise.resolve();
$('button[name="btn_show"]').click(function () {
  queue = queue.then(slideUp);
});

相关问题