Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/443.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将一系列元素包装到另一个元素中的最干净方法_Javascript_Html - Fatal编程技术网

Javascript 将一系列元素包装到另一个元素中的最干净方法

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

我有一些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
}
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
)。