为什么 ForEach 只注册数组中的第一个元素?

问题描述

目标

我试图将每个 奖项类别 的高度限制为 3 个奖项 div 的总高度。这样做的原因是它是动态的,高度可能会根据用户输入的奖励信息而有所不同。

链接到 CodePen 以获取更多上下文:https://codepen.io/Kaleshe/pen/QWpdJQq

问题

出于某种原因,只有第一个元素被注册,我不知道为什么。

根据错误,循环中的下一项是未定义的,但如果我控制台将它记录在循环之外,它会被拾取,就像这样 awardCatContainers[0].querySelectorAll('.award')

代码

const awardCatContainers = document.querySelectorAll( '.award-category-container' );
const button = document.querySelector( '.award .button' );

awardCatContainers.forEach( (container) => {
    let awards = container.querySelectorAll( '.award' );
    let height = getContainerHeight(awards);

    container.style.maxHeight = height + 'px';
});

function getContainerHeight(containerChildren) {
    let height = 0;

    for ( let a = 0; a <= 3; a++ ) {
        height += containerChildren[a].offsetHeight;
    }

    return height;
}

编辑/解决

在查看了H. Udara 我能够确认我的方法有效。引导我做进一步的调试。

然后我意识到错误是由于没有检查某个类别是否有 3 个或更少的奖项。添加此检查和常量以指定每个类别应显示的最大元素后,代码现在可以工作了。

const containers = document.querySelectorAll( '.award-category-container' );
const maxElems = 4;
for ( let c = 0; c < containers.length; c++) {
    let awards = containers[c].querySelectorAll( '.award' );
    if ( awards.length >= maxElems ) {
        let height = setContainerHeight(awards);
        containers[c].style.maxHeight = height + 'px';
    }
}

// Takes an array of children and uses the total offsetHeight of the first 3 elements to create a height
function setContainerHeight(containerChildren) {
    let height = 0;

    for ( let a = 0; a < maxElems; a++ ) {
        height += containerChildren[a].offsetHeight;
    }

    return height;
}         

解决方法

querySelector 返回一个静态的 NodeList。因此,当运行此代码时,页面中可能只呈现一个元素。您可以尝试做的是向此代码添加超时。这将帮助您调试问题。

但是不要把它作为你的最终代码。因为您永远无法确定超时期限。如果网络太慢,加载元素可能需要 3 秒多的时间。查看承诺或回调并实现您的最终代码。如果您在创建元素之前进行 AJAX 调用以获取数据,请使用 AJAX 提供的回调来确定 AJAX 调用是否完成。

const awardCatContainers = document.querySelectorAll( '.award-category-container' );
const button = document.querySelector( '.award .button' );
// set a timeout
setTimeout(() => {awardCatContainers.forEach( (container) => {
    let awards = container.querySelectorAll( '.award' );
    let height = getContainerHeight(awards);

    container.style.maxHeight = height + 'px';
})},3000);

function getContainerHeight(containerChildren) {
    let height = 0;

    for ( let a = 0; a <= 3; a++ ) {
        height += containerChildren[a].offsetHeight;
    }

    return height;
}
,

您需要循环奖励并应用样式:

awardCatContainers.forEach( (container) => {
    let awards = container.querySelectorAll( '.award' );
    let height = getContainerHeight(awards);

    //container.style.maxHeight = height + 'px';
    for (let award of awards) award.style.maxHeight = height + 'px';
});

我可能误解了您的问题,在这种情况下,您需要提供更多信息。

getContainerHeight 也很奇怪,你从 0 到 3。如果我知道你的结构是什么,这对理解你的确切意图会有很大帮助。