【发布时间】:2019-09-30 13:49:56
【问题描述】:
在这个链接上我已经发布了一个类似的问题,但现在我必须改进我想要的功能。
请阅读了解:How to split each word in <p> (html) considering other elements inside。
如果我只考虑<p> 标签,用户的第一个解决方案非常好并且效果很好,但现在我必须考虑网页中可能存在的所有以下标签:span, p, h1, h2, h3, h4, h5, h6, em, strong, q, abbr, acronym, address, li, dd, dt, a, td, th, caption, legend, label, option。
我总是将标签内的每个单词分开并在其周围放置一个<span> 标签(es:<h2> ...<span> word </span>...</h2>,但现在有一个复杂的问题:
一些标签可以单独存在,也可以在其他标签内部(例如标签<a> 可以在<p> 标签的外部或内部,上面列表中的许多其他标签具有相同的用途)。以这种方式提出的解决方案不是最佳的,因为在同一个词周围插入两个不同的<span> 标签,一个是由于<p> 而一个是由于代码运行时<a>。
我用一个更复杂的例子和不同的标签元素来解释它:
发明了部分html页面:
<a> Text of lorem ipum </a>
<h2> Lorem <span>ipsum</span> dolor <em>sit</em> amet, <a>consectetur</a> adipiscing <strong>elit</strong> </h2>
建议的解决方案是:
标签内没有任何人,工作正常
<a>
<span>Text<span>
<span>of<span>
<span>lorem<span>
<span>ipum<span>
</a>
标记里面有人,效果不好
<h2>
<span><span><span> Lorem </span></span></span> //3times
<span(original)><span><span><span> ipsum </span></span></span></span(original)> //3times + original one
<span><span><span> dolor </span></span></span> //3times
<em><span><span><span> sit </span></span></span></em> //3times
<span><span><span> amet </span></span></span> //3times
<a><span><span><span><span> consectetur </span></span></span></span></a> //4times
<span><span><span>adipiscing</span></span></span> //3times
<strong><span><span><span>elit</span></span></span></strong> //3times
</h2>
它以递归方式工作,因此它会为遇到的不同标签创建不同的标签, 但我想要达到的结果是:
<a>
<span>Text<span>
<span>of<span>
<span>lorem<span>
<span>ipum<span>
</a>
<h2>
<span>Lorem</span>
<span(original)><span>ipsum</span></span(original)>
<span>dolor</span>
<em><span>sit</span></em>
<span>amet</span>
<a><span>consectetur</span></a>
<span>adipiscing</span>
<strong><span>elit</span></strong>
</h2>
我不知道如何编辑下面的代码以避免在递归期间或在它已经存在的情况下复制<span>。
到目前为止使用的解决方案代码(改进):
const span = document.createElement('span');
span.className = 'foo';
span.appendChild(document.createTextNode(''));
for (const p of document.getElementsByTagName('p')) { //I've tried to change in document.querySelectorAll('p,h1,h2,h3,h4,h5,h6,em,strong,q,abbr,acronym,address,li,dd,dt,a,td,th,caption,legend,label,option')
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT);
const textNodes = [];
for (let n; (n = walker.nextNode());) {
if (n.nodeValue.trim()) {
textNodes.push(n);
}
}
for (const n of textNodes) {
const fragment = document.createDocumentFragment();
for (const s of n.nodeValue.split(/(\s+)/)) {
if (s.trim()) {
span.firstChild.nodeValue = s;
fragment.appendChild(span.cloneNode(true));
} else {
fragment.appendChild(document.createTextNode(s));
}
}
n.parentNode.replaceChild(fragment, n);
}
}
谢谢你帮助我!
【问题讨论】:
标签: javascript jquery html google-chrome-extension popup