Javascript DOM中通过前置元素的无限循环
不寻找使用框架XXX答案 这个问题不是为了通过一个框架找到一个实际的解决方案。回答使用框架XXX,或者这在框架XXX中很容易,或者为什么不使用这个框架XXX???没有回答这个问题 我有一个在加载页面后运行的函数:Javascript DOM中通过前置元素的无限循环,javascript,dom,internet-explorer-6,infinite-loop,Javascript,Dom,Internet Explorer 6,Infinite Loop,不寻找使用框架XXX答案 这个问题不是为了通过一个框架找到一个实际的解决方案。回答使用框架XXX,或者这在框架XXX中很容易,或者为什么不使用这个框架XXX???没有回答这个问题 我有一个在加载页面后运行的函数:performShim。此函数迭代DOM中属于span标记的所有元素,检查它们是否有className的shim,如果有,则调用shim向其传递匹配元素的引用 我的目标是为传递给shim的元素预先添加另一个span,其中包含iframe 使用到目前为止我编写的代码,我能够很好地附加到元素
performShim
。此函数迭代DOM中属于span
标记的所有元素,检查它们是否有className
的shim
,如果有,则调用shim
向其传递匹配元素的引用
我的目标是为传递给shim
的元素预先添加另一个span
,其中包含iframe
使用到目前为止我编写的代码,我能够很好地附加到元素的父元素。但是,如果我注释掉append
行,而尝试使用prepend行,那么浏览器可能挂起在一个无限循环中
我不太清楚为什么会这样
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]);
}
}
}
功能垫片(元素){
var iframe=document.createElement('iframe');
setAttribute('frameborder','0');
setAttribute('scrolling','no');
setAttribute('align','bottom');
setAttribute('marginheight','0');
setAttribute('marginwidth','0');
setAttribute('src','javascript:“”;“”);
var span=document.createElement('span');
span.appendChild(iframe);
//element.parentNode.insertBefore(span,element);//导致无限循环?
element.parentNode.appendChild(span);//此行正常
var els=element.style;
var原始可视性=els.可视性;
变量原始位置=els位置;
var originalDisplay=els.display;
els.visibility=‘隐藏’;
els.position=‘绝对’;
els.display='inline';
变量宽度=element.offsetWidth;
var高度=元素。偏离视线;
els.display=原始显示;
els.位置=原始位置;
els.可见性=原始可见性;
iframe.style.width=(width-6)+“px”;
iframe.style.height=(height-6)+“px”;
}
函数performShim(){
var children=document.getElementsByTagName(“span”);
对于(变量i=0;i
ANodeList
(如document.getElementsByTagName
返回的节点列表)通常是一个活动列表——您对DOM所做的更改也会显示在其中。因此,每次在当前元素之前添加span
,都会将列表扩展一个元素,并将当前元素移动一个元素,下一次迭代会将您放回刚刚完成的节点
你有几个简单的解决办法
- 添加节点时碰撞计数器。(很难看,如果你最终添加了一些东西而不是
,你最终会跳过节点,原因也不清楚。)span
- 将列表复制到一个数组,并在该数组上迭代。您可以使用类似
children=[].slice.call(children,0)代码>(更常见)或
children=Array.apply(窗口,子对象)代码>
- 使用
,它将返回一个非活动的节点列表。(即使它是活动的,在这种情况下,您可以选择document.querySelectorAll
,插入的跨距也不会显示在其中。)'span.shim'
- 向后迭代(从
到0)childrence.length-1
这个问题不是为了找到一个实用的解决方案
那么它就错了。@LightnessRacesinOrbit:你通过一个框架忽略了[…],这是一个非常合理的要求。很抱歉,这个问题是为了更好地理解DOM和与DOM相关的纯javascript函数,没有更好地理解框架如何让您的生活更轻松。我对给出的答案很满意。@Felix:你忽略了我的史诗humour@LightnessRacesinOrbit当前位置也许我的幽默感被这一票的微弱优势蒙蔽了双眼,而这一票似乎与你的评论有关。道歉,不要难过;)+1.下一次迭代将您放回刚刚完成的节点,这是重要的部分。追加是“好的”(在本例中),因为在下一次迭代中,您将处理另一个节点,并且最终您将使用类shim
耗尽span
节点。但是,如果生成的span
s也被分配了shim
类,它也会生成一个无限循环。那么在performShim
中,变量children
是否只是对活动列表的引用?如果是这样的话,为什么附加span
就可以了,而预加就不行了?@user1169578:请看我的评论。关于准备,考虑节点<代码> A,B < /代码>。循环变量是i=0
。现在您正在处理a
并在节点c
前加前缀。结果是c、a、b
。循环变量前进到i=1
,这也是节点a
。。。等等。如果你改为追加,你的列表可能看起来像a、b、c
,一旦你处理c
你就不会再追加任何节点,因为c
没有类shim
。如果你使用。queryselectoral()
你可以按类选择,所以(在这种情况下)返回是否有效并不重要。对于选择所有跨度的现有代码,您可以向后迭代循环。谢谢,我想通过函数(如getElementsByTagName
)检索的集合是一个活动集合,这一点很微妙。我选择将初始集合复制到一个数组,并在该数组上迭代。感谢大家对这一微妙的解释,但我相信