【问题标题】:How to remove unwanted counting-increment from forEach method?如何从 forEach 方法中删除不需要的计数增量?
【发布时间】:2019-05-18 16:15:25
【问题描述】:

在我的 CodePen 中,我无法从 forEach 方法中删除不需要的计数增量。

算法很简单:

  1. EventManager() 向每个menuCells 注册一个名为mouseenter 的事件。

  2. menuCount() 获取目标单元格的当前index。接下来,在新节点的index 之间进行匹配,以显示或隐藏slateCell

  3. slateCount()menuCount()获取目标item,并使用forEach()获取li的索引。

问题是每次我重新开始活动时,forEach() 本身的增量会不时增加,如下所示:(无法想象更好的描述词。词汇量有限的问题: |)

这可能不是一个大问题,因为该函数实际上只是获取一个索引。但由于我注意到这是不正常的,我想知道为什么以及如何摆脱这种不需要的增量计数。

我一直在寻找如何解决我的案例或类似我的案例,但仍然没有找到任何信息或文章。

有没有办法解决这个问题?

CodePen

'use strict';
const Slater = (function() {
  let menu = document.querySelector('.menu'),
      slate = document.querySelector('.slate');

  let node_menuCells = menu.querySelectorAll('.cell'),
      node_slateCells = slate.querySelectorAll('.grid.first > .cell');

  let menuCells = Array.from(node_menuCells);
  
  function EventManager(array, node) {
    array.reduce((init, length, current) => {
      node[current].addEventListener('mouseenter', (e) => menuCount(e, current, node_slateCells));
    }, 0);
  }
  function menuCount(event, index, node) {
    console.log(`menuCell count is: ${index}`);
    node.forEach((item, i) => {
      let comparing = (i == index) ? item.classList.add('shown') : item.classList.remove('shown');
      slateCount(item);
    })
  }
  function slateCount(item) {
    let node_cellItems = item.querySelectorAll('li');
    node_cellItems.forEach((listItem, n) => {
      listItem.addEventListener('mouseenter', (e) => {
        console.log(`slateCell count is: ${n}`);
      })
    })
  }
  return {
    initialize: EventManager(menuCells, node_menuCells)
  }
}());
      * {
        margin: 0;
        padding: 0;
        color: white;
      }
      ul li {
        list-style: none;
        text-decoration: none;
        padding: 20px 0;
      }
      .layout {
        width: 900px;
        display: flex;
        flex-flow: row;
        align-items: center;
        background-color: #414141;
      }
      .menu {
        height: 60px;
      }
      .cell {
        
        margin: 0 20px;
        font-family:'Helvetica';
      }
      .slate {
        border-top: 1px solid rgb(160, 117, 0);
        height: 20rem;
      }
      .grid {
        width: 50%;
        height: 100%;
        border: 1px solid rgb(160, 117, 0);
      }
      .grid > .cell {
        display: none;
        position: absolute;
        color: rgb(36, 88, 21);
      }
      .shown {
        display: block !important;
      }
    <div class="menu layout">
      <div class="cell">Lorem</div>
      <div class="cell">Ipsum Dolor</div>
      <div class="cell">Consectetur</div>
      <div class="cell">Similique</div>
    </div>
    <div class="slate layout">
      <div class="grid first">
        <ul class="cell">
          <li>Sample Text 001</li>
          <li>Sample Text 002</li>
        </ul>
        <ul class="cell">
          <li>Sample Text 003</li>
          <li>Sample Text 004</li>
        </ul>
      </div>
      <div class="grid second">
        <ul class="cell">
          <li>Sample Text 001</li>
          <li>Sample Text 002</li>
        </ul>
        <ul class="cell">
          <li>Sample Text 003</li>
          <li>Sample Text 004</li>
        </ul>
      </div>
    </div>

【问题讨论】:

    标签: javascript events indexing foreach increment


    【解决方案1】:

    从您的代码中,每次您将鼠标悬停在顶部菜单时,都会运行一个 for 循环以在 slate 项目上添加事件侦听器。因此,如果您第一次悬停平板项目,则行为与您预期的相同,只记录一次。但是,如果你重复悬停菜单的动作,将会有越来越多的相同事件监听器添加到 slate 项目中,因此日志开始快速爆炸,导致内存泄漏。

    为了解决这个问题,将添加事件侦听器的逻辑提取到 init 函数中,使其只执行一次。

    function EventManager(array, node) {
        array.reduce((init, length, current) => {
            node[current].addEventListener('mouseenter', (e) => menuCount(e, current, node_slateCells));
        }, 0);
    
        // add the event listeners here
        node_slateCells.forEach(item => slateCount(item));
    }
    
    function menuCount(event, index, node) {
        console.log(`menuCell count is: ${index}`);
        node.forEach((item, i) => {
            let comparing = (i == index) ? item.classList.add('shown') : item.classList.remove('shown');
            // slateCount(item);
        })
    }
    
    function slateCount(item) {
        let node_cellItems = item.querySelectorAll('li');
        node_cellItems.forEach((listItem, n) => {
            listItem.addEventListener('mouseenter', (e) => {
                console.log(`slateCell count is: ${n}`);
            })
        })
    }
    

    【讨论】:

    • 该死,无法想象解决方案有多简单,感谢您帮助整理我的问题。
    猜你喜欢
    • 2020-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-05
    • 2011-11-30
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    相关资源
    最近更新 更多