我有一个HTML字符串。我想选择所有的跨度元素,并删除跨度具有相同的id,只让其中一个留在字符串。span元素之间的文本不应该被删除。
具有相同id的span都在彼此后面。剩下的一个应该包含所有删除的文本。
例句:输入:
<p>
Hi,<span id="1">this is just a simple text and we</span>
<span id="1">want to save me because i had a lot of</span>
<span id="1">pressure on and i want to live a better life. 😭</span>
I researched a lot about it but i could't find anything helpful
<span id="2">just another rant. 😭</span>
</p>
输出:<p>
Hi,
<span id="1">
this is just a simple text and we want to save me because i had a lot of
pressure on and i want to live a better life 😭
</span>
I researched a lot about it but i could't find anything helpful
<span id="2">just another rant. 😭</span>
</p>
一个简短的解决方案
一个简短的解决方案是选择所有具有id的span,并使用Array.reduce()将具有相同id的span的内容连接起来。
[...document.querySelectorAll("span[id]")].reduce((last,span) => {
if (span.id === last.id) {
last.innerHTML += ' n' + span.innerHTML;
span.remove();
return last;
}
return span;
}, {});
before.value = document.querySelector('p').innerHTML;
[...document.querySelectorAll("span[id]")].reduce((last,span) => {
if (span.id === last.id) {
last.innerHTML += ' n' + span.innerHTML;
span.remove();
return last;
}
return span;
}, {});
after.value = document.querySelector('p').innerHTML;
body {
font-family: sans-serif;
font-size: 10px;
}
textarea {
width: 100%;
height: 7rem;
font-size: 10px;
}
p {
display: none;
}
<p>
Hi,<span id="1">this is just a simple and we</span>
<span id="1">want to save me for becuase i had a lot of</span>
<span id="1">presure on and i want to live a betteer life. 😭</span>
I researched a lot about it but i could't find anything helpful
<span id="2">just another rant. 😭</span>
<span id="3">Hello World</span>
<span id="3">Duplicate World</span>
<span>A span without an ID</span>
</p>
Before:
<textarea id="before"></textarea>
After:
<textarea id="after"></textarea>
虽然id
是唯一的,但您仍然可以在不切换到使用class
的情况下获得结果。(如果可以切换到使用class,那么就这样做。)
下面的代码查找重复id的第一个实例,复制文本内容,然后删除元素。这样重复,直到没有多余的。然后添加一个新元素,并用先前存储的文本内容填充。
let e = []
while (i = document.getElementById("one")) {
e.push(i.textContent);
i.parentNode.removeChild(i)
}
let x = document.createElement("div")
x.setAttribute("id", "one")
x.innerHTML = e.join("<br>")
document.body.appendChild(x)
<div id="one">One</div>
<div id="one">Two</div>
<div id="one">Three</div>
我希望我正确理解了你想要达到的目的。
因为不能有多个具有相同id的元素。在例2中,我将ID替换为一个类。
算法接受代码中所有的span元素。然后滚动收集到的表格中的所有元素并获取它们的内容。删除给定类的所有元素,除了第一个!在第一个元素中,放置收集到的信息。
我希望我对你有所帮助
ID:的示例在这个例子中,我使用jQuery
let list = [...$('span')];
let tempText = '';
list.forEach((el, i) => {
let currElID = el.getAttribute('id');
let nextElID = null;
if (list[i + 1]) {
nextElID = list[i + 1].getAttribute('id');
} else {
nextElID = null;
};
tempText += el.innerText;
if (currElID !== nextElID) {
let listByClass = [...$(`[id=${currElID}]`)];
if (listByClass.length > 0) {
listByClass.forEach((element, index) => {
if (index > 0) {
element.remove();
}
});
};
listByClass[0].innerText = tempText;
tempText = '';
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<p>
Hi,
<span id="1">this is just a simple and we</span>
<span id="1">want to save me for becuase i had a lot of</span>
<span id="1">presure on and i want to live a betteer life. 😭</span>
I researched a lot about it but i could't find anything helpful
<span id="2">just another rant. 😭</span>
</p>
示例与CLASS:
let list = document.querySelectorAll('span');
let tempText = '';
list.forEach((el, i) => {
let currElClass = el.getAttribute('class');
let nextElClass = null;
if (list[i + 1]) {
nextElClass = list[i + 1].getAttribute('class');
} else {
nextElClass = null;
};
tempText += el.innerText;
if (currElClass !== nextElClass) {
let listByClass = [...document.getElementsByClassName(currElClass)];
if (listByClass.length > 0) {
listByClass.forEach((element, index) => {
if (index > 0) {
element.remove();
}
});
};
listByClass[0].innerText = tempText;
tempText = '';
};
});
<p>
Hi,
<span class="1">this is just a simple and we</span>
<span class="1">want to save me for becuase i had a lot of</span>
<span class="1">presure on and i want to live a betteer life. 😭</span>
I researched a lot about it but i could't find anything helpful
<span class="2">just another rant. 😭</span>
</p>
首先,查找所有span id set:
let spans = document.querySelectorAll("span[id]");
对于每个span:
for (let span of spans)
如果给定span的下一个元素是另一个span且具有相同的id:
(nextElement && nextElement.nodeName === "SPAN" && span.id === nextElement.id)
然后将span之间的所有节点移动到第一个span:
let nextNode = span.nextSibling;
while(nextNode !== nextElement) {
span.append(nextNode);
nextNode = span.nextSibling;
}
以及第二个span:
中的所有节点span.append(...nextElement.childNodes);
删除第二个span:
nextElement.remove();
,然后对新的兄弟节点继续相同的过程:
nextElement = span.nextElementSibling;
由于没有必要处理已经删除的span 和重复的id ,因此跳过它们:
if (!span.parentNode) {
continue;
}
最后,应该释放跨NodeList以避免内存泄漏:
spans = null;
通常情况下,出于性能原因,所有DOM操作都应该批处理(移动到代码的最后并一次完成所有操作),但这会使代码变得有点复杂,因此我没有将其包含在下面的代码片段中,以使代码更容易理解。
let spans = document.querySelectorAll("span[id]");
for (let span of spans) {
if (!span.parentNode) {
continue;
}
let nextElement = span.nextElementSibling;
while (nextElement && nextElement.nodeName === "SPAN" && span.id === nextElement.id) {
let nextNode = span.nextSibling;
while (nextNode !== nextElement) {
span.append(nextNode);
nextNode = span.nextSibling;
}
span.append(...nextElement.childNodes);
nextElement.remove();
nextElement = span.nextElementSibling;
}
}
spans = null;
<p>
Hi,<span id="1">this is just a simple and we</span>
<span id="1">want to save me for becuase i had a lot of</span>
<span id="1">presure on and i want to live a betteer life. 😭</span> I researched a lot about it but i could't find anything helpful
<span id="2">just another rant. 😭</span>
</p>