I only want to display the first four characters of a div, but it seems to be more difficult than needed and google isn't very helpful. Different variations of this don't seem to work:
$("#div").html(this.html().substring(0,4));
I really want to avoid having an extra variable in there that stores the text first.
Use a callback for the .html(),
$('#div').html(function(i, currentHtml) {
return currentHtml.substring(0, 4);
});
Demo
You can also use .text() in this case if the div consists only of plain text.
$("#div").text(function(i, currentText) {
return currentText.substring(0, 4);
});
Refer :
Slice vs Substring
Turns out substring is relatively faster.
JsPerf test : slice() vs substring() vs others
If the div elements contains any HTML (html elements) then .html() return the it's as a string. Example
Note: (It's completely depend on the inner content of you div)
If you want to truncate the plain text, you should use .text() instead of using .html()
Try this:
$("#div").text(function(){
return $(this).text().substring(0,4);
});
Working Fiddle
Try this :
$("#div").html(function(){
return $(this).html().substring(0,4)
});
It will count space also...If any there.
Like DIV have "test four 3" will give you output "test"
Use slice() for this purpose :
$("#div").text(function(){
return $(this).text().slice(0,4);
});
Related
I have a span with a text inside it like :
<span class="characters-count">(160 Characters Left)</span>
given the span a class in this case .characters-count , when i tried class selector using jQuery to get the text inside span :
$(".characters-count")[0].text();
it returns undefined !
However this selector works well :
$("span.characters-count").text();
anyone can explain what is happening ?
$("span.characters-count").text();
In our case you work with jQuery Object that has text method
$(".characters-count")[0].text();
In this case you work with actual DOM element (like document.getElementByClassName('characters-count')[0]) that does not have text method
Use
$(".characters-count").text();
Demo
console.log($(".characters-count:first").text())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="characters-count">(160 Characters Left)</span>
try something like this:
$(".characters-count:first").text()
Check here, why it was not working for you.
//This will return dom element, so it doesn't have `text()` method, that's why it was throwing error for you.
console.log($(".characters-count:first")[0]);
// This will return object of an element, you can use jQuery selectors to get first element from collection and set text to it
console.log($("span.characters-count"));
console.log($("span.characters-count:first").text
);
you need to use innerText instead of text() when you use $(".characters-count")[0] check DEMO
$(".characters-count")[0].innerText
<p>some string here xxx</p>
I want to remove the xxx characters
so I do $(p:contains('xxx')).remove(); but it removed the entire <p></p>, how to only get rid of the targeted character?
That would be the text method and a string replace
$('p').text(function(_, txt) {
return txt.replace('xxx', '');
});
remove removes entire elements, not parts of text.
That is the expected behavior of remove(), it removes whole elements . You can use text(fn) or html(fn) to do it.
$("p:contains('xxx')").text(function(idx, oldText){
return oldText.replace('xxx','');
});
If you also have other tags within the p use html(fn) as above
I have this HTML:
<p>
(rcvd)
Title
by Person,
<br></br>
- More text
</p>
And I want to change the color of (rcvd) to green. I tried the following:
This changes the entire line to green but keeps the link
$("p:contains('(rcvd)')").attr("style","color:green");
This changes the rcvd part to green but removes the Title link
$("p").each(function() {
var text = $(this).text();
text = text.replace("(rcvd)", "<span style='color:green;'>(rcvd)</span>");
$(this).html(text);
});
This does nothing, but I think it's the solution I want with a small tweak somewhere that I'm missing
$(p).html($(p).html().replace("(rcvd)","<span style='color:green;'>(rcvd)</span>"));
Any pointers welcome (I am still new to JQuery and trying to learn so I'd love an explanation as to why you make the suggestion you make.
My own suggestion would be:
$('p').html(function(i,h){
return h.replace('(rcvd)', '<span class="greenColoured">(rcvd)</span>');
});
Using CSS to supply the style:
.greenColoured {
color: green;
}
JS Fiddle demo.
As noted by TrueBlueAussie (in comments, below), I've not explained the parameters in the anonymous function passed to the html() method: the function(i, h):
The html() method essentially iterates over the collection returned by the selector (in this case over all the paragraphs selected); without use of the anonymous function each p element would have the same HTML set. Using the function, with the i and v (which can be named however you please allows you to access the index (i) of the currently iterated-over element amongst the collection, and v (the second parameter) returns the current 'value' (in this case the existing innerHTML of the current node being iterated over).
As noted, these parameters can be called anything you like, for me i and h are habitual (i for 'index' and h for HTML in this case); so long as you remember that (as with many other anonymous functions passed to jQuery methods) the first is the index and the second the 'current-value'.
References:
html().
String.replace().
This will select the first node within the P (which happens to be a text node) and style it:
$("p").contents().first().wrap("<span style='color:green'></span>");
Demo: http://jsfiddle.net/jrAWn/
UPDATED. Ok, and this is using class:
.rStyle {
color:green;
}
$("p").contents().first().wrap("<span/>").parent().addClass("rStyle");
Use css() and give your <p> tag a class:
<p id="myGreenClass">(rcvd)</p>
And this jQuery code:
$('.myGreenClass').css('color', 'green');
Try wrapping the tag names in quotes (jsFiddle):
$("p").html($("p").html().replace("(rcvd)","<span style='color:green;'>(rcvd)</span>"));
At the moment you are passing the variable p to the jQuery function. Presumable p is undefined, so you either get a Javascript error or just an empty jQuery object.
As others have said, the standard way to do this is wrapping the rvcd in a span:
<p>
<span class="style-this">(rcvd)</span>
Title
by Person,
<br></br>
- More text
</p>
And
$(".style-this").css("color", "green");
I am using latest Jquery and the following script:
<script type="text/javascript">
$(document).ready(function(){
var el = $('.title');
el.html(el.html().replace(/\./gi, " "));
});
</script>
This is the div:
<div class="title">The.quick.brown.fox</div>
What it does is replaces all dots with spaces in a DIV with class "title" and really it works fine for this job.
But I have many DIVs with the same "title" class with different strings in them and i need them all to have dots replaced with spaces. But here the problem appears as all what i get is the same result string on all these DIVs "The quick brown fox" while all result strings should be different as all source strings are different...
What do i do to get dots replaced in all DIVs with class "title" and all different strings in each DIV?
Thanks
You can use each() to iterate over the matched elements, or pass a function to html() and compute the new text there:
$(document).ready(function() {
$(".title").html(function(index, currentHtml) {
return currentHtml.replace(/\./gi, " ");
});
});
Just use jQuery each method to iterate over all elements with class .title:
$(document).ready(function(){
$('.title').each(function(){
$(this).html($(this).html().replace(/\./gi, " "));
});
});
As long as you have only text inside your divs, suggested functions will work just fine. However, to allow arbitrary html (like The.quick.brown <img src='fox.jpg'>) the code should be more accurate.
$('.title').each(function() {
if (this.nodeType == 3)
this.nodeValue = this.nodeValue.replace(/\./g, " ");
else
$(this).contents().each(arguments.callee);
});
Basically, you recursively iterate over all descendants of a node and replace only nodes of type 3 (=text).
Fiddle: http://jsfiddle.net/jZgUY/
I have a div set up something like this:
<div id="test"> <p>Hello</p> <p style="display: none">Goodbye</p> </div>
EDIT: To clarify, this is the simplest example. The div could have any arbitrary number of n deep nested children.
$('#test').getText() returns 'Hello Goodbye'. Here's a one liner to test in Firebug: jQuery('<div id="test"> <p>Hello</p> <p style="display: none">Goodbye</p> </div>').text()
This seems to be because what jQuery uses internally, textContent (for non IE), returns hidden elements as part of the text. Hrmph.
Is there a way to return the text content ignoring display:none'd elements? Basically I am trying to mimic the text you would get from highlighting the div with your mouse and copying to system clipboard. That ignores hidden text.
Interestingly, if you create a selection range and get the text from it, that also returns text inside display:none elements.
var range = document.body.createTextRange();
range.moveToElementText($('#test')[0]);
range.select();
console.log(range.toString()); // Also logs Hello Goodbye!
So creating a document selection range doesn't appear to do the same thing as highlighting with the mouse in terms of display:none elements. How do I get around this dirty pickle conundrum?
Edit: using .filter(':visible').text has been suggested, but it won't work for this scenario. I need the returned text to be EXACTLY what would come from a selection with the mouse. So for example:
$('<div>test1 <p>test2</p>\r\n <b>test3</b> <span style="display:none">none</span></div>').appendTo(document.body).children().filter(':visible').text()
returns
"test2test3"
When the output I actually want is
test1 test2
test3
linebreaks, whitespace and all, which come from the \r\n
Filter the elements using .filter(":visible").
Or use this:
$("#test :visible").text();
But the jQuery documentation advises us to use .filter() instead:
Because :visible is a jQuery extension and not part of the CSS specification,
queries using :visible cannot take advantage of the performance boost provided by the native DOM querySelectorAll() method. To achieve the best performance when using :visible to select elements, first select the elements using a pure CSS selector, then use .filter(":visible").
Use :visible in your selector as such:
$("#test > p:visible").text()
A Function example:
-- Edit:
http://jsfiddle.net/8H5ka/ ( Works on Chrome it displays "Hello" in Result )
If the above doesn't work:
http://jsfiddle.net/userdude/8H5ka/1/
If space isn't a major concern you could copy the markup, remove the hidden elements, and output that text.
var x = $('#test').clone();
x.filter(':not(:visible)').remove();
return x.text();
I had this problem and found this question, and it seems the actual solution is based on the provided answers but not actually written out. So here's a complete solution that worked for my situation, which is the same as the OP with the additional provision that elements may be invisible due to external styles based on DOM position. Example:
<style>.invisible-children span { display: none; }</style>
<div class="invisible-children">
<div id="test">Hello <span>Goodbye</span></div>
</div>
The solution is to:
Make a clone of the entire object.
Remove invisible objects in place; if we take #test out of the DOM before we remove invisible objects, jQuery might not know they're invisible because they will no longer match the CSS rules.
Get the text of the object.
Replace the original object with the clone we made.
The code:
var $test = $('#test');
// 1:
var $testclone = $test.clone();
// 2: We assume that $test is :visible and only remove children that are not.
$test.find('*').not(':visible').remove();
// 3:
var text = $test.text();
// 4:
$test.replaceWith($testclone);
// Now return the text...
return text;
// ...or if you're going to keep going and using the $test variable, make sure
// to replace it so whatever you do with it affects the object now in DOM and
// not the original from which we got the text after removing stuff.
$test = $testclone;
$test.css('background', 'grey'); // For example.
Here is how I did it with MooTools:
$extend(Selectors.Pseudo, {
invisible: function() {
if(this.getStyle('visibility') == 'hidden' || this.getStyle('display') == 'none') {
return this;
}
}
});
Element.implement({
getTextLikeTheBrowserWould = function() {
var temp = this.clone();
temp.getElements(':invisible').destroy();
return temp.get('text').replace(/ |&/g, ' ');
}
})
I search for that and found this question but without solution.
Solution for me is just get out of jquery to use DOM:
var $test = $('#test').get(0).innerText
or if more than on element in array of selector, you need a for loop and a merge but I guess that most of time it is the first version that you need.
var $test = $('#test').get().map(a => a.innerText).join(' ');