How to change text inside a range using jQuery, leaving the remaining intervals with content in it?

I have the following HTML snippet:

<span class="target">Change me <a class="changeme" href="#">now</a></span> 

I would like to change the text of the node (i.e. “Change me”) within the range from jQuery, leaving the nested <a> tag with all attributes, etc. intact. My initial huch was to use .text(...) on the span node, but as it exits , it will replace the entire inside with the passed text content.

I solved this by first cloning the <a> tag, and then installing the new <span> text content (which will remove the original <a> tag) and finally adding the cloned <a> tag to my <span> . It works, but feels overkill for a simple task like this. Btw. I can not guarantee that inside the span there will be the initial text node - it may be empty, like:

 <span class="target"><a class="changeme" href="#">now</a></span> 

I did jsfiddle . So what would be a neat way to do this?

+4
source share
8 answers

Try something like:

 $('a.changeme').on('click', function() { $(this).closest('.target').contents().not(this).eq(0).replaceWith('Do it again '); }); 

demo: http://jsfiddle.net/eEMGz/

ref: http://api.jquery.com/contents/

Update

I assume that I did not read your question correctly, and you are trying to replace the text if it already exists, and enter it differently. To do this, try:

 $('a.changeme').on('click', function() { var $tmp = $(this).closest('.target').contents().not(this).eq(0), dia = document.createTextNode('Do it again '); $tmp.length > 0 ? $tmp.replaceWith(dia) : $(dia).insertBefore(this); }); 

Demo: http://jsfiddle.net/eEMGz/3/

+6
source

You can use .contents() :

 //set the new text to replace the old text var newText = 'New Text'; //bind `click` event handler to the `.changeme` elements $('.changeme').on('click', function () { //iterate over the nodes in this `<span>` element $.each($(this).parent().contents(), function () { //if the type of this node is undefined then it a text node and we want to replace it if (typeof this.tagName == 'undefined') { //to replace the node we can use `.replaceWith()` $(this).replaceWith(newText); } }); });​ 

Here is a demo: http://jsfiddle.net/jasper/PURHA/1/

Some docs for ya:

Update

 var newText = 'New Text'; $('a').on('click', function () { $.each($(this).parent().contents(), function () { if (typeof this.tagName == 'undefined') { //instead of replacing this node with the replacement string, just replace it with a blank string $(this).replaceWith(''); } }); //then add the replacement string to the `<span>` element regardless of it initial state $(this).parent().prepend(newText); });​ 

Demo: http://jsfiddle.net/jasper/PURHA/2/

+1
source

You can try this.

 var $textNode, $parent; $('.changeme').on('click', function(){ $parent = $(this).parent(); $textNode= $parent.contents().filter(function() { return this.nodeType == 3; }); if($textNode.length){ $textNode.replaceWith('Content changed') } else{ $parent.prepend('New content'); } }); 

Working demo - http://jsfiddle.net/ShankarSangoli/yx5Ju/8/

+1
source

You exit jQuery because it does not help you process text nodes. The following will remove the first child from each <span> with the class "target" if and only if it exists and is the text node.

Demo: http://jsfiddle.net/yx5Ju/11/

the code:

 $('span.target').each(function() { var firstChild = this.firstChild; if (firstChild && firstChild.nodeType == 3) { firstChild.data = "Do it again"; } }); 
+1
source

This is not a perfect example, I think, but you could use contents .

 console.log($("span.target").contents()[0].data); 
0
source

You can wrap text in a range ... but ...

try it. http://jsfiddle.net/Y8tMk/

 $(function(){ var txt = ''; $('.target').contents().each(function(){ if(this.nodeType==3){ this.textContent = 'done '; } }); }); 
0
source

You can change your own (not jquery) property of the object data. Updated jsfiddle here: http://jsfiddle.net/elgreg/yx5Ju/2/

Sort of:

 $('a.changeme3').click(function(){ $('span.target3').contents().get(0).data = 'Do it again'; }); 

The content () gets the insides, and get (0) returns us to the original element, and .data is now a reference to the js native text index. (I have not tested this cross browser.)

This jsfiddle and answer is actually just an extended explanation of the answer to this question: Change text of text nodes

0
source
 $('a.changeme').click(function() { var firstNode= $(this).parent().contents()[0]; if( firstNode.nodeType==3){ firstNode.nodeValue='New text'; } }) 

EDIT: do not know what layout rules you need, update to test only the first node, otherwise adapt if necessary

0
source

Source: https://habr.com/ru/post/1398868/


All Articles