When document.getElementByID is used without an ID what is it doing? - javascript

I have some code I am looking at that is using a variation on getElementByID that I do not understand. I have looked online but I am not finding anything that explains this.
I understand how to use something like document.getElementByID("bob"), however what I am looking at says:
if (document.getElementByID){}
When you use getElementByID in this fashion what is it doing?

document.getElementById returns the function which can be used to get some element by ID.
typeof document.getElementById; // 'function'
However, if some browser didn't implement getElementById, you would get undefined.
Therefore, this is just a test to ensure that the method exists before calling it, avoiding an error.
if(document.getElementById) {
// Hopefully it's safe to call it
document.getElementById("bob");
// ...
} else {
alert('What kind of stupid browser are you using? Install a proper one');
}

This will return false:
if (document.getElementByID){}
because there is no getElementByID on the document object. There is however, getElementById (notice the difference in the d at the end).
Therefore, this will return true
if (document.getElementById){}
In short, if getElementByID exists on document, which because of the typing, does not, but if it did then do something.
A more full example using the right spelling:
if (document.getElementById) {
// it is safe to use this method because it exists on document
var element = document.getElementById('foo');
}
document.getElementById returns a function which evaluates to true when in an expression. You can test this out yourself but running the code snippet.
console.log(document.getElementById);
// The !! forces a boolean
console.log(!!document.getElementById);

Related

What does 'true' mean in a jQuery selector?

This seems like such a basic question, but I swear I can't see it in the jQuery documentation.
I've inherited some code that does:
$('.tag', true);
The jQuery docs simply say:
jQuery( selector [, context ] )
And 'true' isn't a context in this case. Is this something to do with bubbling? What does 'true' do in a selector, and where does the documentation cover this use case?
Edit: As A. Wolff notes below, this isn't jQuery, it's an alias for document.querySelector & querySelectorAll.
function $(selector, all) {
return base['querySelector'+(all?'All':'')](selector);
}
So $ isn't referring to jQuery but to custom method. Then the true parameter has nothing to do with context. :)
There is actually a significant difference.
Passing true forces the context of the returned jQuery object to be undefined.
$('.tag'), $('.tag', false), $('.tag', 'body') etc will all set the context to be document, the default.
I dont know why the original programmer have had this need for working on elements with no context, and do not dare to guess.
check it out -> console.dir($('.tag', true));

Is it wrong too return different types in a javascript function?

Is it wrong to return two different types from a JavaScript function? This is often the case in PHP. For instance PHP's strpos()-function returns an integer telling you the position or false if not found. In Java this would not be possible since it's not a loose typed language and the return type is defined with the function.
So would be be wrong to do the same in JavaScript?
E.g.
function num(x, y) {
if (x !== y) {return false;}
if (x < 5) {return 5;}
return x;
}
In above example we return an integer or boolean. But is it wrong? Would it make the life of the JavaScript engine harder and perhaps force it to de-optimize?
Or in another example, what if I have a function that creates an element and tries to put it into the DOM then returns the newly created element object. But if it can't find the parent element you send as an param it return false.
This is not wrong, since Javascript is dynamically typed.
However, it is often considered as bad taste: makes the code less readable, and might make it less efficiently translatable by JIT techniques.
It's not at all wrong. Your code will execute its job successfully. But the thing is it's not considered a very good programming practice. Though there are no hard and fast rules and in many situations such a methodology may be required, it's advisable to avoid this approach as far as applicable.
Secondly, you can consider re-factoring your code, so that it does only one thing. My suggestion would be to separate both the 'if's into two different methods.
It's not strict wrong, because javascript is dynamically typed. But if it happens, it could hide a wrong architecture of your function.
What happens in some cases?
In some case, JavaScript core returns null if there is no result. Is the case of .match function. In this case, null is something like "I've found nothing".
In other case it returns -1 (i.e. .indexOf). In this case it's appropriate because the return value should be an integer positive. -1 it's a way to tell us: "I've found nothing" or "I've not found a positive integer".
So why it returns in one case null and in other way -1 for tell us the same thing?
In the first case the match should return an Array (that's an Object).
In the second case the indexOf should return an integer. So -1 is more appropriate than null, because null it's an Object and not an integer.
Why not undefined? because undefined is something of undefined, like: "I've found nothing, and I don't know how tell you!". undefined generally is used when the function should returns a String but this string is not found. Returns "" is not elegant because it tell us: "I've found the String, and the string is empty".
Another case could be a function that returns a Boolean but in one case is undefined. So when you ask: "It's true or false?", it seems to says: "Neither!".
A beautiful example is this function:
isAlive(SchroedingersCat); // <--- undefined!!!
What if your function should be return a DOM element?
See what jQuery doing.
jQuery return always an Object. This object (instance of itself) could be empty or not.
var obj = $('#idElement') // <--- return always a jQuery object
if(obj.length == 1) {
// do something
}
This is an excellent trick in order to permit us to do a chain without force to check every time if we found something.

Check if something works

I'm trying to test what is available on a specific browser (JavaScript-wise).
If I just typed this for example:
function checksetAttribute(){
if(document.getElementById("blar").setAttribute("name","blarDiv")){
alert("Your browser supports it.");
}
else{
alert("Your browser does not support it.");
}
}
Would this return a true answer as to whether or not the property(ies) work?
If you want to test whether a certain property works, not whether setAttribute works, then this is the wrong approach, as setAttribute always returns undefined (== false). Instead, test whether the element has the attribute name as a key - and use a new element instead of one pulled from the DOM, because elements in the DOM could have been modified.
function attributeWorks(attr, within) {
return document.createElement(within || 'div').hasOwnProperty(attr);
}
I added the within parameter because some properties exist only on certain types of elements: for example, if you always test against a <div>, then the function will return false for href.
If you want to test whether the setAttribute function works this is still the wrong approach, because, if setAttribute is not implemented, trying to execute it will throw an error instead of returning false. We can use the same method as above, with the simplification that we already know the parameters:
function setAttributeWorks() {
return document.createElement('div').hasOwnProperty('setAttribute');
}
No. Assuming the browser supports document.getElementById and setAttribute, it will just set the name attribute. As that method returns void (which is falsy), it will always alert "Your browser does not support it." - unless an Exception is thrown.
It neither will check whether the browser supports name attributes.
I am guessing that the code you have there would fail if "setAttribute" was not supported.
var a = document.createElement("div");
if(a.setAttribute){
alert("VERY SUPPORTED");
}else{
alert("Not supported");
}
This would check to see if the setAttribute method is available on dom elements.

Any difference between a $ wrap function and getElementById?

I mean a wrap function like this:
function $(id) { return document.getElementById(id); }
but in some code like this:
oDiv1 = $("postInfoDiv");
oDiv2 = document.getElementById("postInfoDiv");
alert(oDiv1 == oDiv2); // return false
alert(oDiv1.style); // error
alert(oDiv2.style); // correct
alert(document.getElementById("postInfoDiv").style); // correct
I got strange results as the comments imply.
I thought the first alert should return the true since they are the same dom object.
I thought the second alert should alert something like "object" or "CSS StyleDeclaration" but not "defined".
So what are the problems? Have you ever met this kind of problems?
thanks.
Your $ function is probably being overridden, potentially by a framework.
You should try doing alert( oDiv1.nodeType ) to see if it's a DOM element. alert( oDiv1.length ) to see if it's an empty array because you may be using jQuery on the same page which overrides your $ function.
oDiv1 may be an array-like object containing that item if jQuery is included. oDiv2 is an actual DOM reference. You probably need to compare oDiv1[0] to oDiv1, in which you reference the first element in the array which points to the actual dom element to make a fair comparison.
function $(id){return document.getElementById(id)}
$('content') == document.getElementById('content')
true
The custom $ function will work perfectly but if you're using a framework function it will return that array-like object instead of the DOM element.
You can also rename your function to something like function getID which would be unique and not conflict with framework $s.
My main concern with this is that it will confuse the heck out of someone the first time they read your code, especially if they are used to coding with a JavaScript framework such as jQuery.
For this reason alone I recommend you do not use this particular syntax for your wrap function.
BTW note that even when jQuery is not loaded, Firebug provides its own $ function, which may participate to confusion.

Check if jQuery method exists

Is it possible? No matter how, in Javascript or jQuery.
For example: $.isFunction($.isFunction());
Upd: But how to check method of a jQuery plugin? Sometimes it not ready at the moment of it call and generates error. Example: $.isFunction($().jqGrid.format)
To pass a function to another function, leave the () off:
$.isFunction($.isFunction); // true!
When you write () you are calling the function, and using the result it returns. $.isFunction() with no argument returns false (because undefined isn't a function), so you are saying $.isFunction(false), which is, naturally, also false.
I wouldn't bother using isFunction merely to check for the existence of something, unless you suspect that someone might have assigned a non-function value to it for some reason. For pure existence-checking, use the in operator:
if ('isFunction' in $) { ...
Yes,
jQuery.fn.exists = function(){return jQuery(this).length>0;}
if ($(selector).exists()) {
// code........
}

Categories

Resources