从HTML集合中通过externalHTML删除元素

时间:2019-01-04 09:49:55

标签: javascript dom htmlcollection

我有以下代码。我正在尝试通过将externalHTML设置为empty('')来删除元素。我还对html集合进行了很少的研究,发现它是一个实时集合

ref:

所以我所知道的是,如果我更改文档,则列表应该更改。该代码证明了这种行为,尽管我的初始html集合的长度为9,循环仍运行了4次。现在,当我用innerHTML替换externalHTML时,循环进行了9次。因此,如果列表应该随着文档的更改而更新,那么当我将innerHTML替换为innerHTML时为什么不发生这种情况

function expTble() {


    let tables = document.getElementsByTagName("table")

    let captions = document.getElementsByTagName("caption")


    if (captions.length > 1) {

        console.log(`${tables.length} tables ${captions.length} captions`)

        for (let i = 0; i < captions.length; i++) {

            console.log('index : ' + i)

            captions[i].outerHTML = ''

        }

        return

    }

    for (let i = 0; i < tables.length; i++) {
        // Do stuffs
        TableExport(tables[i], { bootstrap: false })
    }



}

这是我的结果

使用externalHTML时

9 tables 9 captions 
index : 0 
index : 1 
index : 2 
index : 3 
index : 4

使用innerHTML时

9 tables 9 captions 
index : 0 
index : 1 
index : 2 
index : 3 
index : 4 
index : 5 
index : 6 
index : 7 
index : 8

2 个答案:

答案 0 :(得分:2)

实时集合会在更改其元素引用时进行更新。在您的情况下,externalHTML更改了元素,这将更新集合。但是innerHTML是一个不同的部分。集合未引用该内容,因此对子元素的更改不会更新html集合。

如果要使用相同的逻辑删除元素,请使用While循环并检查,如果长度为0,然后通过第0个索引引用删除元素。

 if (captions.length > 1) {

        while (captions.length > 0) {
            captions[0].outerHTML = ''
        }

        return

    }

答案 1 :(得分:1)

这是由于您在一个引用数组上迭代前向(0-> n),同时操纵了它的长度而造成的。 删除元素bigList时,您正在积极缩短数组。 像本例一样:

i

这将输出以下内容:

let arr = ['A','B','C','D','E','F'];
console.log('started');
for (let i = 0; i < arr.length; i++) {
    var removed = arr.splice(i, 0);
    console.log('i:'+i,'Arr:',arr, '(removed ' + i + ')');
}
console.log('ended');

但是,如果您在哪里修改for循环以反向迭代,那么您将不会遇到此问题,因为您始终将未删除的元素作为目标。

started
i:0 Arr: [B,C,D,E,F] (removed A)
i:1 Arr: [B,D,E,F] (removed C)
i:2 Arr: [B,D,F] (removed E)
ended

那为什么只有在使用externalHtml时才会发生这种情况? 原因是for (let i = captions.length - 1; i >= 0; i--) { ... } 6 tables 6 captions index : 5 index : 4 index : 3 index : 2 index : 1 index : 0 清除元素的内容(x.innerHtml = ""-> <div>test</div>),而<div></div>覆盖元素本身(x.outerHtml = ""-> <div>test</div>