删除具有相同id的span元素,只保留一个



我有一个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>

最新更新