How to change text except its span - javascript

How can we change the text data from except span text?
<h2 id="nameUser" >Muhammed <span> mobile :989 531 9991</span></h2>
Is there any solution to change h2 except span?

.contents() returns a collection of nodes, including text nodes. So in your case this would work:
$('#nameUser').contents()​​​​​​​​[0].nodeValue = 'Another name';​​
If you want to get every node except the SPAN, try:
$('#nameUser').contents().filter(function() {
return this.nodeName != 'SPAN';
}).​each(function(i) {
// modify each text node
this.nodeValue = 'name '+i;
});​​​​​
DEMO: http://jsfiddle.net/Vks82/

Search for the first textnode in childNodes of the h2 element. Change the value of the textnode.
var element = document.getElementById('nameUser');
element.childNodes[0].nodeValue = 'New String';
..should work. Only for this example, because the first childnode is the textnode you want, you don't have to search for it. Otherwise you do..

This example may help you to change father element without changing child elements:
var content= $('#nameUser').children();
$('#nameUser').text('Altered Text').append(content);​

$('#nameUser').contents().each(function() {
if (this.nodeType == 3)
this.data = "The text you want here";
});​
Live DEMO

You can do it by saving the children first here is a codepen of it working.
http://codepen.io/beckje01/pen/sGLot
var h2 = $('#nameUser');
var elmsToSave = h2.children();
h2.empty();
h2.text('bob');
h2.append(elmsToSave);
As pointed out in the comments this will only work if the text to change is first.

This will work not only for span but also for any other element which you want the text without the text of it's children.
$("#nameUser")
.clone()
.children()
.remove()
.end()
.text();
For change the text I've create a simple jQuery function:
replaceTextWith = function($element, $replacement){
$oldText = $element.clone().children().remove().end().text();
$element.text($element.text().replace($oldText, $replacement));
}
replaceTextWith($("#nameUser"), "Bruno"); //usage
Here's a live example working on fiddle

try this ...
<h2 id="nameUser" >Muhammed <span id="nameUserSpan"> mobile :989 531 9991</span></h2>
<script>
$(document).ready(function() {
var inspan= $("#nameUserSpan").html();
var newuser='New User';
$("#nameUser").html('');
$("#nameUser").html(newuser + '<span id="nameUserSpan">' + inspan + '</span>');
});
</script>

Related

How to Change the Html of an Element before a Child element

Suppose I had the following div:
<div id = "master">
"Random Text
<span id = "unknown">...</span>
</div>
If I didn't know the id of the span, how would I modify the "Random Text" using jQuery?
Note the proposed duplicate's answer is javascript not jQuery.
Use the node type property to find the text node
node type 3 is for the text node.
http://www.w3schools.com/jsref/prop_node_nodetype.asp
You can use the nodeValue property to set the text of a text node element
var textNodeList = $("#master")
.contents()
.filter(function() {
return this.nodeType === 3; //Node.TEXT_NODE
});
textNodeList[0].nodeValue = "Not Random Text";
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id = "master">
"Random Text
<span id = "unknown">...</span>
</div>
jQuery does not have it's own text node methods.
Abstract approach using only jQuery that doesn't require knowing or using native dom methods or properties
$('#master').html(function(){
return $(this).children().clone(true);// only return elements, clone to preserve any possible event handlers
}).prepend('Some new text');
Assumes there is only one text node child of #master
You could do this:
var masterDiv = $('#master');
var text_to_change = masterDiv.childNodes[0];
text_to_change.nodeValue = 'new text';
This should get is working.
Maybe something like this?
$('#unknown')[0].previousSibling.nodeValue = 'something else';
JSFiddle

get content of element after slicing his span

I have the next element:
<div id = "mydiv">
abc
<span>123</span>
</div>
document.getElementById('mydiv').textContent returns me: abc123
I want to get only the text of mydiv ('abc'). so I wonder if there is an option to use jquery in order to get it? maybe get all the content of an element except for span element..
and then getting his text..
p.s. I know I can wrap abc in span and then get it, but I wonder if there is another option to do it without changing my element..
DEMO JSFIDDLE
Try this ,
console.log($("#mydiv").clone() .children().remove().end().text());
You must select yours DIV by ID, then run through its "childrens" property and check their nodeType (textNodes has 3);
var div = document.getElementById("mydiv");
var result = "";
for(var i = 0; i < div.length; i++){
var node = div[i];
if( node.nodeType === 3 ){
result += node.data;
}
}
console.log(result);
Since you've included jQuery you can do this
var p = $('#mydiv').clone();
p.find('span').remove();
console.log(p.text());
DEMO
Using jQuery:
$(document).ready(function() {
alert($('#mydiv span').text());
});
If you expect to have more html elements inside your div, user regular expression to extract plain text after getting whole html content from div.
var re = /<.+>/;
var str = "abc<span>123</span>";
var newstr = str.replace(re, "");
Should give "abc"

Jquery remove the innertext but preserve the html

I have something like this.
<div id="firstDiv">
This is some text
<span id="firstSpan">First span text</span>
<span id="secondSpan">Second span text</span>
</div>
I want to remove 'This is some text' and need the html elements intact.
I tried using something like
$("#firstDiv")
.clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.text("");
But it didn't work.
Is there a way to get (and possibly remove, via something like .text("")) just the free text within a tag, and not the text within its child tags?
Thanks very much.
Filter out text nodes and remove them:
$('#firstDiv').contents().filter(function() {
return this.nodeType===3;
}).remove();
FIDDLE
To also filter on the text itself, you can do:
$('#firstDiv').contents().filter(function() {
return this.nodeType === 3 && this.nodeValue.trim() === 'This is some text';
}).remove();
and to get the text :
var txt = [];
$('#firstDiv').contents().filter(function() {
if ( this.nodeType === 3 ) txt.push(this.nodeValue);
return this.nodeType === 3;
}).remove();
Check out this fiddle
Suppose you have this html
<parent>
<child>i want to keep the child</child>
Some text I want to remove
<child>i want to keep the child</child>
<child>i want to keep the child</child>
</parent>
Then you can remove the parent's inner text like this:
var child = $('parent').children('child');
$('parent').html(child);
Check this fiddle for a solution to your html
var child = $('#firstDiv').children('span');
$('#firstDiv').html(child);
PS: Be aware that any event handlers bounded on that div will be lost as you delete and then recreate the elements
Why try to force jQuery to do it when it's simpler with vanilla JS:
var div = document.getElementById('firstDiv'),
i,
el;
for (i = 0; i< div.childNodes.length; i++) {
el = div.childNodes[i];
if (el.nodeType === 3) {
div.removeChild(el);
}
}
Fiddle here: http://jsfiddle.net/YPKGQ/
Check this out, not sure if it does what you want exactly... Note: i only tested it in chrome
http://jsfiddle.net/LgyJ8/
cleartext($('#firstDiv'));
function cleartext(node) {
var children = $(node).children();
if(children.length > 0) {
var newhtml = "";
children.each(function() {
cleartext($(this));
newhtml += $('<div/>').append(this).html();
});
$(node).html(newhtml);
}
}

jQuery selector for an element that directly contains text?

I was able to get this partially working using the :contains selector, but my problem is if an element contains an element that contains the text it is still returned. For example:
$('div:contains("test")')
Will select both divs below:
<div>something else
<div>test</div>
</div>
fiddle: http://jsfiddle.net/TT7dR/
How can I select only divs that "directly" contain the text? Meaning that in the above example only the child div would be selected.
UPDATE:
Just to clarify, if I were searching for the text "something else" instead of "test" then I would like to only find the parent div.
$('div>:contains("test")') is not a general solution, it only works for your specific example. It still matches any element whose descendants contain the text test, as long as its parent is a div.
There is in fact currently no selector that will select only direct parents of text nodes containing your target text. To do it you would have to walk the DOM tree yourself checking each text node you find for the target text, or write a plugin to do the same. It'd be slow, but then not as slow as :contains already is (it's not a standard CSS selector so you don't get browser-native fast selector support).
Here's a plain DOM function you could use as a starting point. It might be improved to find text in adjacent (non-normalised) text nodes, or to hide it in a plugin/selector-extension.
function findElementsDirectlyContainingText(ancestor, text) {
var elements= [];
walk(ancestor);
return elements;
function walk(element) {
var n= element.childNodes.length;
for (var i= 0; i<n; i++) {
var child= element.childNodes[i];
if (child.nodeType===3 && child.data.indexOf(text)!==-1) {
elements.push(element);
break;
}
}
for (var i= 0; i<n; i++) {
var child= element.childNodes[i];
if (child.nodeType===1)
walk(child);
}
}
}
Just to complete the knowledge base. If you need to get all DOM elements within the body (not only DIVs) that contain specific text or characters you can use:
function getNodesThatContain(text) {
var textNodes = $(document).find(":not(iframe, script)")
.contents().filter(
function() {
return this.nodeType == 3
&& this.textContent.indexOf(text) > -1;
});
return textNodes.parent();
};
console.log(getNodesThatContain("test"));
Hope that helps.
jsfiddle: http://jsfiddle.net/85qEh/2/
Credits: DMoses
You might have to do an in-efficient query. Do not use this solution if someone finds a selector that manages to filter out child elements: http://viralpatel.net/blogs/2011/02/jquery-get-text-element-without-child-element.html
$("div:contains('test')")
.clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.filter(":contains('test')")
edit: that snippet above is just to test the element, in implementation it would look more like this: http://jsfiddle.net/rkw79/TT7dR/6/
$("div:contains('test')").filter(function() {
return (
$(this).clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.filter(":contains('test')").length > 0)
}).css('border', 'solid 1px black');
try adding the greater than:
$('div>:contains("test")')
Finds specific element, but not parents
var elementsContainingText = ($(':contains("' + text + '")', target)).filter(function() {
return $(this).contents().filter(function() {return this.nodeType === 3 && this.nodeValue.indexOf(text) !== -1; }).length > 0;
});
This seems to work for me:
$('div >:contains("test")');
http://jsfiddle.net/TT7dR/1/
This forces the matched :contains selector to be a direct child of the <div> element
Try the following:
$("div>div:contains(test):only-of-type")
Add more alternative:
if($(selector).text().trim().length) {
var thetext = $(selector).contents().filter(function(){
return this.nodeType === 3;
}).text().trim();
console.log(thetext);
}
It will select the text only and remove any element with tag!
Reference
You can simply select the element that doesn't have your element
$('div:contains("test"):not(:has(> div))')
less code to write (but with a little limitation):
let selector = $('div:contains("test")');
selector.not(selector.has('div:contains("test")'))
Just use the jQuery function (.has) because the css :has is experimental:
https://developer.mozilla.org/en-US/docs/Web/CSS/:has#Browser_compatibility
Limitation:
When you have a structure like this:
<div>
<div>test</div>
test
</div>
Then only the inner div - Element will be found by this solution. This is because there is still an Element - Child of the div that :contains the string "test".

Replace text with HTML element

How can I replace a specific text with HTML objects?
example:
var text = "some text to replace here.... text text text";
var element = $('<img src="image">').event().something...
function ReplaceWithObject(textSource, textToReplace, objectToReplace);
So I want to get this:
"some text to replace < img src...etc >.... text text text"
And I would like manipulate the object element without call again $() method.
UPDATE:
I solved.
thanx #kasdega, i made a new script based in your script, because in your script i can't modify the "element" after replace.
This is the script:
$(document).ready(function() {
var text = "some text to replace here.... text text text";
var element = $('<img />');
text = text.split('here');
$('.result').append(text[0],element,text[1]);
$(element).attr('src','http://bit.ly/mtUXZZ');
$(element).width(100);
});
I didnt know that append method accept multiples elements.
That is the idea, only need to automate for multiple replacements
thanx to all, and here the jsfiddle
do a split on the text you want to replace then use the array indexes 0 and 1...something like:
function ReplaceWithObject(textSource, textToReplace, objectToReplace) {
var strings = textSource.split(textToReplace);
if(strings.length >= 2) {
return strings[0] + objectToReplace.outerHTML() + strings[1];
}
return "";
}
UPDATE: I found another SO post Get selected element's outer HTML that pointed me to a tiny jquery plugin that helps here.
I believe this jsfiddle has what you want. outerHTML is the tiny jquery plugin I included in the JSFiddle.
You can also use replace which will reduce some code: http://jsfiddle.net/kasdega/MxRma/1/
function ReplaceWithObject(textSource, textToReplace, objectToReplace) {
return textSource.replace(textToReplace, objectToReplace.outerHTML());
}
function textToObj (text,obj,$src){
var className = "placeholder-"+text;
$src.html($src.html().replace(text,"<div class='"+className+"'></div>"));
$("."+className).replace(obj);
}
you can use $(selector).outerHtml to get the html string of an element
You can replace the html directly: http://jsfiddle.net/rkw79/qNFKF/
$(selector).html(function(i,o) {
return o.replace('old_html','new_html');
})

Categories

Resources