“jQuery way” to replace just a text node with a mi

2019-05-06 16:08发布

问题:

In my web browser userscript project I need to replace just one text node without affecting the other HTML elements under the same parent node as the text. And I need to replace it with more than one node:

<div id="target"> foo / bar; baz<img src="/image.png"></div>

Needs to become:

<div id="target"> <a href="#">foo</a> / <a href="#">bar</a>; <a href="#">baz</a><img src="/image.png"></div>

I know jQuery doesn't have a whole lot of support for text nodes. I know I could use direct DOM calls instead of jQuery. And I know I could just do something like $('#target').html(my new stuff + stuff I don't want to change). Also note that I'd like to preserve the initial space, this on its own seems to be tricky.

What I'd like to ask the experts here is, Is there a most idiomatic jQuery way to do this?

回答1:

You basically want to replace the first child (text node) with the new content. You need http://api.jquery.com/replaceWith/

// Text node we want to process and remove
var textNode = $("#target").contents().first();
// Break the text node up
var parts = textNode.text().split(/\s/);
// Put links around them
var replaceWith = "";
for (var i =0; i < parts.length;i++) {
    replaceWith += "<a href='http://www.google.com'>"  + parts[i] + "</a> ";
}
// Replace the text node with the HTML we created
textNode.replaceWith(replaceWith);

http://jsfiddle.net/NGYTB/1/



回答2:

Try this approach

// nodeType = 1 corresponds to element node
   // You are filtering everything out other than that and 
   // removing the textnodes from it..
   // contents() will get everything including the text
    ​$('#target'​).contents().filter(function() {
        return this.nodeType != 1; 
    }).remove();

   // Then you are prepending the div with the html  that needs to 
   //  replaced with the text...
    $('#target').prepend('<a href="#">mixed</a> text <a href="#">and</a> HTML');
   // This makes sure you do not touch the initial img element inside the div

You can add other node types if you do not want to remove specific nodetypes CHECK FIDDLE​



回答3:

try this..edited version

$('#target').html('<a href="#">mixed</a> text <a href="#">and</a> HTML' + $('#target').html());