代码之家  ›  专栏  ›  技术社区  ›  Shruggie

jsdom操作

  •  3
  • Shruggie  · 技术社区  · 6 年前

    我遇到了一个有趣的bug elt 未定义对的某些调用 switchToReady . 它看起来像里面的功能 setTimeout 正在两次传递相同的DOM节点。

    function switchToReady(elt) {
        elt.setAttribute('transform', 'translate(17, 0)');
        elt.classList.remove('compiling');
    }
    
    const compilingElts = document.getElementsByClassName('compiling');
    for (let i = 0; i < compilingElts.length; i++) {
        const randTime = Math.round(Math.random() * (2000 - 500)) + 500;
        setTimeout(() => {
            switchToReady(compilingElts[i]);
        }, randTime);
    }
    
    3 回复  |  直到 6 年前
        1
  •  4
  •   CertainPerformance    6 年前

    getElementsByClassName 返回一个 集合,这意味着如果集合中元素的类发生更改 ,或者如果您向DOM中添加了另一个具有该类的元素,那么您所在的索引(例如,如果 i 2 )可能不再引用那里的旧元素-它可能引用集合中的下一个项目,或上一个项目,甚至可能是 undefined . 这种行为非常不直观,因此我建议使用 querySelectorAll 静止的 NodeList

    const compilingElts = document.querySelectorAll('.compiling');
    

    其他好处 查询选择器 :

    • 它接受为参数的选择器字符串可以是 非常

    • forEach 直接在 节点主义者 ,从而消除了手动迭代和跟踪指标的需要:

      compilingElts.forEach((elm) => {
        const randTime = Math.round(Math.random() * (2000 - 500)) + 500;
        setTimeout(() => {
            switchToReady(elm);
        }, randTime);
      });
      

    使用数组方法比使用 for HTMLCollection 产生于 getElementsByClassName 是用 Array.prototype.forEach :

    Array.prototype.forEach.call(
      compilingElts,
      (elm) => {
        // do stuff with elm
      }
    );
    

    (快捷方式是使用 [].forEach.call Array.prototype 更清楚一点(我的意思是)

        2
  •  3
  •   Felix Kling    6 年前

    getElementsByClassName 返回一个活动列表,正如您所注意到的,这意味着如果从元素中删除该类,该列表将更改(其大小)。

    你可以用 document.querySelectorAll('.compiling')

        3
  •  1
  •   Shruggie    6 年前

    compilingElts 对象