How do I get the class name through JavaScript given no id with this span.
Like: <span class="xyz"></span>
I want to change the background color of this span.
How can I solve this? Please help me.
tympanus.net/Tutorials/CSS3PageTransitions/index3.html#contact
Something like this should work:
var spans = document.getElementsByTagName("span");
for (var i = 0; i < spans.length; i++) {
if (spans[i].className == 'xyz') {
spans[i].style.backgroundColor = '#000';
}
}
You have the following choices:
Use document.getElementsByClassName("xyz"). This will return a NodeList (like an array) of objects that have that class name. Unfortunately, this function does not exist in older versions of IE.
Use document.getElementsByTagName("span") and then loop over those objects, testing the .className property to see which ones have the desired class.
Use document.querySelectorAll(".xyz") to fetch the desired objects with that class name. Unfortunately this function does not exist in older browsers.
Get a library that automatically handles all CSS3 selector queries in all browsers. If you want just a selector library, then you can use Sizzle. If you want a more comprehensive library for manipulating the DOM, then use YUI3 or jQuery (both of which have Sizzle built-in).
As of 2011, my advice is option #4. Unless this is a very small project, your development productivity will improve immensely by using a CSS3 selector library that has already been developed for cross-browser use. For example in Sizzle, you can get an array of objects with your class name with this line of code:
var list = Sizzle(".xyz");
In jQuery, you can create a jQuery object that contains a list of objects with that class with this line of code:
var list = $(".xyz");
And, both of these will work in all browsers since IE6 without you having to worry about any browser compatibility.
In more modern times (like 2021), you can use built in document.querySelectorAll() and see fairly rich CSS3 selector support.
You can use document.getElementsByClassName('xyz'). Note: it returns an array a NodeList (thanks to #IAbstractDownvoteFactory) since there can be multiple elements with the same class.
var spans = document.getElementByClassName('xyz');
var i;
for(i=0; i<spans.length; i++) {
spans[i].style.backgroundColor = your_color;
}
You can use a jquery to solve the same issue.
var classname = $(this).attr('class'); //here you will get current class name if its with multiple class split it and take first class.
$("."+classname.split(" ")[0]).css("background-color", "yellow");
Related
For example:
var inputs = document.querySelectorAll('input[type="checkbox"]');
I want to set the checked to true on all inputs. Can this be done like in jQuery, without using a for loop?
querySelectorAll returns a NodeList. You will need to iterate over the list to change each item in it (jQuery loops over the entire collection too in the background using .each)
You can either use a loop (for, while, etc) or you could use the forEach method on the Array prototype
https://developer.mozilla.org/en-US/docs/DOM/NodeList#Workarounds
No, this cannot be done without some form of iteration over the nodes. jQuery iterates over the nodes as well, it just hides it from the user.
The closest that comes to jQuery-like style is using .forEach [MDN] in browser where it is supported:
[].forEach.call(inputs, function() {
this.checked = true;
});
without using a for loop
At some point, you're going to need some form of loop. Are you just hoping to abstract it?
NodeLists are Array-like, so you can call or apply methods from Array.prototype, including iterators like forEach(). An example from MDN:
Another approach without extending the DOM:
var forEach = Array.prototype.forEach;
var links = document.getElementsByTagName('a');
forEach.call(links, function(link){ // works in most browsers (please document here if you find browsers where it doesn't)
link.style.color = '#0F0';
});
But note that even forEach() depends on a loop (while in this case).
Using pure JavaScript you can use the querySelectorAll() function as below:
var checkboxes = document.querySelectorAll('input[type="checkbox"]');
for(var i=0; i<checkboxes.length; i++) { checkboxes[i].checked = true; }
Unfortunately this doesn't avoid looping which I know you wanted to avoid and It also doesn't have perfect cross browser compatibility as can be checked here with IE 8 only being able to hook on to CSS 2.1 selectors and Pre IE8 not being supported at all but it's the best that can be done without using lots of code and avoiding jQuery.
I know you want to avoid jQuery but, if you change your mind you can try the following:
$('input[type="checkbox"]').attr('checked', 'checked')
This should hook on to any checkbox input and set its attribute to checked using the jQuery attr() function.
If this doesn't work try giving your checkboxes their own class name such as checkbox and try like as follows:
$('.checkbox').attr('checked', 'checked')
This would help with compatibility issues and would avoid looping but if you don't want to go the jQuery route then please ignore.
I have a javascript function MyFunc() that does what it has to do with id="item_for_MyFunc".
In the function there is a
var elem = document.getElementById("item_for_MyFunc");
and html body has:
<body onload="MyFunc()">
<p id="item_for_MyFunc">
Everything works, but I want to use this function for several items on the page. That's why I should use <p class="item_for_MyFunc"> several times on the page to be processed by this function, so using id is not a solution.
What changes in the function should be done so it could be changed for class="item_for_MyFunc"?
So what you're doing there is pretty simple. Let me give you a slightly more robust version:
document.addEventListener('load', function(){
var elements = document.querySelectorAll('.myClassName');
for(var i=0, len=elements.length; i<len; i++){
MyFunc.call( elements[i] );
}
}, false);
So old versions of IE, 6 and 7 to be specific, don't have querySelectorAll. I'm assuming you aren't worried about them. If you are, there's other ways to do this and I can show you how if you need.
Basically we're giving all of your elements a class of 'myClassName', and querySelectorAll finds all of them and returns an array of DOM elements.
We then iterate through the list, and execute MyFunc on each of those elements.
Edit
So one key principal of writing good javascript is to separate the js code from your html markup as much as possible. You should almost never use inline event handlers like onload="myFunc" anymore. Use event handlers written in the js itself.
If you have the option, you should use the jQuery library. It makes a lot of this stuff incredibly easy, has great support for very old browsers, and is used on hundreds of thousands of websites.
document.getElementsByClassName
would return an array of all HTML elements using the class name. Iterate over the results and you are set. Supported in all browsers except IE <= 8, FF < 3. Works just like document.querySelectorAll (works in IE >= 7, FF >=3.5)
Refer:
http://quirksmode.org/dom/w3c_core.html#gettingelements
for compatibility chart.
You could try:
var elems = document.getElementsByClassName('myClass');
I've not used that one before, but you could use jQuery as that's even simpler;
var elems = $('.myClass');
var paras = document.getElementsByClassName('hi');
for (var i = 0; i < paras.length; i++) {
paras[i].style.color = '#ff0011';
// $('.hi').remove();
}
<p class="hi">dood</p>
<p class="hi">dood</p>
<p class="hi">dood</p>
<p class="hi">dood</p>
<p class="hi">dood</p>
<p>not class 'hi'</p>
In jQuery, this would be very easy: $('.hi').remove();. I want to learn JS, and then jQuery.
I am stuck and Google has not provided. I do not want to become a copy/paste jQuery programmer. I am just starting to learn JS. Thanks.
To remove an element you do this:
el.parentNode.removeChild(el);
MDN is a great reference. Here are a few relevant pages:
Node
parentNode
removeChild
However you'll run into issues if you loop like that since getElementsByClassName returns a live list, when you remove a node the element is removed from the list as well so you shouldn't increment or you will end up skipping every other element. Instead just continually remove the first element in the list, until there is no first element:
var paras = document.getElementsByClassName('hi');
while(paras[0]) {
paras[0].parentNode.removeChild(paras[0]);
}
IMO jQuery is great at showing you what is possible to do in Javascript. I actually recommend that after about a week or two of plain JS you learn jQuery, get good at it, and remember what it's abstracting away. One day when you have an excellent grasp of Javascript scoping, objects, and such which you can obtain while using jQuery, go back and try learning how to interact better with the DOM without a library. That way you'll have an easier time learning plain JS and you'll appreciate the abstraction that libraries can provide you even more, while learning that when you only need one or two things a library provides you may be able to write them yourself without including the entire library.
Simple ES6 answer:
document.querySelectorAll('.classname').forEach(e => e.remove());
Explanation:
document.querySelectorAll() loops through the elements in the document returning a NodeList of all elements with the specified selector (e.g. '.class', '#id', 'button')
forEach() loops through the NodeList and executes the specified action for each element
e => e.remove() removes the element from the DOM
Note, however, that this solution is not supported by Internet Explorer. Then again, nothing is.
[].forEach.call(document.querySelectorAll('.hi'),function(e){
e.parentNode.removeChild(e);
});
Here I'm using Array.prototype.forEach to easily traverse all elements in an array-like object, i.e. the static NodeList returned by querySelectorAll, and then using removeChild() to remove the item from the DOM.
For older browsers that don't support querySelectorAll() or forEach():
var classMatcher = /(?:^|\s)hi(?:\s|$)/;
var els = document.getElementsByTagName('*');
for (var i=els.length;i--;){
if (classMatcher.test(els[i].className)){
els[i].parentNode.removeChild(els[i]);
}
}
Note that because getElementsByTagName returns a live NodeList, you must iterate over the items from back to front while removing them from the DOM.
There are also some older browsers that don't support querySelectorAll but that do support getElementsByClassName, which you could use for increased performance and reduced code.
Afaik only a parent can remove a child in native JS. So you would first have to get that elements parent, then use the parent to remove the element. Try this:
var parent = paras[i].parentNode;
parent.removeChild(paras[i]);
I am wondering if I could use query and javascript together so I could select an element by class with the javascript and then use javascript to work on that element. Sorry if that didn't make sense. Here is an example:
$('.nav_flag').src = "images/flags/"+userCountryLower+".gif";
Would that work, if not how do I get an element by class using regular javascript. Thanks!
EDIT:I know JQUERY is JavaScript but I was wondering if I could mix jquery selectors and javascript 'controller'-for a loss of a better word
To answer your question as asked, there are several ways to take a jQuery object, i.e., what is returned by $('some selector'), and get a reference to the underlying DOM element(s).
You can access the individual DOM elements like array elements:
// update the src of the first matching element:
$(".nav_flag")[0].src = "images/flags/"+userCountryLower+".gif";
// if you're going to access more than one you should cache the jQuery object in
// a variable, not keep selecting the same thing via the $() function:
var navFlgEls = $(".nav_flag");
for (var i = 0; i < navFlgEls.length; i++) { ... }
But you wouldn't manually loop through the elements when you can use jQuery's .each() method, noting that within the callback function you provide this will be set to the current DOM element:
$(".nav_flag").each(function() {
this.src = "images/flags/"+userCountryLower+".gif";
});
However, jQuery provides a way to set attributes with one line of code:
$(".nav_flag").attr("src", "images/flags/"+userCountryLower+".gif");
To answer the second part of your question, doing the same thing without jQuery, you can use .getElementsByClassname() or .querySelectorAll() if you don't care about supporting older browsers.
jQuery IS Javascript. You can mix and match them together. But you better know what you're doing.
In this case, you probably want to use .attr function to set value of attribute.
Use .attr() in jQuery, rather than mix the two here.
$('.nav_flag').attr('src', "images/flags/"+userCountryLower+".gif");
In many instances, it is fine to mix jQuery with plain JavaScript, but if you have already included the jQuery library, you might as well make use of it. Unless, that is, you have an operation which in jQuery would be more computationally expensive than the same operation in plain JavaScript.
You can do it with jQuery too:
$('.nav_flag').attr("src", "images/flags/"+userCountryLower+".gif");
keep in mind that jQuery is simply a library built upon javascript.
for any jQuery object, selecting its elements by subscription will return the corresponding dom element.
e.g.
$('#foo')[0] // is equivalent to document.getElementById('foo');
You need to add an index to the jQuery object to get the native Javascript object. Change:
$('.nav_flag').src = "images/flags/"+userCountryLower+".gif";
To:
$('.nav_flag')[0].src = "images/flags/"+userCountryLower+".gif";
To get elements by class name in Javascript you can use:
document.getElementsByClassName( 'nav_flag' )[0].src = "images/flags/"+userCountryLower+".gif";
To answer your question, you could use .toArray() to convert the jQuery object into an array of standard DOM elements. Then either get the first element or loop through the array to set all the elements with the class.
However, you could do this easier with pure jquery with attr or prop depending on the version:
$('.nav_flag').attr("src", "images/flags/"+userCountryLower+".gif");
Or use pure javascript:
if (navFlagElements = document.getElementsByClassName("nav_flag") && navFlagElements.length > 0) {
navFlagElements[0].src = "images/flags/"+userCountryLower+".gif"
}
I got a div, and there i got some childnodes in undefined levels.
Now I have to change the ID of every element into one div. How to realize?
I thought, because they have upgoing IDs, so if the parent is id='path_test_maindiv' then the next downer would be 'path_test_maindiv_child', and therefore I thought, I'd solve that by wildcards, for example:
document.getElementById('path_test_*')
Is this possible? Or are there any other ways?
Not in native JavaScript. You have various options:
1) Put a class and use getElementsByClassName but it doesn't work in every browser.
2) Make your own function. Something like:
function getElementsStartsWithId( id ) {
var children = document.body.getElementsByTagName('*');
var elements = [], child;
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (child.id.substr(0, id.length) == id)
elements.push(child);
}
return elements;
}
3) Use a library or a CSS selector. Like jQuery ;)
In one of the comments you say:
(...) IE is anyway banned on my page, because he doesn't get it with CSS. It's an admin tool for developer, so only a few people, and they will anyway use FF
I think you should follow a different approach from the beginning, but for what it's worth, in the newer browsers (ok, FF3.5), you can use document.querySelectorAll() with which you can get similar results like jQuery:
var elements = document.querySelectorAll('[id^=foo]');
// selects elements which IDs start with foo
Update: querySelectorAll() is only not supported in IE < 8 and FF 3.0.
jQuery allows you to find elements where a particular attribute starts with a specific value
In jQuery you would use
$('[id^="path_test_"]')
Try this in 2019 as a wildcard.
document.querySelectorAll("[id*=path_test_]")
I don't think so wildcards are allowed in getelementById.
Instead you can have all the child nodes of your respective DIV using:
var childNodeArray = document.getElementById('DIVID').childNodes;
This'll give you an array of all elements inside your DIV. Now using for loop you can traverse through all the child elements and simultaneously you can check the type of element or ID or NAME, if matched then change it as you want.
You should not change ID of element to ID of other existing element. It's very wrong, so you better re-think your core logic before going on.
What are you trying to do exactly?
Anyway, to get all elements with ID starting with something, use jQuery as suggested before, if you can't it's also possible using pure JavaScript, let us know.