Why is it when I select html elements using .get(i) or similar methods, I am unable to use methods on those elements like the .removeClass() or .html().
I would think that the code below is perfectly valid, yet neither lines work. What do I need to do to apply jQuery methods to an element based on its ordinal index in the DOM?
($('li').get(0)).removeClass('yourClass');
$('li')[0].addClass('myClass');
Here is an example of the issue: http://jsfiddle.net/KcNWy/2/
Check the documentation:
The .get() method grants us access to the DOM nodes underlying each jQuery object.
You can DOM object into jQuery object again: $($('li').get(0)). Or, better yet, use eq: $('li').eq(0).
And also a debugging hint. You can use in firefox/chrome/safari console.log(myObject) to see what's actually returned.
The get() method passes back the DOM object
Retrieve the DOM elements matched by the jQuery object.
Try this instead:
$("li:eq(" + 0 + ")").removeClass("yourClass")
Working example: http://jsfiddle.net/KcNWy/6/
Related
I am getting different console output for $('#list') and document.getElementById("list")
My console print is given below.
console.log($('#list'));
console.log(document.getElementById("list"));
But output in console shows different.
[select#list.form-control]
<select id="list" class="form-control" size="10"><option>PHP</option><option>JavaScript</option></select>
but i need same output in javascript like jquery.
The difference is because $('#list') returns a jQuery object and document.getElementById("list") returns an Element.
If you need to get the Element from a jQuery object, access it by index, or use get(). All of the below will give the same output of an Element object:
console.log($('#list').get(0));
console.log($('#list')[0]);
console.log(document.getElementById("list"));
If you want to return a jQuery object use any of these:
console.log($('#list'));
console.log($(document.getElementId('list'));
Note however that the second example in this case is entirely redundant and is only included for completeness.
This is to be expected, jQuery returns the DOM node wrapped in a jQuery object with jQuery methods, while native methods like getElementById will just return the DOM node.
If you wanted the DOM node, you could do
console.log($('#list').get(0));
There's no way to return a jQuery object without jQuery though, and doing
$(document.getElementById("list"))
is pointless, however if you already have a native DOM node, you can just wrap it in jQuery -> $(element)
Ok so I finally have a code example to show this!
if ($('#Snowsports-row')[0].classList.contains("hidden") == false) {
$('#snowsports-only').removeClass("hidden")
}
The code works ONLY as written above, i.e., if the [0] were moved to the second line and removed from the first line, or if it were present/absent in both lines, it would fail.
I understand the output difference...
$('#Snowsports-row')
=> [<div>...]
$('#Snowsports-row')[0]
=> <div>...
...but I'm not understanding under what circumstances you're OK to get an array of element(s) and in which you need to tease out the exact element.
THANKS FOR ALL ANSWERS! Very clearly helped me to figure out that the problem may have been confusing JS/jQuery methods. Final version:
if ($('#Snowsports-row').hasClass("hidden") == false) {
$('#snowsports-only').removeClass("hidden")
}
The .classList method is not widely supported (not in MSIE 9.0 for example) so it's not portable, although where it exists it's fast.
Since every ID in a document is supposed to be unique, and since calling removeClass for a class that isn't present is harmless, just replace your entire call with:
$('#Snowsports-row').removeClass('hidden')
Or better yet, if that class means what I think it does, use .hide() and let jQuery do its job for you, potentially animation the transition in the process.
Alternatively, if you actually wanted to stick with using DOM and classList, you should use the .remove() method that classList already supports:
document.getElementById('#Snowsports-row').classList.remove('hidden')
although there's a minor disadvantage in that this code will crash if that element isn't found (since .getElementById will return null) whereas jQuery silently ignores calls made on empty selectors.
As for the meta-question - you use [n] if you want to access the single DOM element at position n within the jQuery object, as you've done when you use .classList.
You use .eq(n) to obtain a jQuery object representing that DOM element, e.g. if you want to apply jQuery methods to that (single) element.
If there's only a single element, or you want the jQuery method to apply to every matching element, just call the method directly on the selector, as I've done above.
First off, by using jQuery for what it's good at, you can replace this:
if ($('#Snowsports-row')[0].classList.contains("hidden") == false) {
$('#snowsports-only').removeClass("hidden")
}
with this:
$('#Snowsports-row').removeClass("hidden");
Your first block of code does the following:
With $('#Snowsports-row'), make a jQuery object that contains all DOM elements that match the select '#Snowsports-row'.
Then reach into the jQuery object with [0] and get the first DOM object in that jQuery object.
Then, use a property/method on that DOM element to determine if a class exists on that DOM element with your .classList.contains("hidden") reference.
Then, if you find that class, remove it.
A jQuery object contains inside it an array of DOM elements. If you call a method on the jQuery object itself like:
$('.tableRows').html("hello");
Then, you are asking jQuery to operate on ALL the DOM elements inside the jQuery object. You must use jQuery methods, not DOM methods.
If, on the other hand, you want to use a method such as .classList.contains(), that is only a method on an actual DOM element. That isn't a jQuery method. So, you have to reach inside of the jQuery object to get a specific DOM element out of it. That's what the [0] does. It reaches into the jQuery object and gets the first DOM element from its internal data structure. Once you have that DOM element, you can then use any DOM element methods on that DOM object.
FYI, if you ever want to get just the first DOM element from a jQuery object, but want the result to be a jQuery object, not just a DOM element, instead of [0], you can use .eq(0) like ths:
$('#Snowsports-row').eq(0).removeClass("hidden");
Now, in this specific case, this is never necessary because $('#Snowsports-row') cannot ever contain more than one DOM element because internally jQuery will only return the first matching DOM element when you are searching for a ID value (since there's never supposed to be more than one matching element with the same ID).
Just keep in mind that DOM element and a jQuery object are completely different types of objects with different methods on them. What makes it slightly confusing is that a jQuery object contains an internal list of DOM elements. But, if the object you are operating on is a jQuery object, then you can only call jQuery methods on it. If you reach into the jQuery object and pull out a DOM element, then you can only call DOM methods on it.
First of all, ids must be unique, so if you have more than one #Snowsports-only elements you can experience problems.
In your question, you are mixing jQuery code with pure Javascript code.
This:
if ($('#Snowsports-row')[0].classList.contains("hidden") {
...
}
Means that you get the first instance of #Snowsports-row (remember that is better if there is only one element with this id), but you get the DOM object (pure javascript) with the jQuery selector. You can do the same thing in jQuery like this:
$('#Snowsports-row').hasClass("hidden")
See more:
https://api.jquery.com/hasclass/
https://developer.mozilla.org/es/docs/Web/API/Element/classList
Sure, because you are operating over a list. Now, you're kind of mistaking the jQuery/javascript code. If you would like to use the same line twice you can basically drop jQuery altogether and write something like this:
var el = document.getElementById('Snowsports-row');
if (el.classList.contains('hidden')){
el.classList.remove('hidden');
}
In the first line you're selecting one specific DOM element, whereas in the second line you are selecting ALL elements in the DOM that fit that selector and removing the "hidden" class from all of them. Basically checking whether the element has a class can only be performed over an element (that's why you need to select the index, specifying a given element), but jQuery allows you to remove the class of every element inside a list (hence your second line)
Use jQuery's .eq() function. So:
var el = $('#Snowsports-row').eq(0);
if (el.hasClass("hidden")) {
$(el.removeClass("hidden")
}
There's also no harm in calling removeClass on an element that might not have that class... so:
$('#Snowsports-row').eq(0).removeClass('hidden');
How do I access the core HTML DOM element from a JQuery Selector?
For example, the following code:
$(document.body).appendChild(x);
will not work because the DOM object that $(document.body) is referring to is wrapped around by a JQuery Selector Object.
(Please don't suggest that I can use jQuery's append() instead, it's just for an example)
jQuery Objects are arrays of native DOM elements. So try this:
$(document.body)[0].appendChild(x)
On the other hand, if you have a native DOM element, you can just wrap it in a jQuery Object to use jQuery's methods on it.
var x = document.getElementsByTagName('div');
$(x).remove(); // wrap it with $ to use jQuery methods.
.get() should do the work like so :
$(document.body).get(0)
Since jQuery is built on top of Sizzle you can refer to the Sizzle's documentation under this link.
Since $ is just an alias, you can refer to the documentation:
$(String selector[, DOMNode context[, Array results]])
The main function for finding elements. Uses querySelectorAll if
available.
the above will return an array, even if there is only one element. So if you want to refer to the one element exactly, you have to use array index like:
$(document.body)[0].appendChild(x);
this is a native DOM code which should definitely work:
document.body.appendChild(x)
I'm trying to get the children of the nth element returned by a jquery call. For example:
var kids = $('div')[7].children();
However, I keep getting this error with respect to children():
Uncaught TypeError: object is not a function
Can someone explain why this happens? children() works fine as long as I'm not calling it on an indexed element.
It's because it is no longer a jQuery object after you specify an index [7]. Thus, you are calling a jQuery method on a DOM element (which doesn't work).
You could use the .eq() method instead:
$('div').eq(7).children();
You could also use:
$($('div')[7]).children();
It's worth pointing out that this would work because the DOM element is wrapped in $() - thus turning it into a jQuery object.
You're using children method in javascript object i.e. $('div')[7]. To work with jquery method you need to use jquery object instead of javascript object.
Use eq method:
var kids = $('div').eq(7).children();
When you use array syntax with a jquery list you get back a document node, not a jquery element. Use $('div').eq(7).children() instead.
Is there a way to have get() returning a jQuery object instead of "just" the DOM element?
Example:
$("div").get(0) returns [<div></div>] instad of <div></div>.
I'd like to prevent overwrapping like $($("div).get(0)) because the query will get a little bit longer than the example and I fear the readability gets lost. I'd rather not use variables to save unnecessary DOM elements in the RAM, either.
Use eq() to return the jquery object instead of get()
$("div").eq(0)
Given a jQuery object that represents a set of DOM elements, the .eq()
method constructs a new jQuery object from one element within that
set. The supplied index identifies the position of this element in the
set, jQuery doc
You would use eq:
$("div").eq(0)
Use eq() instead , which will return jQuery object
$("div").eq(0)
Also try this also:
$('div:first')