why when i write
document.getElementByClass('home1').setAttribute('style', 'background-image:url(img/red_menu.PNG);');
it doesn't work?
i have the element with class="home1"
with document.getElementById('home1')...
works fine
thanks
It's getElementsByClassName, not getElementByClass; details here. Note that IE does not support this function (yet).
getElementsByClassName returns a NodeList of matching elements (rather than a single element), so:
var list, index;
list = document.getElementsByClassName("home1");
for (index = 0; index < list.length; ++index) {
list[index].setAttribute(/* ... */);
}
For this sort of thing, you may want to use a library like jQuery, Prototype, Google Closure, etc., to pave over the various browser differences for you. They can save you a lot of time and trouble compared with dealing with those differences yourself.
For instance, in jQuery:
$(".home1").attr(/* ... */);
...applies that attribute (via jQuery#attr) to every element with the class "home1". Although in your particular case, you'd probably want jQuery#css instead.
If you have only one classname in your entire HTML file, then you could also use
document.getElementsByClassName('navbar-nav')[0].setAttribute('id', 'navbar-toggle');
Related
I want to know if there is a way to getElementByClassName("classname").innerHTML function or something to the equivalent of getElementById("ClassName").innerHTML.
You are missing an s in your function name. getElementsByTagName returns a collection of elements, of elements, which you need to iterate over:
var elements = document.getElementsByClassName("classname");
for (var i = 0; i < elements.length; i++) {
elements[i].innerHTML = 'foo';
}
IE8 and below don't support getElementsByClassName, so you'll have to find a polyfill or use querySelectorAll (IE8).
I suggest you to use JQuery, where you can use directly CSS selectors (like .yourclass) to find all elements of a given class:
$('.yourclass').doWhatYouWant();
If you prefer not to use JQuery, you can use plain Javascript:
document.getElementsByClassName('my-fancy-class')
But be careful with IE8 incompatibility issue.
As an alternative (slower but you can build more complex CSS selectors) you can use:
document.querySelector('.cssSelector')
Which will return one element responding to your CSS selector, or
document.querySelectorAll('.cssSelector')
Which will return multiple elements instead.
You can do this using jquery
$('.className').html();
http://api.jquery.com/html/
If tou use jQuery you can get it as you would in a CSS selector so:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
then...
$('.classname').each(function() {
// get html
$(this).html();
// set html
$(this).html('something');
});
Notice you have also convenient way to manage innerHTML.
Honestly, I don't know where to start with "extracting." My best guess would be to use the basic .html() tag from JQuery to solve this problem. This is for a small project to improve my JavaScript skills. Any ideas on how this could be done? Thanks so much...
I apologize for being unclear. I meant extracting all the links from a particular page from a domain I don't own. Then, putting these links into an array. Thanks!
Well, this comes to mind ?
var arr = [].slice.call( document.querySelectorAll('a') );
It gets all the matching elements with querySelectorAll, and converts the returned nodeList to an array using [].slice.call, where [] is a shortcut for Array.prototype. In other words it calls the native Array.slice method with call(), passing the elements in as the this value, effectively creating an array from the elements.
if you need the HTML, and not the DOM elements, you can map the elements array and return the outerHTML
var markup = arr.map(function(elem) { return elem.outerHTML; });
or if you just need the URL's, you can run the same map and return the href attribute instead
var urls = arr.map(function(elem) { return elem.getAttribute('href'); });
You don't necessarily need jQuery for this and if learning Javascript is your goal you might be better off without using it for now. querySelectorAll is available in all modern browsers and can accomplish what you are looking for. Per the documentation:
Returns a list of the elements within the document (using depth-first pre-order traversal of the document's nodes) that match the specified group of selectors. The object returned is a NodeList.
A NodeList is not an array however so you would need to do a little extra work to make an array of the link elements. You can read in the documentation why they are different.
The selectors used in the method are CSS Selectors and you can checkout the documentation for querySelector for examples.
So to do what you want you could do something like:
var a_list = document.querySelectorAll('a'); // returns NodeList
var a_array = Array.prototype.slice.call(a_list); // converts NodeList to Array
If the jQuery is an acceptable option, you can get all the links by a simple
var links = $('a[href]');
The "links" is an array already.
I would also fiddle around with something like this.
Array.prototype.slice.call(document.querySelectorAll('a'));
Googling it would be a good start so you can learn more about how it works and use it to your advantage.
Hello this seems to be working on IE8 :
var clsName = link.parents("div.fixed_column").attr("class").split(" ");
if($.inArray("column_one", clsName)
While this one reports error (Object expected errror in jquery).
var clsName = link.parents("div.fixed_column").attr("class");
What is the right way to do this? I thought purpose of inArray was that jquery will handle cross browser issues.
Unfortunately, this is indirectly answering your question, but... You seem to be looking to detect if an element has a class, and since you're already using jQuery, just use the hasClass method - http://api.jquery.com/hasClass/
For your specific code, try:
if (link.parents("div.fixed_column").hasClass("column_one")) {
// It has the "column_one" class
}
The more immediate answer to your question is that link.parents("div.fixed_column").attr("class") returns a single string. When the jQuery selector (div.fixed_column) returns multiple elements, which is very possible when using classes, using jQuery methods that get information (like .attr, using one parameter...to "get" the value) return the first matched element's value only.
So say the selector matches 3 elements:
["<div id='div30' class='fixed_column div30_class'></div>",
"<div id='div2' class='fixed_column div2_class'></div>",
"<div id='div17' class='fixed_column div17_class'></div>"]
Then the value returned from .attr("class") will be: fixed_column div30_class because it's the first matched element.
I'm not sure, but I think you're expecting jQuery to return an array of all the matched elements' values, which it just doesn't. So that doesn't mean jQuery isn't handling cross-browser issues, it just means you need to look up what the method does/returns.
I could've sworn that jQuery 2.0 has options for doing what you want - directly from calling the getters (or something similar), but I can't find it anymore :( Maybe I'm remembering incorrectly. Anyways, you could easily use $.each and/or $.map to look at every matched element, but it depends on what you were really trying to do with it.
You can't read the attributes of multiple elements into an array with .attr("class"). But why don't you just target the desired class in the selector like this?
var cols = link.parents("div.fixed_column.column_one");
Then change your conditional to check for an empty set:
if(cols.length) { ...
Libraries I've seen have DOM wrappers that inclusively handle only the first element of the list in some case, like:
return this[0].innerHTML
and use the whole list in some other like:
for( var i=0, l=this.length; ++i<l; ) this[i].className = cls;
return this
Why is this approach accepted?
I think singling out the first element defeats the purpose of having methods that apply the same thing on the rest of the list. Isn't it bad to have dubious functions? I know it suits many people..but it feels inconsistent and I'm interested in why this is accepted so widely.
EDIT as an example:
jQuery.html()
If the selector expression matches more than one element, only the
first match will have its HTML content returned.
why not all?
the hide() method in bonzo, from Dustin Diaz
//...
hide: function () {
return this.each(function (el) {
el.style.display = 'none'
})
}
why not only the first?
The accessor methods in jQuery return single values because it's simpler and more generally useful. If the .html() API were to return the value if innerHTML for all elements, that'd mean it'd have to return an array. That, in turn, would mean that in the most common case of wanting the contents of a single element, you'd have to add the array access. There's also the problem of knowing exactly which returned value goes with which selected element. In other words, if .html() returned an array of element contents:
var contentList = $('.someClass, span, .hidden .container').html();
If "contentList" were just a simple array, what use would it be? How would the code know for each element which DOM node it came from? Of course there are solutions to this, but again the simple case is made complicated in order to support a rare general case.
It's possible of course to get the list yourself with .map(). I think this is just an issue of smart, practical, pragmatic API design.
why when i write
document.getElementByClass('home1').setAttribute('style', 'background-image:url(img/red_menu.PNG);');
it doesn't work?
i have the element with class="home1"
with document.getElementById('home1')...
works fine
thanks
It's getElementsByClassName, not getElementByClass; details here. Note that IE does not support this function (yet).
getElementsByClassName returns a NodeList of matching elements (rather than a single element), so:
var list, index;
list = document.getElementsByClassName("home1");
for (index = 0; index < list.length; ++index) {
list[index].setAttribute(/* ... */);
}
For this sort of thing, you may want to use a library like jQuery, Prototype, Google Closure, etc., to pave over the various browser differences for you. They can save you a lot of time and trouble compared with dealing with those differences yourself.
For instance, in jQuery:
$(".home1").attr(/* ... */);
...applies that attribute (via jQuery#attr) to every element with the class "home1". Although in your particular case, you'd probably want jQuery#css instead.
If you have only one classname in your entire HTML file, then you could also use
document.getElementsByClassName('navbar-nav')[0].setAttribute('id', 'navbar-toggle');