Как убрать ненужный подсчет-приращение из метода forEach? - PullRequest
1 голос
/ 18 мая 2019

У меня возникла проблема, чтобы избавиться от нежелательного приращения счета из метода forEach в моем CodePen .

Алгоритм прост:

  1. EventManager() регистрирует событие с именем mouseenter для каждого из menuCells.

  2. menuCount() получает текущий index целевой ячейки.Затем сопоставляет его между index нового узла для показа или сокрытия slateCell.

  3. slateCount() получает целевой item из menuCount() и использует forEach() для получения индекса li.

Проблема заключается в том, что каждый раз, когда я перезапускаю событие , приращение самого forEach() увеличиваетсявремя от времени, как это: (не могу себе представить лучше описания слов. Ограниченная проблема словарного запаса: |)

enter image description here

Это не может быть большой проблемой, потому чтото, что делает функция - это просто получение индекса.Но так как я заметил, что это ненормально, я хотел знать, почему и как избавиться от этого нежелательного подсчета приращений.

Я пытался найти, как разрешить мой случай или такой, как мой, но все еще нет 'не нашел какой-либо информации или статей.

Есть ли способы решения этой проблемы?

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>

1 Ответ

1 голос
/ 18 мая 2019

Из вашего кода каждый раз, когда вы наводите верхнее меню, запускается цикл for для добавления прослушивателей событий на элементы списка. Так что, если вы впервые наводите на планшет, то поведение будет таким же, как вы ожидаете, входя в систему только один раз. Однако, если вы повторите действие при наведении курсора на меню, все больше и больше слушателей одного и того же события будут добавляться в элементы списка, поэтому журнал начинает быстро взрываться, вызывая утечки памяти.

Чтобы решить эту проблему, извлеките логику добавления прослушивателей событий в функцию 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}`);
        })
    })
}
...