为什么我不能<li>用javascript将一系列的包装在一个标签中?



我知道如何用jQuery做到这一点,但我想学习它与香草javascript,我有一种感觉,它会更快。这里有一个jsFiddle的链接,其中包含了我要做的事情的简化版本。http://jsfiddle.net/yramagicman/MyM2B/和下面是违规的脚本。

<script>
var id = 'ul';
var tag = 'li';
var wrapTag = 'span';
var wrapper = document.createElement(wrapTag);
var z = document.getElementById(id);
var y = z.getElementsByTagName(tag);
var count = y.length;
for (var i = 0; i < count; i++) {
    y[i].setAttribute("class", "red"); //so I can see the result
    wrapper.appendChild(y[i].cloneNode(true));
    y[i].parentNode.replaceChild(wrapper, y[i]);
    wrapper.setAttribute('class', 'hi'); //so I can see the result
}</script>
<!-- and the html-->
<ul id="ul" class="ul">
    <li class="li">1</li>
    <li class="li">2</li>
    <li class="li">3</li>
    <li class="li">4</li>
    <li class="li">5</li>
    <li class="li">6</li>
    <li class="li">7</li>
    <li class="li">8</li>
</ul>

我可以包装整个Ul在一个div或span或任何只是好的,但当我试图包装每个列表项目,我得到错误"HIERARCHY_REQUEST_ERR: DOM异常3:一个节点被插入到某个地方它不属于。"什么好主意吗?

flem的答案不正确。尽管在任何版本的HTML中,<li>元素作为<span>元素的子元素都是无效的,但对于DOM来说,这应该不是一个问题,事实上也不是。

有两个关键的信息你需要理解。首先,getElementsByTagName返回的节点列表是附加到DOM文档的活动列表。如果JS循环改变了DOM文档,那么列表就会被更新。

第二种情况是,您只创建了一次包装器元素,但每次在循环中都与replaceChild一起使用它。

所以第一次循环一切正常。第二次循环时,克隆元素被添加到包装器中,包装器现在位于DOM文档中,因此成为y节点列表中的第二个元素。

所以y[i]不再是源<li>,而是克隆元素,因此y[i].parentNode是包装元素。

这意味着在replacecchild行中,您的代码试图使包装器元素成为其自身的子元素。这是不可能的,因此HIERARCHY_REQUEST_ERR

您正在构建一个无效的DOM。<li>必须属于<ul><ol>,但您试图将其放在<span>中。因此错误:"一个节点被插入到它不属于的地方"

最新更新