My scenario is that I have one JS file which is being used on two HTML pages. One has a button
with id="a"
and the other doesn't have it. I have attached an event on id="a"
by doing this.
document.getElementbyId("a").onclick = function () { .. }
My problem is when I run second file which doesn't have the button
with id="a"
and it throws the error
TypeError: document.getElementbyId(...) is null
which causes some unexpected behaviour! Is there any way to keep using just one JS file or should I separate the JS file for every html page?
I read a question on StackOverflow here which is about why jQuery doesn't throw an error if the selector is invalid. I need same or similar functionality with vanilla JavaScript.
My scenario is that I have one JS file which is being used on two HTML pages. One has a button
with id="a"
and the other doesn't have it. I have attached an event on id="a"
by doing this.
document.getElementbyId("a").onclick = function () { .. }
My problem is when I run second file which doesn't have the button
with id="a"
and it throws the error
TypeError: document.getElementbyId(...) is null
which causes some unexpected behaviour! Is there any way to keep using just one JS file or should I separate the JS file for every html page?
I read a question on StackOverflow here which is about why jQuery doesn't throw an error if the selector is invalid. I need same or similar functionality with vanilla JavaScript.
Share Improve this question edited May 23, 2017 at 11:47 CommunityBot 11 silver badge asked Apr 21, 2015 at 20:31 maqmaq 1,2263 gold badges19 silver badges34 bronze badges 1- 1 jQuery silently ignores "element not found" conditions because sometimes you want that behaviour and sometimes you don't. Personally, if I say "find this element" and "this element" doesn't exist, I want an error... – Niet the Dark Absol Commented Apr 21, 2015 at 20:34
3 Answers
Reset to default 15The simple fix is to add a check:
if (document.getElementById("a") !== null) {
document.getElementById("a").onclick = function () /* .. */ };
}
jQuery will never break on missing elements, it just silently fails. You can argue about whether that is good or not.
The trick jQuery uses is that it will always return something. $("#id")
will return a jQuery wrapper. That wrapper has functions like .on
and .load
and .html
. A selector can match one, more or no elements. For the wrapper it doesn't matter how many elements are matched.
It works like this:
var elem = get_element("a");
elem.onclick(callback);
function get_element(id) {
var elem = document.getElementById(id);
return { // return a wrapper
onclick: function (callback) {
if (elem !== null) {
elem.onclick = callback;
} else {
// silently fail
}
}
};
}
Consider testing existance
var elm = document.getElementById("a");
if (elm) elm.onclick = function () { .. };
Or falling back in the case of a falsy
(document.getElementById("a") || {}).onclick = function () { .. };
In this second method, the function still gets set but will be quickly GC'd as the reference to {}
dies by the next line.
All of the above solutions are correct. However, you should definitely move away from writing whatever.onclick = function
as that is no longer the best way to write your code. Using this method, you only get one click event. Using a more modern approach allows you to attach as many events as you want.
Also, you mention jQuery but there is no jQuery in the supplied code only vanilla JavaScript. Do you need a jQuery solution or JavaScript?
JavaScript
document.addEventListener('DOMContentLoaded', function(){
var elm = document.getElementById('a');
if ( elm ) { //if the element exists add the click event
elm.addEventListener('click', function(){
//Your "onclick" code here
});
}
});
jQuery
$(function(){
$('#a').on('click', function(){
//Your "onclick" code here
});
});