亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

setTimeout() 中的代碼在多次調用時不會被執行

setTimeout() 中的代碼在多次調用時不會被執行

心有法竹 2022-06-09 10:30:57
我有以下功能:function deleteFood(index) {    // animate    document.getElementById(foodList[index].id).style.transform = 'translate(500px, 0)';    // delete from airtable    foodList[index].destroy();    window.setTimeout(() => {      // delete from state      let newState = foodList.slice();      newState.splice(index, 1);      setFoodList(newState);    }, 500);}基本上有一個列表,用戶可以在每個列表條目上單擊刪除。如果您單擊條目上的刪除,它會動畫,然后在刪除時消失。到目前為止,一切正常。但是,如果我非??斓卦趦蓚€條目上單擊刪除,則只有第二個被刪除。假設我們有 4 個條目(0,1,2,3),我在 1 和 2 上單擊刪除,然后列表仍然有 0,1,3。所有條目都是動畫的,并被稱為銷毀。我嘗試使用承諾無濟于事。我怎樣才能解決這個問題?
查看完整描述

2 回答

?
躍然一笑

TA貢獻1826條經驗 獲得超6個贊

正如您所指出的,如果您很快單擊刪除,則只有第二個被刪除,原因是索引變量在超時觸發之前被覆蓋,這就是為什么第二個是唯一被刪除的原因。

您可以立即刪除該項目,然后在動畫完成后保留超時以重置列表?;蛘?,為過渡已結束添加偵聽器以從列表中刪除項目,而不是等待超時。


查看完整回答
反對 回復 2022-06-09
?
慕斯王

TA貢獻1864條經驗 獲得超2個贊

萬一有人遇到這個,這就是我最終做的事情(謝謝@Lynyrd?。?/p>


// transition names (found in Modernizr)

let transEndEventNames = {

  'WebkitTransition': 'webkitTransitionEnd', // Saf 6, Android Browser

  'MozTransition': 'transitionend', // only for FF < 15

  'transition': 'transitionend', // IE10, Opera, Chrome, FF 15+, Saf 7+

};

我使用 React,所以我在 useEffect 中添加了事件偵聽器,以便在再次獲取 foodList 等時自動添加它們。


// add & remove event listeners for transition end

useEffect(() => {

  foodList.forEach((item, index) => {

    if (!document.getElementById(index)) return;

    document

      .getElementById(index)

      .addEventListener(

        transEndEventNames.WebkitTransition,

        handleTransitionEnd

      );

    document

      .getElementById(index)

      .addEventListener(

        transEndEventNames.MozTransition,

        handleTransitionEnd

      );

    document

      .getElementById(index)

      .addEventListener(transEndEventNames.transition, handleTransitionEnd);

  });


  return () => {

    foodList.forEach((item, index) => {

      if (!document.getElementById(index)) return;

      document

        .getElementById(index)

        .removeEventListener(

          transEndEventNames.WebkitTransition,

          handleTransitionEnd

        );

      document

        .getElementById(index)

        .removeEventListener(

          transEndEventNames.MozTransition,

          handleTransitionEnd

        );

      document

        .getElementById(index)

        .removeEventListener(

          transEndEventNames.transition,

          handleTransitionEnd

        );

    });

  };

}, [foodList]);

我決定不嘗試根據當前瀏覽器僅添加一個事件偵聽器,但這也是可能的。請記住,每次轉換都會觸發此偵聽器。結果,當有人將鼠標懸停在其中的元素上時(觸發了工具提示),我的表格條目被刪除。所以不要忘記過濾:


function handleTransitionEnd(event) {

  // only delete element for transform transition

  if (!(event.propertyName === 'transform')) return;

  let newState = foodList.slice();

  newState.splice(event.target.id, 1);

  setFoodList(newState);

}

就我而言,這很容易,因為我在元素上只有一個“變換”過渡。另外,我不知道 eventListener 的數量是否會成為較大表的性能問題?,F在根本不需要 setTimeout() 函數,在 deleteFood() 中,我現在只啟動動畫并從數據庫中刪除項目:


function DeleteFood(index) {

  // animate

  document.getElementById(index).style.transform = 'translate(500px, 0)';


  // delete from airtable

  foodList[index].destroy();

}


查看完整回答
反對 回復 2022-06-09
  • 2 回答
  • 0 關注
  • 281 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號