2009-12-02 20 views

risposta

15

In primo luogo, hai bisogno di un modo per accedere al paragrafo. Si potrebbe voler dare un attributo id, come ad esempio "pippo":

<p id="foo">Lorem Ipsum <a href="#">Link</a> <div ... </div> </p> 

Quindi, è possibile utilizzare document.getElementById per accedere a tale elemento e sostituire i suoi figli come richiesto:

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); 

Per rendere più più affidabile, è possibile chiamare p.normalize() prima di accedere al primo figlio, per garantire che tutti i nodi di testo prima dell'ancoraggio vengano uniti come uno.


Oook, Così si vuole sostituire una parte di un nodo di testo con un elemento. Ecco come lo farei:

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); 

Lavorare con i nodi al livello basso è un po 'una brutta situazione di essere in; soprattutto senza alcuna astrazione per aiutarti. Ho cercato di mantenere un senso di normalità creando un nodo DOM da una stringa HTML prodotta dalla frase "Lorem Ipsum" sostituita. I puristi probabilmente non amano questa soluzione, ma la trovo perfettamente adatta.


EDIT: Ora utilizzando un frammento di documento! Grazie Crescent Fresh!

+0

Ma, ma ... dove si trova la * ricerca * (e si sposta nel punto corrispondente all'interno di 'firstTextNode') per" Lorem Ipsum "? –

+0

Ah, ho trascurato questo, lavorando ora. – James

+0

@ J-P: il mio upvote attende la modifica !! –

0

Combinare questi 2 tutorial:

PPK on JavaScript: The DOM - Part 3

Adding elements to the DOM

In sostanza è necessario per accedere al valore del nodo, rimuoverlo, e creare un nuovo elemento figlio che è il valore del nodo è il valore della nodo dell'articolo genitore, quindi aggiungere l'elemento (in questo caso spazia) al genitore (paragrafo in questo caso)

0

Come utilizzare un espressione regolare in javascript e sostituire "Lorem Ipsum" con '<arco> Lorem Ipsum </span >' (ricordate solo che si dovrà ottenere il 'innerHTML' dell'elemento e quindi sostituire l'intero lotto di nuovo che può essere un po 'lento)

+3

E cloberà tutti i gestori di eventi associati (se presenti). –

+0

il problema è che il testo non è ony due parole, è un testo più lungo. anche il testo apparirà in posti diversi con diversi contenuti di testo. quindi la ricerca di un nodo di testo specifico non funzionerà qui: -/ – patad

0

UPDATE: Il metodo seguito sarà la ricerca nella sottostruttura guidato da container e avvolgere tutte le istanze di text in un elemento arco. Le parole possono comparire ovunque all'interno di un nodo di testo e il nodo di testo può trovarsi in qualsiasi posizione nella sottostruttura.

(OK, quindi ci sono voluti più piccoli aggiustamenti.: 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's 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's 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; 
    } 
} 
+0

grazie per quello. il problema è che il testo non è lorem ipsum, è un lungo testo. il testo può anche apparire in luoghi diversi con contenuti diversi. quindi la ricerca di un nodo di testo specifico non funzionerà qui: -/ – patad

+0

Quindi è necessario eseguire la scansione di una porzione (o di tutti?) Dell'albero DOM e avvolgere ogni istanza di una stringa di testo con una span? Questo dovrebbe essere possibile con un po 'di riprogettazione. Modificherò la mia funzione per farlo. – Annabelle

+0

Ho aggiornato la mia risposta. Ora esegue la scansione attraverso una sottostruttura DOM esaminando qualsiasi nodo di testo che trova per il testo specificato. – Annabelle

Problemi correlati