2009-12-02 13 views

Respuesta

15

En primer lugar, necesitas alguna forma de acceder al párrafo. Es posible que desee darle un atributo id, tales como "foo":

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

A continuación, puede utilizar document.getElementById acceder a ese elemento y reemplazar sus hijos según sea necesario:

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

Para que sea más confiable, es posible que desee llamar al p.normalize() antes de acceder al primer hijo, para asegurarse de que todos los nodos de texto antes del delimitador se fusionen como uno solo.


Oook, por lo que desea reemplazar una parte de un nodo de texto con un elemento. Así es como yo lo haría:

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

Trabajar con nodos en el nivel bajo es un poco de una situación desagradable para estar en; especialmente sin ninguna abstracción para ayudarte. Intenté mantener la sensación de normalidad creando un nodo DOM a partir de una cadena HTML producida a partir de la frase reemplazada "Lorem Ipsum". Los puristas probablemente no les gusta esta solución, pero la encuentro perfectamente adecuada.


EDITAR: Ahora, utilizando un fragmento de documento! Gracias Crescent Fresh!

+0

Pero, pero ... ¿dónde está la * búsqueda * (y mover al punto coincidente dentro de 'firstTextNode') para" Lorem Ipsum "? –

+0

Ah, lo pasé por alto, trabajando en eso ahora. – James

+0

@ J-P: mi upvote espera su edición !! –

0

La combinación de estos 2 tutoriales:

PPK on JavaScript: The DOM - Part 3

Adding elements to the DOM

Básicamente se necesitan para acceder al valor del nodo, y eliminar, y crear un nuevo elemento secundario que es el valor de nodo es el valor de la nodo principal del elemento, luego anexe ese elemento (span en este caso) al elemento principal (párrafo en este caso)

0

¿Qué le parece usar una expresión regular en javascript y reemplazar "Lorem Ipsum" con '<lapso> Lorem ipsum </span >' (recuerde que usted tendrá que obtener la 'innerHTML' del elemento y luego vuelva a colocar la totalidad del lote nuevo que puede ser un poco lento)

+3

Y tropezará con todos los controladores de eventos enlazados (si los hubiera). –

+0

el problema es que el texto no está en dos palabras, es un texto más largo. también el texto aparecerá en diferentes lugares con diferente contenido de texto. así que buscar un nodo de texto específico no funcionará aquí: -/ – patad

0

ACTUALIZACIÓN: El método a continuación una búsqueda en el subárbol encabezada por container y envolver todas las instancias de text en un elemento span. Las palabras pueden aparecer en cualquier lugar dentro de un nodo de texto, y el nodo de texto puede aparecer en cualquier posición en el subárbol.

(OK, por lo que tomó más de unos pocos ajustes menores).: 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

gracias por eso. el problema es que el texto no es lorem ipsum, es un texto largo. el texto también puede aparecer en diferentes lugares con diferente contenido. así que buscar un nodo de texto específico no funcionará aquí: -/ – patad

+0

Entonces, ¿necesita rastrear una parte (o todas?) Del árbol DOM y ajustar cada instancia de una cadena de texto con un lapso? Eso debería ser posible con un poco de rediseño. Editaré mi función para hacer esto. – Annabelle

+0

Actualicé mi respuesta. Ahora rastrea a través de un subárbol DOM que examina cualquier nodo de texto que encuentre para el texto especificado. – Annabelle

Cuestiones relacionadas