for example we have this file
<div id="mydiv">
some text here
<div id="inner div">
text for inner div
</div>
</div>
i need to get #mydiv text only with some code like this :
alert($('#mydiv').text()); // will alert "some text here"
hey try this please": http://jsfiddle.net/MtVxx/2/
Good link for your specific case in here: http://viralpatel.net/blogs/jquery-get-text-element-without-child-element/ (This will only get the text of the element)
Hope this helps, :)
code
jQuery.fn.justtext = function() {
return $(this).clone()
.children()
.remove()
.end()
.text();
};
alert($('#mydiv').justtext());
The currently accepted answer is pretty horrible in terms of performance, so I felt obligated to write a more lightweight one:
$.fn.mytext = function() {
var str = '';
this.contents().each(function() {
if (this.nodeType == 3) {
str += this.textContent || this.innerText || '';
}
});
return str;
};
console.log($('#mydiv').mytext());
Like Ja͢ck's answer but no need for iterating explicitly (via .each()) and collecting textContents:
$('#mydiv').contents().filter(function(){return this.nodeType === 3}).text()
OR, if you can use arrow functions:
$('#mydiv').contents().filter((i, el) => el.nodeType === 3).text()
Related
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);
}
}
Say a web page has a string such as "I am a simple string" that I want to find. How would I go about this using JQuery?
jQuery has the contains method. Here's a snippet for you:
<script type="text/javascript">
$(function() {
var foundin = $('*:contains("I am a simple string")');
});
</script>
The selector above selects any element that contains the target string. The foundin will be a jQuery object that contains any matched element. See the API information at: https://api.jquery.com/contains-selector/
One thing to note with the '*' wildcard is that you'll get all elements, including your html an body elements, which you probably don't want. That's why most of the examples at jQuery and other places use $('div:contains("I am a simple string")')
Normally jQuery selectors do not search within the "text nodes" in the DOM. However if you use the .contents() function, text nodes will be included, then you can use the nodeType property to filter only the text nodes, and the nodeValue property to search the text string.
$('*', 'body')
.andSelf()
.contents()
.filter(function(){
return this.nodeType === 3;
})
.filter(function(){
// Only match when contains 'simple string' anywhere in the text
return this.nodeValue.indexOf('simple string') != -1;
})
.each(function(){
// Do something with this.nodeValue
});
This will select just the leaf elements that contain "I am a simple string".
$('*:contains("I am a simple string")').each(function(){
if($(this).children().length < 1)
$(this).css("border","solid 2px red") });
Paste the following into the address bar to test it.
javascript: $('*:contains("I am a simple string")').each(function(){ if($(this).children().length < 1) $(this).css("border","solid 2px red") }); return false;
If you want to grab just "I am a simple string". First wrap the text in an element like so.
$('*:contains("I am a simple string")').each(function(){
if($(this).children().length < 1)
$(this).html(
$(this).text().replace(
/"I am a simple string"/
,'<span containsStringImLookingFor="true">"I am a simple string"</span>'
)
)
});
and then do this.
$('*[containsStringImLookingFor]').css("border","solid 2px red");
If you just want the node closest to the text you're searching for, you could use this:
$('*:contains("my text"):last');
This will even work if your HTML looks like this:
<p> blah blah <strong>my <em>text</em></strong></p>
Using the above selector will find the <strong> tag, since that's the last tag which contains that entire string.
Take a look at highlight (jQuery plugin).
Just adding to Tony Miller's answer as this got me 90% towards what I was looking for but still didn't work. Adding .length > 0; to the end of his code got my script working.
$(function() {
var foundin = $('*:contains("I am a simple string")').length > 0;
});
this function should work. basically does a recursive lookup till we get a distinct list of leaf nodes.
function distinctNodes(search, element) {
var d, e, ef;
e = [];
ef = [];
if (element) {
d = $(":contains(\""+ search + "\"):not(script)", element);
}
else {
d = $(":contains(\""+ search + "\"):not(script)");
}
if (d.length == 1) {
e.push(d[0]);
}
else {
d.each(function () {
var i, r = distinctNodes(search, this);
if (r.length === 0) {
e.push(this);
}
else {
for (i = 0; i < r.length; ++i) {
e.push(r[i]);
}
}
});
}
$.each(e, function () {
for (var i = 0; i < ef.length; ++i) {
if (this === ef[i]) return;
}
ef.push(this);
});
return ef;
}
How can I change text-nodes text?
HTML:
<p class='theClass'> bbb <a href=#> foo</a> aaa </p>
I'm trying to change 'aaa' and 'bbb' to hello world. I successed to select those nodes but couldn't change their text.
Jquery so far:
var $textNodes = $('.theClass').contents().filter(function() {
return this.nodeType == Node.TEXT_NODE;
});
JSFiddle
What can I do with this $textNodes to change their text?
Use the nodeValue or data property of the text node. Both are equally valid and well supported:
$textNodes.each(function() {
this.data = "CHANGED";
});
Incidentally, Node.TEXT_NODE does not exist in IE < 9, so you'd be better off simply using 3 instead.
You can't directly edit a text node with jQuery.
Just use the native data or nodeValue property directly on the nodes.
$textNodes.each(function() {
this.data = "Hello world";
// this.nodeValue = "Hello world";
});
jsFiddle
Found it after a lot of time in MDN:
This propery is called nodeValue not value for some stupid reason...
fixed JQuery:
var $textNodes = $('.theClass').contents().filter(function() {
return this.nodeType == Node.TEXT_NODE;
}).each(function(){
this.nodeValue = "hello World";
});
Fixed JSFiddle
How to select a part of string?
My code (or example):
<div>some text</div>
$(function(){
$('div').each(function(){
$(this).text($(this).html().replace(/text/, '<span style="color: none">$1<\/span>'));
});
});
I tried this method, but in this case is selected all context too:
$(function(){
$('div:contains("text")').css('color','red');
});
I try to get like this:
<div><span style="color: red">text</span></div>
$('div').each(function () {
$(this).html(function (i, v) {
return v.replace(/foo/g, '<span style="color: red">$&<\/span>');
});
});
What are you actually trying to do? What you're doing at the moment is taking the HTML of each matching DIV, wrapping a span around the word "text" if it appears (literally the word "text") and then setting that as the text of the element (and so you'll see the HTML markup on the page).
If you really want to do something with the actual word "text", you probably meant to use html rather than text in your first function call:
$('div').each(function(){
$(this).html($(this).html().replace(/text/, '<span style="color: none">$1<\/span>'));
// ^-- here
}
But if you're trying to wrap a span around the text of the div, you can use wrap to do that:
$('div').wrap('<span style="color: none"/>');
Like this: http://jsbin.com/ucopo3 (in that example, I've used "color: blue" rather than "color: none", but you get the idea).
$(function(){
$('div:contains("text")').each(function() {
$(this).html($(this).html().replace(/(text)/g, '<span style="color:red;">\$1</span>'));
});
});
I've updated your fiddle: http://jsfiddle.net/nMzTw/15/
The general practice of interacting with the DOM as strings of HTML using innerHTML has many serious drawbacks:
Event handlers are removed or replaced
Opens the possibility of script inject attacks
Doesn't work in XHTML
It also encourages lazy thinking. In this particular instance, you're matching against the string "text" within the HTML with the assumption that any occurrence of the string must be within a text node. This is patently not a valid assumption: the string could appear in a title or alt attribute, for example.
Use DOM methods instead. This will get round all the problems. The following will use only DOM methods to surround every match for regex in every text node that is a descendant of a <div> element:
$(function() {
var regex = /text/;
function getTextNodes(node) {
if (node.nodeType == 3) {
return [node];
} else {
var textNodes = [];
for (var n = node.firstChild; n; n = n.nextSibling) {
textNodes = textNodes.concat(getTextNodes(n));
}
return textNodes;
}
}
$('div').each(function() {
$.each(getTextNodes(this), function() {
var textNode = this, parent = this.parentNode;
var result, span, matchedTextNode, matchLength;
while ( textNode && (result = regex.exec(textNode.data)) ) {
matchedTextNode = textNode.splitText(result.index);
matchLength = result[0].length;
textNode = (matchedTextNode.length > matchLength) ?
matchedTextNode.splitText(matchLength) : null;
span = document.createElement("span");
span.style.color = "red";
span.appendChild(matchedTextNode);
parent.insertBefore(span, textNode);
}
});
});
});
I have some text below called (16 Courses). I need to hide only this text, but I can't seem to hide it no matter what I try using jquery. Is there any help someone could provide so I can hide on this text?
<div id="programAttributes">
<div class="left" id="credits">
<h3>Credits</h3>
<h3 class="cost">48</h3>
(16 Courses)
</div>
<div class="gutter12 left"> </div>
<div class="left" id="costPer">
<h3>Cost Per Credit</h3>
<h3 class="cost">$300</h3>
</div>
</div>
I thought if I could write something like this that would do the trick, but I am so far unsuccessful.
$("#credits:not([class!=h3])").hide();
Usage
// hides in the whole document
hideText("(16 Courses)");
// only hide inside a specific element
hideText("(16 Courses)", $('#programAttributes'));
// make it visible again
showText("(16 Courses)");
[See it in action]
CSS
.hiddenText { display:none; }
Javascript
// escape by Colin Snover
RegExp.escape = function(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}
function hideText(term, base) {
base = base || document.body;
var re = new RegExp("(" + RegExp.escape(term) + ")", "gi");
var replacement = "<span class='hiddenText'>" + term + "</span>";
$("*", base).contents().each( function(i, el) {
if (el.nodeType === 3) {
var data = el.data || el.textContent || el.innerText;
if (data = data.replace(re, replacement)) {
var wrapper = $("<span>").html(data);
$(el).before(wrapper.contents()).remove();
}
}
});
}
function showText(term, base) {
var text = document.createTextNode(term);
$('span.hiddenText', base).each(function () {
this.parentNode.replaceChild(text.cloneNode(false), this);
});
}
You can check for and remove textnodes like this:
$("#credits").contents().filter(function() {
if(this.nodeType == 3)
this.parentNode.removeChild(this);
});
You can test it here, this gets all the nodes (including text nodes) with .contents(), then we loop through, if it's a text node (.nodeType == 3) then we remove it.
Could you wrap it in a separate span, and then do:
$('#credits span').hide();
?
Try wrapping the text in a span as follows:
<div class="left" id="credits">
<h3>Credits</h3>
<h3 class="cost">48</h3>
<span id="toHide">(16 Courses)</span>
</div>
then you can use jquery:
$("#credits > span)").hide();
the hide() function has to be applied to a DOM element.
I would use a label tag around the text so I can handle it with jquery.
It's textnode. Loop thru all parents nodes and if it's type is textnode, hide it. See also this:
How do I select text nodes with jQuery?