Как сделать раунд вокруг раздела текста без использования jQuery
<p>Lorem Ipsum <a href="#">Link</a> <div ... </div> </p>
Я хочу поместить span вокруг "Lorem Ipsum" без использования jQuery, поэтому результат выглядит так:
<p><span>Lorem Ipsum </span><a href="#">Link</a> <div ... </div> </p>
Любые идеи? Благодаря
Ответы
Ответ 1
Сначала вам нужен какой-то способ доступа к абзацу. Вы можете указать атрибут id
, например "foo":
<p id="foo">Lorem Ipsum <a href="#">Link</a> <div ... </div> </p>
Затем вы можете использовать document.getElementById
для доступа к этому элементу и при необходимости заменить его дочерние элементы:
var p = document.getElementById('foo'),
firstTextNode = p.firstChild,
newSpan = document.createElement('span');
// Append "Lorem Ipsum" text to new span:
newSpan.appendChild( document.createTextNode(firstTextNode.nodeValue) );
// Replace old text node with new span:
p.replaceChild( newSpan, firstTextNode );
Чтобы сделать его более надежным, вы можете вызвать p.normalize()
перед доступом к первому ребенку, чтобы все текстовые узлы перед якорем были объединены как один.
Oook, поэтому вы хотите заменить часть текста node на элемент. Вот как я это сделаю:
function giveMeDOM(html) {
var div = document.createElement('div'),
frag = document.createDocumentFragment();
div.innerHTML = html;
while (div.firstChild) {
frag.appendChild( div.firstChild );
}
return frag;
}
var p = document.getElementById('foo'),
firstChild = p.firstChild;
// Merge adjacent text nodes:
p.normalize();
// Get new DOM structure:
var newStructure = giveMeDOM( firstChild.nodeValue.replace(/Lorem Ipsum/i, '<span>$&</span>') );
// Replace first child with new DOM structure:
p.replaceChild( newStructure, firstChild );
Работа с узлами на низком уровне - это немного неприятная ситуация; особенно без какой-либо абстракции, чтобы помочь вам. Я попытался сохранить чувство нормальности, создав DOM node из строки HTML, созданной из замещенной фразы "Lorem Ipsum". Пуристам, вероятно, не нравится это решение, но я считаю его вполне подходящим.
EDIT: теперь используйте фрагмент документа! Спасибо Полумесяц свежий!
Ответ 2
Объедините эти 2 руководства:
PPK на JavaScript: DOM - часть 3
Добавление элементов в DOM
В принципе вам нужно получить доступ к значению node, удалить его и создать новый дочерний элемент, значение node - это значение родительского элемента node, а затем добавить этот элемент (span в этом случае) в родительский (абзац в этом случае)
Ответ 3
Как насчет использования регулярного выражения в javascript и замены "Lorem Ipsum" на "<span> Lorem Ipsum </span> " (просто помните, что вам нужно будет получить "innerHTML" элемента, а затем снова заменить всю партию, которая может быть немного медленной)
Ответ 4
UPDATE:
Нижеприведенный метод будет искать в поддереве, возглавляемом container
, и обернуть все экземпляры text
в элементе span. Слова могут встречаться в любом месте текста node, а текст node может возникать в любой позиции в поддереве.
(ОК, поэтому потребовалось больше нескольких мелких настроек: P)
function wrapText(container, text) {
// Construct a regular expression that matches text at the start or end of a string or surrounded by non-word characters.
// Escape any special regex characters in text.
var textRE = new RegExp('(^|\\W)' + text.replace(/[\\^$*+.?[\]{}()|]/, '\\$&') + '($|\\W)', 'm');
var nodeText;
var nodeStack = [];
// Remove empty text nodes and combine adjacent text nodes.
container.normalize();
// Iterate through the container child elements, looking for text nodes.
var curNode = container.firstChild;
while (curNode != null) {
if (curNode.nodeType == Node.TEXT_NODE) {
// Get node text in a cross-browser compatible fashion.
if (typeof curNode.textContent == 'string')
nodeText = curNode.textContent;
else
nodeText = curNode.innerText;
// Use a regular expression to check if this text node contains the target text.
var match = textRE.exec(nodeText);
if (match != null) {
// Create a document fragment to hold the new nodes.
var fragment = document.createDocumentFragment();
// Create a new text node for any preceding text.
if (match.index > 0)
fragment.appendChild(document.createTextNode(match.input.substr(0, match.index)));
// Create the wrapper span and add the matched text to it.
var spanNode = document.createElement('span');
spanNode.appendChild(document.createTextNode(match[0]));
fragment.appendChild(spanNode);
// Create a new text node for any following text.
if (match.index + match[0].length < match.input.length)
fragment.appendChild(document.createTextNode(match.input.substr(match.index + match[0].length)));
// Replace the existing text node with the fragment.
curNode.parentNode.replaceChild(fragment, curNode);
curNode = spanNode;
}
} else if (curNode.nodeType == Node.ELEMENT_NODE && curNode.firstChild != null) {
nodeStack.push(curNode);
curNode = curNode.firstChild;
// Skip the normal node advancement code.
continue;
}
// If there no more siblings at this level, pop back up the stack until we find one.
while (curNode != null && curNode.nextSibling == null)
curNode = nodeStack.pop();
// If curNode is null, that means we've completed our scan of the DOM tree.
// If not, we need to advance to the next sibling.
if (curNode != null)
curNode = curNode.nextSibling;
}
}