通过DOM中的前置元素实现无限循环

infinite-loop via prepend element in DOM(通过DOM中的前置元素实现无限循环)
本文介绍了通过DOM中的前置元素实现无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不寻找使用框架XXX答案

这个问题不是为了通过框架找到实际的解决方案。回答使用框架XXX,或者这在框架XXX中很容易,或者为什么不使用这个框架XXX??不能回答问题。

我有一个在页面加载后运行的函数:performShim。此函数迭代DOM中作为span标记的所有元素,检查它们是否具有classNameshim,如果有,则调用shim向其传递匹配元素的引用。

我的目标是span前面添加另一个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]);  
        }
    }
} 

推荐答案

ANodeList(如document.getElementsByTagName返回的那个)通常是一个实时列表--您对DOM所做的更改也会显示在其中。因此,每次在当前元素之前添加span时,您就是将列表扩展了一个元素,并将当前元素移动了一个元素,而下一次迭代会将您带回到刚刚完成的节点。

您有几个简单的解决方法来解决这个问题...

  • 添加节点时撞到计数器。(丑陋的,如果您最终添加的是某项内容而不是span,您将最终跳过节点,原因将不明显。)

  • 将列表复制到数组并迭代该数组。您可以使用
    children = [].slice.call(children, 0);(更常见)或
    children = Array.apply(window, children);

  • 使用document.querySelectorAll,这将返回一个非活动的NodeList。(即使它是实时的,在这种情况下,您也可以选择'span.shim',插入的跨度无论如何都不会显示在其中。)

    /li>
  • 向后迭代(从children.length - 1到0)。

这篇关于通过DOM中的前置元素实现无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Update another component when Formik form changes(当Formik表单更改时更新另一个组件)
Formik validation isSubmitting / isValidating not getting set to true(Formik验证正在提交/isValiating未设置为True)
React Validation Max Range Using Formik(使用Formik的Reaction验证最大范围)
Validation using Yup to check string or number length(使用YUP检查字符串或数字长度的验证)
Updating initialValues prop on Formik Form does not update input value(更新Formik表单上的初始值属性不会更新输入值)
password validation with yup and formik(使用YUP和Formick进行密码验证)