我有这些HTML:
<div class="main_class">
<div class="first_part"><img src="0.gif" /></div>
<span>...</span>
<img src="1.gif" />
<img src="2.gif" />
<img src="3.gif" />
<div class="end_part"></div>
</div>
span和div之间的图像数量是可变的,我试图用锚标记包装它们以得到这样的结果:
<div class="main_class">
<div class="first_part"><img src="0.gif" /></div>
<span>...</span>
<a href="link">
<img src="1.gif" />
<img src="2.gif" />
<img src="3.gif" />
</a>
<div class="end_part"></div>
</div>
我认为这就像获取span并使用outerHTML添加开放式标记一样简单:
mc = document.querySelectorAll(".main_class:not(.modified)");
for (i = 0; i < mc.length; i++) {
mc[i].classList.add('modified');
mc[i].children[1].outerHTML += '<a href="link">';
mc[i].lastElementChild.outerHTML = '</a>' + mc[i].lastElementChild.outerHTML
}
但后来我意识到浏览器太聪明了并自动关闭了标签。是否有一种相对简单的方法可以做到这一点,我不知道?
答案 0 :(得分:2)
请勿使用outerHTML
,但请使用document.createElement
,.appendChild
,.insertBefore
,...等方法:
for (let mc of document.querySelectorAll(".main_class:not(.modified)")) {
mc.classList.add('modified');
let anchor = document.createElement('a');
anchor.href = "link";
for (let child of [...mc.children]) {
if (child.tagName === 'IMG') {
mc.insertBefore(anchor, child);
anchor.appendChild(child);
}
}
console.log(mc.innerHTML);
}
&#13;
<div class="main_class">
<div class="first_part"><img src="0.gif" /></div>
<span>...</span>
<img src="1.gif" />
<img src="2.gif" />
<img src="3.gif" />
<div class="end_part"></div>
</div>
&#13;
注意:如果你想知道为什么有[...mc.children]
而不仅仅是mc.children
:这需要获取子元素的副本,否则在循环体中发生的操作会影响mc.children
的 live 集合并使循环错过某些元素。 T.J。的Array.from
将绕过同样的事情发生。
答案 1 :(得分:2)
你在考虑标记,但DOM(specs,MDN)不是标记,它是一个对象树。从对象的角度思考。创建a
元素,然后通过img
将现有的appendChild
元素移动,然后在div.end_part
元素之前插入它。 (除此之外,这意味着附加到它们的任何事件处理程序保持不受干扰,通过标记的往返将会删除。)
由于您只是想在Chrome上运行此功能,因此您可以愉快地利用forEach
上的NodeList
和箭头功能:
// Find all unhandled .main_class elements
document.querySelectorAll(".main_class:not(.modified)").forEach(mc => {
// Mark we've done this one
mc.classList.add("modified");
// Create our link
const a = document.createElement("a");
a.setAttribute("href", "link"); // You can use `a.href = "link"` if it's okay for the attribute to get a resolved value
// Move the images into it
Array.from(mc.children).filter(child => child.tagName === "IMG").forEach(img => {
a.appendChild(img);
});
// Insert it before the div.end_part
mc.insertBefore(a, mc.querySelector("div.end_part"));
});
实例(我在链接周围添加了一个蓝色边框,并在图像周围添加了红色边框,以便我们可以看到它们的位置):
// Find all unhandled .main_class elements
document.querySelectorAll(".main_class:not(.modified)").forEach(mc => {
// Mark we've done this one
mc.classList.add("modified");
// Create our link
const a = document.createElement("a");
a.setAttribute("href", "link");
// Move the images into it
Array.from(mc.children).filter(child => child.tagName === "IMG").forEach(img => {
a.appendChild(img);
});
// Insert it before the div.end_part
mc.insertBefore(a, mc.querySelector("div.end_part"));
});
a[href=link] {
border: 1px solid blue;
}
img {
border: 1px solid red;
height: 1em;
width: 1em;
}
<div class="main_class">
<div class="first_part"><img src="0.gif" /></div>
<span>...</span>
<img src="1.gif" />
<img src="2.gif" />
<img src="3.gif" />
<div class="end_part"></div>
</div>
<div class="main_class">
<div class="first_part"><img src="0.gif" /></div>
<span>...</span>
<img src="1.gif" />
<img src="2.gif" />
<img src="3.gif" />
<div class="end_part"></div>
</div>
<div class="main_class">
<div class="first_part"><img src="0.gif" /></div>
<span>...</span>
<img src="1.gif" />
<img src="2.gif" />
<img src="3.gif" />
<div class="end_part"></div>
</div>