How do I check an element is exists in JQuery? - javascript

I have to set a specific value to an element if the element is exists.
var a = jQuery("#abc");
if(a) {
a.val("something");
}
For this, I've to check a.length to check the element is exits.
What happen if I directly set the value without checking the element is present or not?
Because, If I do the following
jQuery("#abc").val("dfd");
I don't get any error in chrome when the element is not present. So, can I continue to use like this?
or
any workaround?
Help appreciated!

What happen if I directly set the value without checking the element is present or not?
Nothing. Calling jQuery methods on an empty jQuery object (set) doesn't cause a problem, it just does nothing. This is one of the great things about the set-based concept used in jQuery. The equivalent DOM code (document.getElementById("abc").value = "something";) would throw an error, but the jQuery version doesn't.
Specifically, if the jQuery set is empty:
Calling setter methods (like your val call) becomes a no-op.
Calling getter methods — for instance, var x = $("#foo").val(); — returns the value undefined.
Calling traversal methods — for instance, var divs = $("#foo).find("div"); — gives you a new empty set.
You only need to check (using if (a.length) as you said, or if (a[0])) if you actually care.
jQuery("#abc").val("dfd");
I don't get any error in chrome when the element is not present. So, can I continue to use like this?
Yup.

jQuery's val() method simply sets (or gets) the value of each matching element. If there are no matching element, there will be no value to set (or get). You don't need to check if the element exists first.
From jQuery's val() documentation:
Description: Set the value of each element in the set of matched elements.
If there are no matched elements, nothing will happen.

Try with -
jQuery("#abc").length > 0

Yes, you can safely continue. JQuery just executes a function on all elements found by the selector - if there are none, it does nothing. There's no error.

Related

jQuery: better performance with check whether binding element exists?

I wonder... Let's imagine I have a code something like that:
$('#specific-element').change(some_long_and_ajax_function);
Element with binded ID doesn't exist on all of my pages. On some of them only. I do check whether this element exists like this:
if($('#specific-element').length > 0){
$('#specific-element').change(some_long_and_ajax_function);
// There can be more stuff related to this specific element
}
My question: is it worth it? Is there any performance impact for binding handlers for non-existing elements or checking length is worse than it? Or is it basically same and I have two useless rows? What would you recommend? The first one keeps code nice and clear but I'm not sure if this will be "healthy" for jQuery with dozens of examples like that. Thanks.
jQuery fails gracefully if the element doesn't exist, internally it does it's own check to see if the element exists, and if it doesn't the event handler isn't attached etc.
jQuery() calls jQuery.fn.init wich checks if the passed argument is a string, which in your case it is, it then calls jQuery.fn.find with the right context, and inside that it does
var i, ret = [],
self = this,
len = self.length;
... code
for (i = 0; i < len; i++) {
// add event handlers
}
so the loop never runs if there are no elements to run it on, so there's no need to do your own check, just let jQuery handle it.
EDIT:
When you call $('#specific-element').length you're already calling $(), and it does all the usual things internally and returns an array-like jQuery object that has a length property, and that's exactly what $('#specific-element').change... does as well, and jQuery's on() also returns rather quickly if no elements exists in the collection, so there really is no difference.
If you're really concerned about speed, you'd do something like
var el = document.getElementById('specific-element');
if ( el !== null ) {
el.addEventListener('change', fn, false);
}
but there's really no reason, just add event handler with jQuery the usual way, without checking it the element exists, it's what almost every website in existance does, and it works just fine.
As said in the comment, jQuery check if the element exist before binding events. But there is a speed difference wether you check or not.
When checking before binding, you save time if the element doesn't exist because getting a property (.length) is way faster than calling a function (which will probably call other functions) and failing gracefully.
But if the element exist, it will be slower since you add a condition before binding. Hence, it add 1 more step than if you did not check before and directly binded the event.
Just interpret those test results : http://jsperf.com/check-before-binding1
You can see that if the element exist, the difference between the check before is only 4000 operations / second more. It is not a lot... On the other hand, when you check if the element exist and it doesn't, it save 1,000,000 operations / second because it doesn't call the function .change().
Conclusion
I'd say checking before is better if that really matter, but mostly, it doesn't. If the element is most often present than missing on different pages, i'd directly bind the event. If the element is mostly missing than present, i'd check before binding.
In the end, we are talking about 0.0000001ms...
1I have slightly changed to code to optimise your. Caching the element sure is important is you want better performances.

Strange ie behaviour with jquery inArray

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) { ...

What does $('<div>').parent() return?

I'm working on a jQuery widget that attaches events to the widget's parent, but I'm unable to tell if it has a parent.
For example;
var x = $('<div>');
x.mywidget();
........... in mywidget
_create : function () {
var y = this.element.parent() === undefined ? this.element : this.element.parent();
y.bind(....);
}
I need to check if the widget has been added to the DOM before I do the bind statement. If it has not been added to the DOM, then I'll just bind this.element.bind(....) instead.
The problem is that $('<div>').parent() returns a jQuery object! I was expecting that it would return undefined.
So I'm wondering what parent could it be returning when it shouldn't have a parent?
You may use myDiv.parent().length to know if the jQuery set is empty or not.
But this will yield false positives if the object wasn't removed from the DOM directly but it parent was.
If you want a reliable detection, then, you should use jQuery.contains(document.documentElement, myDiv).
It will always return an object. If you want to see whether anythings in the object, you can check for .length == 0, so $("<div>").parent().length == 0 would be your check.
Check the length of the jQuery object returned. If your div has no parent, the jQuery object returned by .parent will wrap zero elements.
All jQuery DOM searching and manipulation methods return a jQuery collection with 0 or more elements. $("<div>").parent() returns a collection with no elements (an empty collection). You can still call any jQuery method on it, but without being tied to a DOM element what you can do is very limited. It will have .length of zero, and the callback will not be reached when iterating over with .each.
I would check the length of the jQuery object since jQuery will always return an object.
it will be always a parent, can be the body for example
use jquery data for example to set your init marker
var wasInit = ( $(this).data("mypluginwasinit") !== undefined );
if(wasInit) return;
$(this).data("mypluginwasinit","yes");

Why does jQuery.val() behave differently to the rest of jQuery

Typically in a case where jQuery fails to find matching elements using its selector the default value is never an exception but rather a lack of action.
My understanding is this is done by design to ensure that the lack of an element does not result in an error condition. However I have found that jQuery.val() does not exhibit this same behaviour. If a selected element does not exist jQuery.val() will return undefined rather than an empty string (which in keeping with the remainder of the framework I would have expected).
So why is jQuery.val() an exception to the rest of the framework and what would be the best way to change this behaviour?
The key here is chainability of jQuery methods. A jQuery method doesn't return undefined when a selector doesn't match anything because it would break the chain. Consider:
$( '#doesntExist' ).addClass( 'foo' ).fadeIn();
If the selector that doesn't match anything would return undefined it would break the chain since undefined doesn't have any methods of its own. Now every method is executed (and do nothing) whether or not the element is found.
.val() on the other hand is different since it's purpose is to return the value of an element. It doesn't chain at all unlike many other jQuery methods, because a method has to return a jQuery object for it to be able to chain. For example, $( '#foo' ).val().addClass( 'bar' ) does not work regardless of whether the element #foo exists or not.
In this light having .val() return an empty string would not make it any more in line with chainable methods, since no other method returns an empty string when the element isn't found either, and returning undefined does not break chainability since the method doesn't chain in the first place.
(By the way, the same is true for every method that returns a value, like .css() and .data().)
Usually it's more useful to know whether the value of an element is empty or whether the element doesn't exist at all, but if you prefer to always get a string back you can add a method of your own:
$.fn.stringVal = function() {
return( this.val() || '' );
};
If I use .val() to get the value of an item, I expect that item to exist. If it does not, I need to know that. Returning undefined in this case seems the best way.
As pointed out by #Ricardo, .val() performs differently in other cases as well, depending on the input.
jQuery.val() returns the value of an input (or the selected option of a "select")

document.getElementById vs jQuery $()

Is this:
var contents = document.getElementById('contents');
The same as this:
var contents = $('#contents');
Given that jQuery is loaded?
Not exactly!!
document.getElementById('contents'); //returns a HTML DOM Object
var contents = $('#contents'); //returns a jQuery Object
In jQuery, to get the same result as document.getElementById, you can access the jQuery Object and get the first element in the object (Remember JavaScript objects act similar to associative arrays).
var contents = $('#contents')[0]; //returns a HTML DOM Object
No.
Calling document.getElementById('id') will return a raw DOM object.
Calling $('#id') will return a jQuery object that wraps the DOM object and provides jQuery methods.
Thus, you can only call jQuery methods like css() or animate() on the $() call.
You can also write $(document.getElementById('id')), which will return a jQuery object and is equivalent to $('#id').
You can get the underlying DOM object from a jQuery object by writing $('#id')[0].
Close, but not the same. They're getting the same element, but the jQuery version is wrapped in a jQuery object.
The equivalent would be this
var contents = $('#contents').get(0);
or this
var contents = $('#contents')[0];
These will pull the element out of the jQuery object.
A note on the difference in speed. Attach the following snipet to an onclick call:
function myfunc()
{
var timer = new Date();
for(var i = 0; i < 10000; i++)
{
//document.getElementById('myID');
$('#myID')[0];
}
console.log('timer: ' + (new Date() - timer));
}
Alternate commenting one out and then comment the other out. In my tests,
document.getElementbyId averaged about 35ms (fluctuating from 25ms up to 52ms on about 15 runs)
On the other hand, the
jQuery averaged about 200ms (ranging from 181ms to 222ms on about 15 runs).
From this simple test you can see that the jQuery took about 6 times as long.
Of course, that is over 10000 iterations so in a simpler situation I would probably use the jQuery for ease of use and all of the other cool things like .animate and .fadeTo. But yes, technically getElementById is quite a bit faster.
No. The first returns a DOM element, or null, whereas the second always returns a jQuery object. The jQuery object will be empty if no element with the id of contents was matched.
The DOM element returned by document.getElementById('contents') allows you to do things such as change the .innerHTML (or .value) etc, however you'll need to use jQuery methods on the jQuery Object.
var contents = $('#contents').get(0);
Is more equivilent, however if no element with the id of contents is matched, document.getElementById('contents') will return null, but $('#contents').get(0) will return undefined.
One benefit on using the jQuery object is that you won't get any errors if no elements were returned, as an object is always returned. However you will get errors if you try to perform operations on the null returned by document.getElementById
No, actually the same result would be:
$('#contents')[0]
jQuery does not know how many results would be returned from the query. What you get back is a special jQuery object which is a collection of all the controls that matched the query.
Part of what makes jQuery so convenient is that MOST methods called on this object that look like they are meant for one control, are actually in a loop called on all the members int he collection
When you use the [0] syntax you take the first element from the inner collection. At this point you get a DOM object
In case someone else hits this... Here's another difference:
If the id contains characters that are not supported by the HTML standard (see SO question here) then jQuery may not find it even if getElementById does.
This happened to me with an id containing "/" characters (ex: id="a/b/c"), using Chrome:
var contents = document.getElementById('a/b/c');
was able to find my element but:
var contents = $('#a/b/c');
did not.
Btw, the simple fix was to move that id to the name field. JQuery had no trouble finding the element using:
var contents = $('.myclass[name='a/b/c']);
var contents = document.getElementById('contents');
var contents = $('#contents');
The code snippets are not the same. first one returns a Element object (source).
The second one, jQuery equivalent will return a jQuery object containing a collection of either zero or one DOM element. (jQuery documentation). Internally jQuery uses document.getElementById() for efficiency.
In both the cases if more than one element found only the first element will be returned.
When checking the github project for jQuery I found following line snippets which seems to be using document.getElementById codes (https://github.com/jquery/jquery/blob/master/src/core/init.js line 68 onwards)
// HANDLE: $(#id)
} else {
elem = document.getElementById( match[2] );
Just like most people have said, the main difference is the fact that it is wrapped in a jQuery object with the jQuery call vs the raw DOM object using straight JavaScript. The jQuery object will be able to do other jQuery functions with it of course but, if you just need to do simple DOM manipulation like basic styling or basic event handling, the straight JavaScript method is always a tad bit faster than jQuery since you don't have to load in an external library of code built on JavaScript. It saves an extra step.
One other difference: getElementById returns the first match, while $('#...') returns a collection of matches - yes, the same ID can be repeated in an HTML doc.
Further, getElementId is called from the document, while $('#...') can be called from a selector. So, in the code below, document.getElementById('content') will return the entire body but $('form #content')[0] will return inside of the form.
<body id="content">
<h1>Header!</h1>
<form>
<div id="content"> My Form </div>
</form>
</body>
It might seem odd to use duplicate IDs, but if you are using something like Wordpress, a template or plugin might use the same id as you use in the content. The selectivity of jQuery could help you out there.
All the answers are old today as of 2019 you can directly access id keyed filds in javascript simply try it
<p id="mytext"></p>
<script>mytext.innerText = 'Yes that works!'</script>
Online Demo!
- https://codepen.io/frank-dspeed/pen/mdywbre
jQuery is built over JavaScript. This means that it's just javascript anyway.
document.getElementById()
The document.getElementById() method returns the element that has the ID attribute with the specified value and Returns null if no elements with the specified ID exists.An ID should be unique within a page.
Jquery $()
Calling jQuery() or $() with an id selector as its argument will return a jQuery object containing a collection of either zero or one DOM element.Each id value must be used only once within a document. If more than one element has been assigned the same ID, queries that use that ID will only select the first matched element in the DOM.
All the answers above are correct. In case you want to see it in action, don't forget you have Console in a browser where you can see the actual result crystal clear :
I have an HTML :
<div id="contents"></div>
Go to console (cntrl+shift+c) and use these commands to see your result clearly
document.getElementById('contents')
>>> div#contents
$('#contents')
>>> [div#contents,
context: document,
selector: "#contents",
jquery: "1.10.1",
constructor: function,
init: function …]
As we can see, in the first case we got the tag itself (that is, strictly speaking, an HTMLDivElement object). In the latter we actually don’t have a plain object, but an array of objects. And as mentioned by other answers above, you can use the following command:
$('#contents')[0]
>>> div#contents

Categories