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

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()

Related

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

How is this element accessible when not found with selector

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.

Is there a better way to do innerHTML?

I want to know if there is a better way to be doing innerHTML than what I do here. The way I am doing it is causing problems because of the fact that I can't have triple nested quotes. along side that, it is really hard to look at and manage. Thanks!
function buttonClicked(buttonValue)
{
switch (buttonValue)
{
case 1:
soundFolders.innerHTML = "<li onClick='buttonClicked(11);'>Thunder 1</li> <li onClick='buttonClicked(13);'>Light Rain 1</li> <li onClick='buttonClicked(0);'>Back</li>";
break;
case 11:
if(!thunder1Control)
{
thunder1.play();
var thunder1Control = document.createElement("li");
soundList.appendChild(thunder1Control);
thunder1Control.innerHTML = "<h3>Thunder 1</h3> <button class='stopSound' onClick='thunder1.pause(); thunder1.currentTime=0; thunder1Control.parentNode.removeChild(thunder1Control); '>X</button> <button class='volDown' onClick='thunder1.volume -= 0.25;'>-</button> <button class='volUp' onClick='thunder1.volume += 0.25;'>+</button>";
thunder1Control.setAttribute("class", "playingSound");
}
P.S. Do you guys know why the thunder1Control.parentNode.removeChild(thunder1Control) is not working?
To your first question about another way to approach this type of code, "best" is a matter of opinion so I won't really try to address what is best. But, I will give you some alternatives:
Avoid putting code into strings in your HTML. There are all sorts of limitations with that and you generally want to separate code from presentation anyway.
Install event handlers in your code with obj.addEventListener() instead of putting event handlers and code in your HTML.
Use classes and IDs or DOM queries from a particular point in the hierarchy to retrieve specific objects in your page rather than trying to save references to them in global variables. In plain javascript, element.querySelectorAll() is pretty powerful.
In many cases, it's much simpler to just hide and show blocks of HTML using obj.style.display = "none" and obj.style.display = "block" than it is to dynamically create and destroy HTML and this has the added advantage of the HTML is all specified in the page and doesn't have to be shoehorned into a javascript string.
For large blocks of dynamic HTML that wouldn't work well with hide/show for whatever reason, you can dynamically load snippets/templates of HTML from your server using ajax or you dynamically create the HTML using javascript. My first preference is generally hide/show and then if that isn't practical for some reason, it depends upon how much the HTML I want to insert varies based on the state for whether I'd rather load a template or create it dynamically using javascript. If you have large blocks of HTML you have to fit in your javascript, it is messy with quoting, etc... - no way around that if you go that route other than using one quoting scheme for the JS string delimiter and the other in your HTML.
In your particular case, it sure looks like the hide/show method would be simple.
To your second question, this line of code:
thunder1Control.parentNode.removeChild(thunder1Control)
does not work because the thunder1Control variable is long, long out of scope when your click handler is executed because it's a local variable in your buttonClicked() clicked function.
When you put code into a string as part of HTML, it is evaluated in the global scope only so any variables that it tries to reference, must themselves be global in scope.
I'd suggest that you NOT put code into strings in your HTML like that. Use references to actual javascript functions. In that particular case, I'd have to see your HTML to know how to best advise you. If there is only ever one thunder1Control, then I'd suggest you just put an id value on it and retrieve it with document.getElementBtId() when you need it rather than trying to save a reference to it in a variable.
There are essentially two other ways that I can see:
Use a framework that helps with this kind of things. Others have
mentioned jQuery. A commenter is arguing that it might be overkill
to include a framework for just this. I would argue that if you're
doing any javascript at all, you should be using a framework to
make it less terrible. But continue onto suggestion 2 if you
disagree!
You can create each of the elements via plain old javascript and append it to the elements that you need, instead of inserting it directly into innerHTML. ex.
var li = document.createElement("li");
soundFolders.appendChild(li);
etc...
But, honestly, use jQuery with some of the suggestions from others. It's pretty small, and it will heavily clean up all of your javascript. Include it via Google and it will likely already be cached in the users browser.
https://developers.google.com/speed/libraries/devguide#jquery
I think a better alternative is to use jQuery, and then instead of using .html() (equivalent of innerHTML in jQuery), you can create a template with your html and use .load() instead. Works nicer and it's cleaner. And you don't have to worry about triple nesting quotes as you said.
Edit: I'm not sure why I'm getting downvoted so much here... The poster doesn't want to worry about triple nesting quotes. A simple and, to me, elegant solution is to use .load() and to create a template, rather than a really long string of html...

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.

$(element).data("dataAtribute") vs $(element).hasClass("className")

Which is quicker in jQuery?
$(element).data("dataAtribute");
or
$(element).hasClass("className");
My first guess was .hasClass since it doesn't have to work with custom attributes, but checks the native .className attribute.
According to this test I am right. But didn't think it would be THAT much (~90%) of a difference though.
Checking these methods in the source (see src/data.js and src/attributes.js) makes it quite clear.
Try it and see - especially as this is so simple. Please report back with your findings too.
I would guess that data() is quicker as it's directly checking an attribute, as opposed to having to search the class attribute for a value.

Categories

Resources