Javascript 将一系列元素包装到另一个元素中的最干净方法
我有一些HTML:Javascript 将一系列元素包装到另一个元素中的最干净方法,javascript,html,Javascript,Html,我有一些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 cl
<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
}
mc=document.queryselectoral(.main_类:not(.modified)”;
对于(i=0;i
但后来我意识到浏览器太聪明了,自动关闭标签。有没有一种我不知道的相对简单的方法可以做到这一点?不要使用
outerHTML
,而是使用类似document.createElement
,.appendChild
,,.insertBefore
,…:
for(让mc的document.queryselectoral(“.main\u class:not(.modified)”){
mc.classList.add('modified');
让anchor=document.createElement('a');
anchor.href=“link”;
为了(让[…mc.儿童的孩子]){
如果(child.tagName=='IMG'){
mc.insertBefore(主播、孩子);
主播:儿童(child);
}
}
log(mc.innerHTML);
}
...
您考虑的是标记,但DOM(,)不是标记,而是对象树。从对象的角度思考。创建一个a
元素,然后通过appendChild
将现有的img
元素移动到其中,然后将其插入div.end\u部分
元素之前。(除其他外,这意味着附加到它们的任何事件处理程序都保持不受干扰,而通过标记的往返过程将删除这些事件处理程序。)
由于您只需在Chrome上运行此功能,您可以很高兴地利用NodeList上的forEach
和箭头功能:
// 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"));
});
实时示例(我在链接周围添加了蓝色边框,在图像周围添加了红色边框,以便我们可以看到它们的位置):
//查找所有未处理的.main\u类元素
document.querySelectorAll(“.main\u class:not(.modified)”).forEach(mc=>{
//马克,我们已经做过了
mc.classList.add(“修改”);
//创建我们的链接
常量a=document.createElement(“a”);
a、 setAttribute(“href”,“link”);
//将图像移入其中
Array.from(mc.children).filter(child=>child.tagName==“IMG”).forEach(IMG=>{
a、 儿童(img);
});
//将其插入div.end\u零件之前
mc.insertBefore(一个mc.querySelector(“div.end_部分”);
});代码>
a[href=link]{
边框:1px纯蓝色;
}
img{
边框:1px纯红;
高度:1米;
宽度:1米;
}
...
...
...
为什么要不断地移动锚?(我真的需要习惯于接触for of
..:-)@T.J.Crowder,只需要移动一次锚,但我很懒,不想依赖.end\u part
或图像的存在。如果没有图像,则不会发生任何更改。定位点的插入点完全由找到的最后一个图像的位置决定。很公平。:-)实际上,解析器将知道它们的存在,因此将从外部范围屏蔽具有相同名称的其他变量,但如果在声明之前引用它们,则会引发错误。这就是你的意思吗,@T.J.Crowder?哇,你们真快。我继续尝试自己解决问题,最后终于解决了问题,现在我看到了另外两种解决方案(我的解决方案和trincot的类似,但我不熟悉,让)很高兴你解决了问题!:-)关于let
:,但trincot使用它的位置可能更合适(因为mc
的值在循环体中从未更改)。你是对的,我是用标记的方式思考的。这正是我所熟悉的。我已经很长时间没有深入研究Javascript了,所以我对所有“新的”DOM内容都不太熟悉。另外,我完全被你的剧本迷住了,等我有几分钟的时间,我将不得不对它进行详细的分析。谢谢你的回复@塞克斯:不用担心!上面的几个相关链接:(querySelectorAll
返回的不是数组,但在现代浏览器上,它也有forEach
)。