How is this element accessible when not found with selector - javascript

In my company, some of the code accesses html elements purely by id, rather than document.getElementById or jQuery $("#id"). For example, if there is a select with an id of test they then use alert(test.selectedIndex) in the javascript and this works.
This breaks my model of how elements can be found / accessed in the DOM and I would have expected the alert to say that test was undefined. However, this works (and I have set up a fiddle to double check this). Can anyone please explain why elements can be accessed by their id, without any need for a getElementById / jQuery selector?
Many thanks.

See http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object (noting that 'globals' in javascript are just looked up from properties on the window object, so window[id] is exactly the same as just id, if id is not defined as a local variable)
This was previously non-standard behaviour, added by IE, that has now become part of the HTML5 spec.
In general I wouldn't recommend relying on it though because, as you've noticed, it can be quite confusing.

Related

Can't get access elements with querySelector?

I wish to access elements in a site with javascript and I have been using javascript for quite some time, especially with the querySelector functions. But for some reason, it won't work in this case; whenever I try to access any of the top-level elements, as illustrated below, no elements are found.
Does anyone have an idea about what the problem could be, and maybe even how to fix it?
That's normal,
It's because when you use the chrome developer console you can change the document context and in your screen you are inside the iframe.
You can see it here:

Scope of inline JavaScript vs script element [duplicate]

It is common for me to register javascript functions for certain events by doing something like:
myBtn.Attributes.Add("onClick", "Validate(getElementById('"+txtFirstName.ClientID + "'));");
I've always used getElementById by itself, or in other words, sans document being prepended to it. But I'm having pages break on me lately when I try to use getElementById instead of document.getElementById. Why is this? Oddly, I have a website where one page allows me to use just getElementById, but another other page throws a javascript error because it can't find the element if I do just getElementById, and it'll only work if I do document.getElementById.
Anyone know why this is? Should I be using document.getElementById everywhere, regardless of whether it works without the document prefix?
EDIT:
Could it have anything to do with the fact that one page is using AJAX and the other isn't?
When you use getElementById() and it works that mean that the function where it's called is running on the context of the document, that's is this == document.
So, you should ALWAYS use document.getElementById to avoid that kind of errors.
Anyway, I would even stop using getElementById altogether and start using JQuery, i'm sure you'll never regret it.
Your code would look something like this if you used JQuery:
$("#myBtnID").click(function () { Validate($("#myTextboxID"))});
Any function or variable you access without an owning object (ex: document.getElementById) will access the property from window.
So getElementById is actually window.getElementById, which isn't natively defined (unless you defined it before (ex: getElementById = document.getElementById).
You should use the full document.getElementById(). If you find that too verbose, you could use jQuery:
$('#' + id)
or you could create an alias at the top of your script:
var byID = document.getElementById;
You should only use document.getElementById (even if I'd recommend using libraries like prototype or jquery to be able to use the $ sign).
If you are able to use getElementById on its own, it's just because the browser you're using is doing some kind of trick to get it to work, but the correct way is to use the document variable.
I dont really know how to explain it but its because the getElementById() finds an element in the html structure of a page. Some browsers know that by default you want to search the document, but other browsers need that extra guidance hence document.
The correct way is indeed document.getElementById().
The reason (speculation) it might work by itself is that depending on where you use it the current context may in fact be the document object, thus inexplicitly resulting in document.getElementById().

Why $('div#my') is returning Object Reference instead of HTML Tag? [duplicate]

This question already has an answer here:
Why sometimes jQuery selector returns something like "a.fn.init"? [closed]
(1 answer)
Closed 6 years ago.
I don't know what happen to my Chrome browser, but all of sudden the behavior of doing $('div#my') in console is totally different from before. One time I've experienced this but later it somehow recovered, so I don't know how to reproduce it, and today it happened again.
Please watch the video:http://peaceevertvimg.org/jq.php.
In the video I do $('div#my') in two different browsers:
the first browser is not chrome but I believe it imitates Chrome so its behavior is what I expect and what I have almost always been experienced. Because currently my chrome is not working as expected so I have to use it to demonstrate my expection: when you do $('div#my)` you see directly the html TAG, and you can easily see the tag's html content, which is "something" in this case.
In contrast, in my chrome browser, the result is different, when I do $('div#my') I see an Object(n.fn.init), and I can't see the "something" immediately, which of course is very inconvenient. But before, I am pretty sure it was not like this, the behavior WAS exactly like that in the first browser.
The simple webpage in this video is http://peaceevertvimg.org/jquery.php, you can go test for yourself in chrome browser. And I am pretty sure most of you will see the first behavior. What happened to my chrome?(I've disabled all expansions and updated it to the latest version)
By the way, is "HTML Tag" and "Object Reference" the right words to describe these two different outcome?
*************Update*************
If the video is not sufficient to understand what I ask and what I want to fix, these two pictures may help.
Picture#1: This is the "normal" behavior I've expected:
Picture#2: This is the current behavior I am experiencing:
You can see the big differences, the first one is much more intuitive, revealing key information immediately, while the 2nd one is not, at least to me. What causes this problem and how do I go back to the first one?
$('div#my') doesn't return a DOM reference. It returns a jQuery wrapper around the found elements.
$('div#my')[0] would return a DOM reference. Or, forget jQuery and use:
document.getElementById("my");
...and you will get a DOM reference directly
Also, since there should/will only ever be one element with a given ID, it is unnecessary to use div#my, just use #my.
Assuming we have a <div id=someDiv>, and then we write:
console.log($("#someDiv"));
console.log($("#someDiv")[0]);
Chrome shows this:
In the first log, we see that the result is a jQuery object that contains one element (the div). In the second, we see the element directly.
Now, depending on what version of Chrome you have, you may see the first one reported simply as [Object object], but that doesn't change the underlying result.
From: Devx (http://www.devx.com/codemag/Article/40923)
Selectors let you select DOM elements so that you can apply
functionality to them with jQuery's operational methods. jQuery uses a
CSS 3.0 syntax (plus some extensions) to select single or multiple
elements in a document. You're probably already familiar with the CSS
syntax from HTML styling. Even if you're not, it's fairly easy to pick
up the key CSS selector features. I'll go as far as saying that jQuery
is the reason I really started to grok CSS. Using CSS syntax you can
select elements by ID, CSS class, attribute filters, or by their
relationship to other elements. You can even chain filter conditions
together. Look at this simple example, which selects all second-column
TD elements in a table using a simple selector: $("#gdEntries
td:nth-child(2)").
The jQuery Object: The Wrapped Set: Selectors return a jQuery object
known as the "wrapped set," which is an array-like structure that
contains all the selected DOM elements. You can iterate over the
wrapped set like an array or access individual elements via the
indexer ($(sel)[0] for example). More importantly, you can also apply
jQuery functions against all the selected elements. - See more at:
http://www.devx.com/codemag/Article/40923#sthash.l8Mo8CbH.dpuf
What you are seeing is said jQuery object returned by jQuery.fn.init().
What is going on is that jQuery() is being defined as jQuery.fn.init() which is another way to say jQuery.prototype.init() which is the selector function! What this means is that no one would call jQuery.fn.init() or jQuery.init() because jQuery() IS .init().
Some more info and a look at the jQuery code here: Help understanding jQuery's jQuery.fn.init Why is init in fn
As for a solution to your problem: https://chrome.google.com/webstore/detail/jquery-console-fix/jlmkkpkcgomkdpfhgjlpaaonhafnjgob?hl=en

document.formname.checkbox[0].checked versus document.getElementById('checkbox').checked

In Javascript, I usually use the syntaxdocument.formname.checkbox[0].checked, but I notice that almost everyone else uses document.getElementById('checkboxid').checked. My apologies if this seems a silly question, but I'm trying to find out if my preferred syntax has been deprecated, or do others simply use what is more convenient?
What each means:
document.formname.checkbox[0].checked
This uses the form's and the element's name= attribute to select the element you want. It's good because sometimes you don't want to dirty your markup with IDs everywhere, and you'd prefer to use names, which are something most forms has (because default submission uses names as keys).
The potential problems with that is that it's a bit verbose, and might not very readable.
document.getElementById('checkboxId').checked
This has the simplicity of just plugging an ID and getting the correct element, but then to get any element in the form, it must also have an ID, which can be pretty annoying.
document.querySelectorAll('#myForm input[type=checkbox]')[0].checked
Here's an alternative solution, which uses CSS selectors and document.querySelectorAll(), I feel that it's more readable, especially for people who are more proficient in CSS than in JavaScript.
Which of those is better? Depends on your particular use case and preference. I like to use querySelector and querySelectorAll, especially if I already have the form DOM object in a variable:
myForm.querySelector('input[type=checkbox]').checked;
It's up to you.
getElementById is preferred. Consider a webpage with the following contents:
<div id="x"></div>
You can access your div x in javascript with just console.log(x).
Now consider if you had var x = 5 defined in the global context. Well, now you can't use x to access your div before it now has a value of just 5.
getElementById is preferred because you don't have the potential to overwrite your selector with a variable for something else.
document.formname.checkbox[0].checked might not actually work on all Browsers. document.forms[0].elements and document.formName is standardized, as is document.getElementById()

Is using document.getElementsByTagName() a good idea or bad idea?

Ok so I am wondering which way is the preffered way to access a certain tag.
Is it better to use..
document.getElementById('myDiv').innerHTML
or this way..
document.getElementsByTagName('div')[0].innerHTML
// I use [0] because it is the first div in the body
My guess is that it doesn't matter at all which way i do it.
Absolutely the getElementById is better in that case. It's much faster.
Update
Here is a test about JavaScript selector functions. http://jsperf.com/queryselectorall-vs-getelementbyid/6
There are not many articles about performance of JavaScript selector functions. Instead there are many articles about jQuery selector performance like this or this. jQuery uses native JavaScript selector functions internally, so you can guess from these articles.
They do completely different things. If you want to get a particular element and you always need to get the same element, use an id. If you want to get a particular element based on what place it has in the DOM, then use the it's position in the getElementsByTagName NodeList.
If you want to get a particular element and you get it by index, then your script will be brittle - if you change your DOM structure later, you will need to change your code. If you want to get an element by it's position, then using an ID will require you to add redundant attributes to your markup.
Also, it is important to note that getElementById returns a DOM node, while getElementsByTagName returns a NodeList. To quote MDC on the properties of a NodeList:
NodeList is live, meaning that it updates itself automatically to stay in sync with the DOM tree without having to call document.getElementsByTagName again.
So if you need a particular element, getElementById will be significantly faster.
For readability purposes, it depends on what you're trying to do.
Is your intent to get the first div, which just happens to be named myDiv? if yes, then I think getElementsByTagName is better, as it would more express what you're trying to do.
Or is your intent to get myDiv, which just happens to be the first div? If that's the case, then use getElementById.
All other considerations aside, go with the one that expresses your intent.

Categories

Resources