Javascript For循环附加子元素只附加第一个元素,然后抛出错误

Posted

技术标签:

【中文标题】Javascript For循环附加子元素只附加第一个元素,然后抛出错误【英文标题】:Javascript For loop appending child only appends first element, then throws error 【发布时间】:2017-03-18 01:04:49 【问题描述】:

我正在循环一个带有嵌套 for 循环的 js 对象,如下所述,它正确地附加了第一个元素,但随后引发以下错误: Can't set the property className of an undefined reference or empty reference.(不确定是否准确,翻译自荷兰语...)

function allVideos() 
    var sql = "SELECT videos.VideoName, videos.VideoPath FROM videos";
    var resultSet = db.query(sql, json:true); //returns: ["VideoName":"timelapse aethon2","VideoPath":"videos\\Roermond Papier\\160424 Time laps Aethon2.avi","VideoName":"timelapse aethon3","VideoPath":"videos\\Roermond Papier\\160424 Time laps Aethon2.avi"]
    var parsed = JSON.parse(resultSet);
    var parsedlength = arrLenght(parsed);
    //alert(resultSet);
    for(var i = 0; i < parsedlength; i++) 
        var obj = parsed[i];
        //alert(i);
        var videoElement = document.getElementById("allVideos");
        for (var key in obj) 
            if(obj.hasOwnProperty(key)) 

                videoElement.appendChild(document.createElement('div'));
                videoElement.children[i].id='allVid' + i;
                videoElement.children[i].className='col-md-4 col-xs-12';
                //alert(typeof key)
                var card = document.getElementById('allVid' + i);
                alert(i);
                card.appendChild(document.createElement('div'));
                card.children[i].className='card card-block';
                card.children[i].innerhtml = "<h3 class='card-title'>" + obj['VideoName'] + "</h3><button class='btn btn-primary'>Selecteren</button>"
            
        
    

[EDIT] 添加了外观截图

【问题讨论】:

【参考方案1】:

您的代码存在一些严重的逻辑问题。您正在使用嵌套循环,但附加到一个元素,假设 outer 循环计数器将让您索引到该元素的子元素以获取您刚刚附加的元素。稍后,您尝试使用getElementById 再次获取相同的元素。然后,您将一个新元素附加到新创建的元素,但尝试在您刚刚创建的元素上使用 children[i] 访问该新元素 - 此时,card 元素将只有一个子元素,因此第二个外循环,它会失败。

createElement 将元素返回给您,因此完全没有理由尝试通过children[i](任何时间)或getElementById 访问它。

见 cmets:

function allVideos() 
    var sql = "SELECT videos.VideoName, videos.VideoPath FROM videos";
    var resultSet = db.query(sql, json:true);
    var parsed = JSON.parse(resultSet);
    var parsedlength = arrLenght(parsed);
    for(var i = 0; i < parsedlength; i++) 
        var obj = parsed[i];
        //alert(i);
        var videoElement = document.getElementById("allVideos");
        for (var key in obj) 
            if(obj.hasOwnProperty(key)) 
                // Create the card, give it its id and class
                var card = document.createElement('div');
                card.id='allVid' + i;
                card.className='col-md-4 col-xs-12';

                // Create the div to put in the card, give it its class and content
                var div = document.createElement('div');
                card.appendChild(div);
                div.className='card card-block';
                div.innerHTML = "<h3 class='card-title'>" + obj['VideoName'] + "</h3><button class='btn btn-primary'>Selecteren</button>"

                // Append the card
                videoElement.appendChild(card);
            
        
    


旁注:arrLenght 看起来像是一个错字(应该是th,而不是ht),但此外,没有理由使用函数来获取数组的长度;它可以通过数组的length 属性获得:parsedLength = parsed.length

附注 2:您可能会发现 these ways of looping through arrays 很有用。

【讨论】:

哦,哇,我现在意识到这个逻辑确实是多么愚蠢,你的回答有帮助,虽然其中有一个很小的错误,videoElement.appendChild(card) 不应该在嵌套的 for 循环中,因为这将导致双打,相反,我把它放在第一个 for 循环中。 @Luuk:如果videoElement.appendChild(card)不应该在内部循环中,我们可能需要调整创建card的逻辑...? 由于某种原因,它在内循环之外与 videoElement.appendChild(card) 完美配合【参考方案2】:

您的问题是嵌套 for 中的 if:

 if(obj.hasOwnProperty(key))  ...

即使属性不是“拥有”(当 if 条件返回 false 时),变量 i 也会增加,因此下次条件为真时,i 超出范围。

【讨论】:

不,这是在内部循环中。确实使用i 来索引children 是一个问题,但主要问题是试图使用它来索引根据定义只有一个子元素的元素。

以上是关于Javascript For循环附加子元素只附加第一个元素,然后抛出错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery 在 for 循环中正确附加元素

JavaScript嵌套元素循环并附加bug?

批处理:如何在 FOR 循环中附加字符串

附加到数据帧中特定值的 for 循环中的向量

Pandas 将浮点数附加到 for 循环中的列

通过for循环将值附加到向量不起作用