如何从 forEach 方法中删除不需要的计数增量?
How to remove unwanted counting-increment from forEach method?
我在 CodePen.
中无法从 forEach
方法中删除不需要的计数增量
算法简单:
EventManager()
为每个 menuCells
.
注册一个名为 mouseenter
的事件
menuCount()
获取目标单元格的电流 index
。接下来,在新节点的 index
之间匹配它以显示或隐藏 slateCell
.
slateCount()
从 menuCount()
获取目标 item
,并使用 forEach()
获取 li
的索引。
问题是每次我 重新启动事件 时, forEach()
本身的增量会不时增加,就像这样:(无法想象更好描述单词。词汇量有限的问题:|)
这可能不是什么大问题,因为该函数所做的实际上只是获取索引。但是因为我注意到这是不正常的,所以我想知道为什么以及如何摆脱不需要的增量计数。
我一直在努力寻找如何解决我的案件或类似我的案件,但仍然没有找到任何信息或文章。
是否有解决此问题的解决方案?
'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>
根据您的代码,每次将鼠标悬停在顶部菜单时,for-loop 就是 运行 在可选项目上添加事件侦听器。因此,如果您第一次将鼠标悬停在 slate 项目上,行为与您预期的相同,仅记录一次。但是,如果你重复悬停菜单的动作,越来越多的相同事件监听器将被添加到 slate items,所以日志开始快速爆炸,导致内存泄漏。
为了解决这个问题,将添加事件监听器的逻辑提取到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}`);
})
})
}
我在 CodePen.
中无法从forEach
方法中删除不需要的计数增量
算法简单:
EventManager()
为每个menuCells
. 注册一个名为 menuCount()
获取目标单元格的电流index
。接下来,在新节点的index
之间匹配它以显示或隐藏slateCell
.slateCount()
从menuCount()
获取目标item
,并使用forEach()
获取li
的索引。
mouseenter
的事件
问题是每次我 重新启动事件 时, forEach()
本身的增量会不时增加,就像这样:(无法想象更好描述单词。词汇量有限的问题:|)
这可能不是什么大问题,因为该函数所做的实际上只是获取索引。但是因为我注意到这是不正常的,所以我想知道为什么以及如何摆脱不需要的增量计数。
我一直在努力寻找如何解决我的案件或类似我的案件,但仍然没有找到任何信息或文章。
是否有解决此问题的解决方案?
'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>
根据您的代码,每次将鼠标悬停在顶部菜单时,for-loop 就是 运行 在可选项目上添加事件侦听器。因此,如果您第一次将鼠标悬停在 slate 项目上,行为与您预期的相同,仅记录一次。但是,如果你重复悬停菜单的动作,越来越多的相同事件监听器将被添加到 slate items,所以日志开始快速爆炸,导致内存泄漏。
为了解决这个问题,将添加事件监听器的逻辑提取到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}`);
})
})
}