по этой ссылке я опубликовал похожий вопрос, но теперь мне нужно улучшить функцию, которую я хочу. Пожалуйста, прочитайте, чтобы понять: Как разбить каждое слово на (html) с учетом других элементов внутри
. Первое решение для пользователя великолепно и хорошо работает, если я рассматриваю только теги <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);
}
}
Спасибо за помощь!