我试图开发一个嵌入式小部件。用户将包括一个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
.
小部件.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);
问题是,当我删除元素时,循环也会运行更短的数字。例如,如果有两个具有 class 的元素my-widget
,第一次循环运行后,一个元素被删除,循环仅运行一次。如何替换所有元素?
那是因为getElementsByClassName
返回一个live HTMLCollection
;当你删除class="my-widget"
元素从 DOM 中删除,它也会从集合中删除。
要么向后遍历集合(这样您就可以从末尾删除,这不会影响之前的集合),或者使用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-of
with NodeList
现在(在大多数平台上;这个答案 https://stackoverflow.com/questions/46929157/foreach-on-queryselectorall-not-working-in-recent-microsoft-browsers/46929259#46929259有其他人的填充):
for (const element of document.querySelectorAll('.my-widget')) {
// ...and remove the `let element = ...` line
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)