不寻找使用框架XXX回答
此问题并非旨在通过框架找到实用的解决方案。回答使用框架XXX ,或这在框架XXX 中是如此简单,或为什么不使用此框架XXX ??? 不回答问题。
我有一个函数意味着在加载页面后运行:performShim
。此函数迭代DOM中span
个标记的所有元素,检查它们是否className
shim
,如果是,则调用shim
传递给它{匹配的元素。
我的目标是预先包含span
的另一个iframe
到传递给shim
的元素。
到目前为止我写的代码,我能够追加到元素的父级就好了。但是,如果我注释掉append
行,而是尝试前置行,则浏览器会挂起,可能是无限循环。
对我来说,为什么会出现这种情况并不容易。
function shim( element ) {
var iframe = document.createElement('iframe');
iframe.setAttribute( 'frameborder', '0' );
iframe.setAttribute( 'scrolling', 'no' );
iframe.setAttribute( 'align', 'bottom' );
iframe.setAttribute( 'marginheight', '0' );
iframe.setAttribute( 'marginwidth', '0' );
iframe.setAttribute( 'src', "javascript:'';" );
var span = document.createElement('span');
span.appendChild(iframe);
//element.parentNode.insertBefore(span,element); //causes infinite loop?
element.parentNode.appendChild(span); //this line works OK
var els = element.style;
var originalVisibility = els.visibility;
var originalPosition = els.position;
var originalDisplay = els.display;
els.visibility = 'hidden';
els.position = 'absolute';
els.display = 'inline';
var width = element.offsetWidth;
var height = element.offsetHeight;
els.display = originalDisplay;
els.position = originalPosition;
els.visibility = originalVisibility;
iframe.style.width = (width-6) + 'px';
iframe.style.height = (height-6) + 'px';
}
function performShim() {
var children = document.getElementsByTagName("span");
for( var i = 0; i < children.length; i++ ) {
if( children[i].className == "shim" ) {
shim(children[i]);
}
}
}
答案 0 :(得分:8)
NodeList
(例如document.getElementsByTagName
返回的那个)通常是 live 列表 - 您对DOM所做的更改也会显示在其中。因此,每次在当前元素之前添加span
时,您将列表扩展一个元素并将当前元素移动一个,然后下一个迭代将您返回到刚刚完成的节点。 / p>
你有几个简单的解决方法...
在添加节点时将计数器搞砸。(丑陋,如果你最终添加的东西而不是span
,你最终会跳过节点和为什么不明显。)
将列表复制到数组并遍历数组。你可以用类似的东西做到这一点
children = [].slice.call(children, 0);
(更常见)或
children = Array.apply(window, children);
。
使用document.querySelectorAll
,它会返回一个不活动的NodeList。 (即使它是实时的,在这种情况下,您可以选择'span.shim'
,插入的跨距也不会显示在其中。)
向后迭代(从children.length - 1
到0)。