替换属于特定类的所有元素

时间:2018-10-04 10:22:37

标签: javascript

我正在尝试开发嵌入式小部件。用户将在其页面中包含一个anchor标签和一个javascript,它将呈现内容。类似于嵌入式推文。

<a href="http://localhost:3000/user/13"
        target="_blank"
        class="my-widget" 
        data-widget-type="profile" 
        data-widget-identifier="id" 
        data-identifier-value="13"
   >Sayantan Das</a>
</div>
<script src="//localhost/my-widget/js/widget.js" async ></script>

然后从widget.js中,我将使用class="my-widget"获得所有元素,并用iframe替换。

widgets.js

!function(global, document) {
    global.MyWidgets = global.MyWidgets || {};

    for(let widgets = document.getElementsByClassName('my-widget'), i = 0; i < widgets.length; i++) {
        console.log(widgets)
        let element = widgets[i];
        let span = document.createElement('span');

        span.innerHTML = "Changed from widget " + i;
        element.parentNode.appendChild(span);
        element.parentNode.removeChild(element);
    }

}(window, document);

问题是,当我删除元素时,循环还会运行较短的数字。例如,如果有两个元素的类为my-widget,则在第一次运行循环后,将删除一个元素,并且循环仅运行一次。如何替换所有元素?

2 个答案:

答案 0 :(得分:1)

这是因为getElementsByClassName返回了实时 HTMLCollection;当您从DOM中删除class="my-widget"元素时,该元素也将从集合中删除。

要么向后浏览整个集合(因此您要从头开始删除,这不会影响到之前的集合),或者使用querySelectorAll(".my-widget")来返回快照NodeList,而不是实时HTMLCollection

后退:

for(let widgets = document.getElementsByClassName('my-widget'), i = widgets.length - 1; i >= 0; i--) {

改为使用qSA:

for(let widgets = document.querySelectorAll('.my-widget'), i = 0; i < widgets.length; i++) {

,或者如果您不需要i(您似乎只是在使用它来获取元素并用于演示目的),则可以将for-ofNodeList s一起使用(在大多数平台上; this answer为其他平台提供了一个polyfill):

for (const element of document.querySelectorAll('.my-widget')) {
    // ...and remove the `let element = ...` line

答案 1 :(得分:0)

使用document.querySelectorAll达到小部件的长度