0

我有以下代码。我试图通过将outerHTML设置为空('')来删除一个元素。我也对html集合做了一些研究,发现它是一个活的集合

参考:

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

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 })
    }



}

这是我的结果

使用 outerHTML 时

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
4

2 回答 2

2

实时集合在其引用的元素发生更改时自行更新。在您的情况下,outerHTML 会更改元素,这会更新集合。但是innerHTML 是一个不同的部分。它不是集合引用的东西,因此对子元素的更改不会更新 html 集合。

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

 if (captions.length > 1) {

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

        return

    }
于 2019-01-04T10:13:33.387 回答
1

这是由于您在引用数组上向前迭代 (0->n) 并同时操纵它的长度。当您删除元素时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');

这将输出以下内容:

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

但是,如果您在哪里修改您的 for 循环以反向迭代,您将不会遇到此问题,因为您总是会定位一个尚未删除的元素。

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

那么为什么只有在使用 outerHtml 时才会发生这种情况呢?这样做的原因是x.innerHtml = ""清除元素的内容(<div>test</div>-> <div></div>),同时x.outerHtml = ""覆盖元素本身(<div>test</div>-> )。

于 2019-01-04T10:20:39.640 回答