This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Remove elements with only a space using jQuery
I have an automatically generated HTML feed that is filled with garbage... I am trying to clean it up a bit and would like to use jquery to strip out some of the bad code. So for example on an average page buried in the code there are close to 200x:
<div align="center"> </div>
If there was some sort of id or class element, these would be easy to get rid of. But I can't think of a way to find them without anything actually in them. Can I search by attribute? Or better yet is there a way to find by HTML code...
If you are trying to simply remove all empty DIV elements, or DIV's with only a single space, then you could do this:
$('div').map(function() {
if( $(this).html().length <= 0 || $(this).html() == " ")
{
return this;
}
}).remove();
This iterates through all of the div's on your page and if they match a certain criteria (they are empty or only have a whitespace) then it removes them from the DOM.
This should give you a starting point. If you wanted to only check the DIV's with an align property of "center" then you would do this:
$('div:[align="center"]').map(function() {
if( $(this).html().length <= 0 || $(this).html() == " ")
{
return this;
}
}).remove();
jQuery's map() function can be great when a simple filter, or attribute comparison will not suffice.
You can read more about it here.... http://api.jquery.com/map/
There is a jQuery attribute selector
For your example:
jQuery( "div [align='center']" )
Related
This question already has answers here:
Advantages of createElement over innerHTML?
(5 answers)
Closed 6 years ago.
I'm making divs with several sub elements something like this:
<div class="item" data-id="28">
<div class="action-btns">
<button class="add"></button>
<button class="rmv"></button>
</div>
<div class="info">
<h3>Title here</h3>
<span>caption here</span>
</div>
</div>
And im giving functions to those two buttons on click. I'm wondering which method of creating these items is better - createElement or innerHTML?
As far as createElement goes i like it because i can bind the onclick while creating the button inside the element and then append it. Also im wondering if appending this "item" to the parent div is faster / better than updating innerHTML += "something";
As far as innerHTML goes there are fewer lines of code to write, but also i have to either write the onclick="myFunction()" inside the buttons instead of adding it dynamically.
Please no jQuery or anyting but pure Js. Thanks for your time :)
https://jsperf.com/innerhtml-vs-createelement-test (Note i did not write this)
Results in chrome is about 60% ish percent slower using createElement. As per (#Sagar V and #Hajji Tarik) answer consider more then just speed.
There are several advantages to using createElement instead of modifying innerHTML (as opposed to just throwing away what's already there and replacing it) besides safety, like Pekka already mentioned:
Preserves existing references to DOM elements when appending elements
When you append to (or otherwise modify) innerHTML, all the DOM nodes inside that element have to be re-parsed and recreated. If you saved any references to nodes, they will be essentially useless, because they aren't the ones that show up anymore.
Preserves event handlers attached to any DOM elements
This is really just a special case (although common) of the last one. Setting innerHTML will not automatically reattach event handlers to the new elements it creates, so you would have to keep track of them yourself and add them manually. Event delegation can eliminate this problem in some cases.
Could be simpler/faster in some cases
If you are doing lots of additions, you definitely don't want to keep resetting innerHTML because, although faster for simple changes, repeatedly re-parsing and creating elements would be slower. The way to get around that is to build up the HTML in a string and set innerHTML once when you are done. Depending on the situation, the string manipulation could be slower than just creating elements and appending them.
Additionally, the string manipulation code may be more complicated (especially if you want it to be safe).
Here's a function I use sometimes that make it more convenient to use createElement.
function isArray(a) {
return Object.prototype.toString.call(a) === "[object Array]";
}
function make(desc) {
if (!isArray(desc)) {
return make.call(this, Array.prototype.slice.call(arguments));
}
var name = desc[0];
var attributes = desc[1];
var el = document.createElement(name);
var start = 1;
if (typeof attributes === "object" && attributes !== null && !isArray(attributes)) {
for (var attr in attributes) {
el[attr] = attributes[attr];
}
start = 2;
}
for (var i = start; i < desc.length; i++) {
if (isArray(desc[i])) {
el.appendChild(make(desc[i]));
}
else {
el.appendChild(document.createTextNode(desc[i]));
}
}
return el;
}
If you call it like this:
make(["p", "Here is a ", ["a", { href:"http://www.google.com/" }, "link"], "."]);
you get the equivalent of this HTML:
<p>Here is a link.</p>
The answer of #Matthew Crumley
innerHTML just put the plain text. Whereas createElement creates the element object and adds to Parent.
since browser convert tags in plain text to HTML element, it is converted to tags. It is not recommended.
createElement is the recommended method
I'm trying to do something seemingly simple but it's turning out more difficult than I thought.
I have on a page 4 span elements (that I have no control over) all with the same class ID (BOfSxb) and I need to edit only two of them - the second and the 4th element. So I'm not sure how to select only those two and before I do that, I need to know the contents of the 2nd or the 4th span element (2 and 4 have identical content). I figured out how to get the contents but I'm getting both combined so if the content is 2,304,400 I'm getting back 2,304,4002,304,400
here's how I was able to get the content so far:
var spanContent = $("span.BOfSxb:contains(2,304,400)").text()
console.log(spanContent); //returns 2,304,4002,304,400 ( I need 2,304,400)
The other problem with the above is :contains has a number I won't know ahead of time.
After I get the content off the second or 4th span, I need to compare it and see what range it falls under and do something else with it. Something like:
if ($(".BOfSxb:contains("+ spanContent + ")").text() >= 0 && $(".BOfSxb:contains("+ spanContent + ")").text() <= 1000) {
$("span.BOfSxb:contains("+ spanContent + ")").replaceWith(finalDiv);
} else if ($(".BOfSxb:contains("+ spanContent + ")").text() >= 1001 && $(".BOfSxb:contains("+ spanContent + ")").text() <= 1000000) {
$("span.BOfSxb:contains("+ spanContent + ")").replaceWith(finalDiv2);
} else {
//something else
}
EDIT: I should add this is actually a Chrome extension that will be doing the editing of the span elements on a page I have no control over.
Thank you for any help!
You can specify the element to grab by using it's index number in relation to it's class. You can do this with the jquery .eq() method.
$(".span.BOfSxb").eq(1).text();
$(".span.BOfSxb").eq(3).text();
You can then use the parseInt(); method to change them into numbers and add them if you wish. The parseInt() method returns an integer from a string. When you get the text from the elements they are not able to be added together because they are not considered numbers, they are considered text strings.
Here's the fiddle: http://jsfiddle.net/atw5z0ch/
If I understood your question, this should work:
HTML:
<span class="span">1234</span>
<span class="span">Other content 1</span>
<span class="span">1234</span>
<span class="span">Other content 2</span>
JavaScript (using jQuery):
var content = '1234';
// Notice:
// (i) content is a string. You should use quotes if you
// directly write the value, as specified here: https://api.jquery.com/contains-selector/
// (ii) Using classes to select objects with jQuery will return an array of elements
var spans = $('.span:contains(' + content + ')');
spans.each(function(i){
var value = parseInt($(this).text());
if(value > 0 && value < 1000){
console.log(value);
}
});
Working JsFiddle: http://jsfiddle.net/3tbag1qs/2/
UPDATE: as #zfrisch suggests, you can also get the spans by their positions. The solution presented here is another way to solve your problem, if you are not sure of the exact order.
You can use :nth-of-type selector. It probably wont work in older browsers though.
https://css-tricks.com/almanac/selectors/n/nth-of-type/
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Use jQuery to change an HTML tag?
I have searched around for a while but haven't found an answer that quite matches what I am trying to do. I would like to be able to replace part of an html tag without actually replacing everything. For example my HTML...
Test
I would like the end result to be something like this...
<test href="">Test</a>
I have tried this... but it just replaces everything...
$("a").replaceWith("<test");
This doesn't seem to work either...
$("a").find().html("<a").replaceWith("<test");
EDIT:
I don't think I was very clear with my first part. My end goal is to only replace just part of the tag... For example..
find <a and replace it with <test
........
I feel like I am heading down the right path but I am not sure where to go from here. Any help is much appreciated. Thanks.
God only knows why you would change your elements into something that is'nt even close to being valid HTML, but here's how to do it:
(function($) {
$.fn.changeElementType = function(newType) {
var attrs = {};
$.each(this[0].attributes, function(idx, attr) {
attrs[attr.nodeName] = attr.nodeValue;
});
this.replaceWith(function() {
return $("<" + newType + "/>", attrs).append($(this).contents());
});
};
})(jQuery);
$("a").changeElementType('test');
FIDDLE
(Stolen from Andrew Whitakers answer here on SO)
Here's how to do it with .unwrap() and .wrap()
$('a') // select the element
.contents() // traverse to contents
.unwrap() // unwrap - remove parent tag - which happens to be the a
.wrap('<test href="">') // wrap contents with test tag
http://jsfiddle.net/wirey00/mVWfp/
This question already has answers here:
How can I change an element's text without changing its child elements?
(16 answers)
Closed 1 year ago.
I have next html:
<label for="user_name">
<abbr title="required">*</abbr>
Name
</label>
And I want to change label caption to Title with jquery. So I do
$('label[for=user_name]').html('Title')
And it replaces all inner html (including abbr tag)
So, what's the easiest way to replace only Name?
If you use contents() method it will also return text nodes. Since jQuery doesn't have text node methods, convert last node to a DOM node
$('label[for="user_name"]').contents().last()[0].textContent='Title';
Demo: http://jsfiddle.net/yPAST/1/
Sorry for the late reply... But here is a way to do so using only jQuery:
$('label').contents().last().replaceWith('Title');
It may not be the prettiest way, but this works:
var $label = $('label[for=user_name]');
$label.html($label.html().replace("Name", "Title"));
You can select only the abbr element, store it, and then replace the whole content with the stored element plus the changed caption:
$('label[for="user_name"]').each(function(){
var a = $(this).children('abbr');
$(this).html(a).append('Title');
});
See this fiddle
you can use replace accomplish this
var html = $('label[for=user_name]').html().replace('Name','Testing');
$('label[for=user_name]').html(html);
check it : http://jsfiddle.net/DyzMJ/
Evans solution added to jquery fn to make it's use comfortable:
// get/change node content not children
jQuery.fn.content = function( n ){
var o = $(this).clone();
var c = o.children().remove();
if (typeof n === "string" ){
o.html(n);
$(this).html(c).append(n);
}
return o.html();
}
Usage :$('myselector').content('NewContentString');
This is the solution that worked for the most browsers
$('label[for="user_name"]').contents().last()[0].nodeValue = 'Title';
This one came close but gave issues in ie8 since textContent is not supported
$('label[for="user_name"]').contents().last()[0].textContent='Title';
if you are manipulating more than 1 label you can select each label and replace text with jquery:
$('label[for="user_name"]').contents().last().replaceWith("Title");
and for the second label :
$('label[for="user_lastname"]').contents().last().replaceWith("Title2");
and so on ...
I'm having an impossibly hard time finding out to get the actual DOMElement from a jQuery selector.
Sample Code:
<input type="checkbox" id="bob" />
var checkbox = $("#bob").click(function() { //some code } )
and in another piece of code I'm trying to determine the checked value of the checkbox.
if ( checkbox.eq(0).SomeMethodToGetARealDomElement().checked )
//do something.
And please, I do not want to do:
if ( checkbox.eq(0).is(":checked"))
//do something
That gets me around the checkbox, but other times I've needed the real DOMElement.
You can access the raw DOM element with:
$("table").get(0);
or more simply:
$("table")[0];
There isn't actually a lot you need this for however (in my experience). Take your checkbox example:
$(":checkbox").click(function() {
if ($(this).is(":checked")) {
// do stuff
}
});
is more "jquery'ish" and (imho) more concise. What if you wanted to number them?
$(":checkbox").each(function(i, elem) {
$(elem).data("index", i);
});
$(":checkbox").click(function() {
if ($(this).is(":checked") && $(this).data("index") == 0) {
// do stuff
}
});
Some of these features also help mask differences in browsers too. Some attributes can be different. The classic example is AJAX calls. To do this properly in raw Javascript has about 7 fallback cases for XmlHttpRequest.
Edit: seems I was wrong in assuming you could not get the element. As others have posted here, you can get it with:
$('#element').get(0);
I have verified this actually returns the DOM element that was matched.
I needed to get the element as a string.
jQuery("#bob").get(0).outerHTML;
Which will give you something like:
<input type="text" id="bob" value="hello world" />
...as a string rather than a DOM element.
If you need to interact directly with the DOM element, why not just use document.getElementById since, if you are trying to interact with a specific element you will probably know the id, as assuming that the classname is on only one element or some other option tends to be risky.
But, I tend to agree with the others, that in most cases you should learn to do what you need using what jQuery gives you, as it is very flexible.
UPDATE: Based on a comment:
Here is a post with a nice explanation: http://www.mail-archive.com/jquery-en#googlegroups.com/msg04461.html
$(this).attr("checked") ? $(this).val() : 0
This will return the value if it's checked, or 0 if it's not.
$(this).val() is just reaching into the dom and getting the attribute "value" of the element, whether or not it's checked.