Directly reference HTML elements [duplicate] - javascript

This question already has answers here:
Why don't we just use element IDs as identifiers in JavaScript?
(5 answers)
Closed 8 years ago.
Possible Duplicate:
IE/Chrome: are DOM tree elements global variables here?
why window[id] === document.getElementById( id )
I've just come across something in html/javascript which has surprised me a bit. When obtaining a reference to an html element, using javascript, I have always previously used either jQuery or document.getElementById. It also appears that you can directly access a element simply by using it's id. Can someone explain the nuances of this? I've googled but cannot find any reference to this ability, every site talks about getElementById.
The following page snippet illustrates this.
<html>
<head>
</head>
<body>
<input type="button" value="getElement" onclick="document.getElementById('blah').innerText = 'getElementById'" />
<input type="button" value="direct" onclick="blah.innerText = 'direct';" />
<div id="blah"></div>
</body>
Many thanks in advance.

Being able to select elements on the page based on their [id] is a "feature" from early JavaScript (DOM lvl 0 or 1 methinks, can't seem to find the source).
Unfortunately it's a temperamental feature. What would happen if you had:
<div id="window"></div>
or
<div id="document"></div>
Better yet, what happens here?
<div id="foo"></div>
<div id="bar"></div>
<script>var foo = document.getElementById('bar');</script>
So the nuances to calling an element based on it's [id] is simply this:
Don't use it.
It's not consistent, and not guaranteed to receive future support.
Personally I'd like to see this "feature" go the way of document.all. It only causes more issues than it solves, and document.getElementById, while certainly verbose, is meaningful and understandable.

Using getElementById is more flexible and readable. For instance, this won't work:
<input type="button" value="direct" onclick="document.innerText = 'direct';" />
<div id="document"></div>
for obvious reasons, but this will:
<input type="button" value="getElement" onclick="document.getElementById('document').innerText = 'getElementById'" />
<div id="document"></div>
and it's more clear to other developers what's really going on.

I don't believe it's a documented feature, and it doesn't appear to work in Firefox (6), but it appears to work in the latest version of Chrome, as well as IE 6-9.
I wouldn't rely on it, and would just consider it one of the oddities of browsers features.

Related

Why does JQuery .val() method sometimes return undefined when code is valid? [duplicate]

This question already has answers here:
val() vs. text() for textarea
(2 answers)
Closed 4 years ago.
Not a duplicate question; so please consider the content closely before presumption.
I've been using JQuery for years and have never seen this type of behavior before. Consider the following:
<html>
<div class="order-form-group">
<label class="order-form-label" for="guestSpecialInstructions">Special Instructions:</label>
<textarea class="order-form-textarea" id="guestSpecialInstructions" type="text"></textarea>
</div>
<div class="order-form-group">
<label class="order-form-label" for="guestReason">Reason:</label>
<textarea class="order-form-textarea" id="guestReason" type="text"></textarea>
</div>
<div class="button-container">
<input class="order-form-submit" type="submit" value="Submit">
</div>
</html>
I've observed that the following script in some instances will return 'undefined' even when "all" the more obvious reasons have been eliminated. Such as
having the incorrect selector, having more than 1 id on the page and etc.
<script>
var specInstr = $("#guestSpecialInstructions").val();
var guestReason = $("#guestReason").val();
</script>
I spent literally hours attempting to determine what the disconnect was; stripping my code to the simplest basic level and couldn't find any reasonable explanation for the behavior.
The code is contained within a simple HTML page; nothing fancy and references the JQuery repository https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
I have another project which runs in an aspx page, still the markup is identical and the .val() method works without issue.
After hours of hitting a wall I ran across the post at JQuery: .val() is not working for textarea and someone else attesting to the exact same issue using valid code and the suggestion was:
<script>
var specInstr = $("#guestSpecialInstructions")[0].value;
var guestReason = $("#guestReason")[0].value;
</script>
Then the issue is automagically resolved. Only problem I have with this is that there no one seems to have answered the question of why the JQuery .text() method sometimes return undefined when all aspects of the code is valid.
Resolutions are great but without understanding why the issue exists, really gains nothing intellectually.
If I need to change the wording of the title, let me know.
You can only use text() on a <textarea> if it is pre-populated and to return the original content
Any changes to the content by user or setting new value programatically will not alter what is returned by text() as it will always be the original pre-pre-populated content
Always use val() to get and set
var $txt = $('textarea')
console.log('text() Original content:', $txt.text())
console.log('val() Original content:', $txt.val())
$txt.val( 'Some new content')
console.log('text() after value change:', $txt.text())
console.log('val() after value change:', $txt.val())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="one" type="text">
Original text
</textarea>

Access from input directly from id [duplicate]

This question already has answers here:
Why don't we just use element IDs as identifiers in JavaScript?
(5 answers)
Closed 8 years ago.
Possible Duplicate:
IE/Chrome: are DOM tree elements global variables here?
why window[id] === document.getElementById( id )
I've just come across something in html/javascript which has surprised me a bit. When obtaining a reference to an html element, using javascript, I have always previously used either jQuery or document.getElementById. It also appears that you can directly access a element simply by using it's id. Can someone explain the nuances of this? I've googled but cannot find any reference to this ability, every site talks about getElementById.
The following page snippet illustrates this.
<html>
<head>
</head>
<body>
<input type="button" value="getElement" onclick="document.getElementById('blah').innerText = 'getElementById'" />
<input type="button" value="direct" onclick="blah.innerText = 'direct';" />
<div id="blah"></div>
</body>
Many thanks in advance.
Being able to select elements on the page based on their [id] is a "feature" from early JavaScript (DOM lvl 0 or 1 methinks, can't seem to find the source).
Unfortunately it's a temperamental feature. What would happen if you had:
<div id="window"></div>
or
<div id="document"></div>
Better yet, what happens here?
<div id="foo"></div>
<div id="bar"></div>
<script>var foo = document.getElementById('bar');</script>
So the nuances to calling an element based on it's [id] is simply this:
Don't use it.
It's not consistent, and not guaranteed to receive future support.
Personally I'd like to see this "feature" go the way of document.all. It only causes more issues than it solves, and document.getElementById, while certainly verbose, is meaningful and understandable.
Using getElementById is more flexible and readable. For instance, this won't work:
<input type="button" value="direct" onclick="document.innerText = 'direct';" />
<div id="document"></div>
for obvious reasons, but this will:
<input type="button" value="getElement" onclick="document.getElementById('document').innerText = 'getElementById'" />
<div id="document"></div>
and it's more clear to other developers what's really going on.
I don't believe it's a documented feature, and it doesn't appear to work in Firefox (6), but it appears to work in the latest version of Chrome, as well as IE 6-9.
I wouldn't rely on it, and would just consider it one of the oddities of browsers features.

Is using custom HTML tags and replacing custom tags with outerHTML okay?

Is it alright to define and use custom tags? (that will not conflict with future html tags) - while replacing/rendering those by changing outerHTML??
I created a demo below and it seems to work fine
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<script type="text/javascript" src="jquery.min.js"></script>
</head>
<body>
<div id="customtags">
<c-TextField name="Username" ></c-TextField> <br/>
<c-NameField name="name" id="c-NameField"></c-NameField> <br/>
<c-TextArea name="description" ></c-TextArea> <br/>
<blahblah c-t="d"></blahblah>
</div>
</body>
<script>
/* Code below to replace the cspa's with the actual html -- woaah it works well */
function ReplaceCustomTags() {
// cspa is a random term-- doesn;t mean anything really
var grs = $("*");
$.each(grs, function(index, value) {
var tg = value.tagName.toLowerCase();
if(tg.indexOf("c-")==0) {
console.log(index);
console.log(value);
var obj = $(value);
var newhtml;
if(tg=="c-textfield") {
newhtml= '<input type="text" value="'+obj.attr('name')+'"></input>';
} else if(tg=="c-namefield") {
newhtml= '<input type="text" value="FirstName"></input><input type="text" value="LastName"></input>';
} else if(tg=="c-textarea") {
newhtml= '<textarea cols="20" rows="3">Some description from model</textarea>';
}
obj.context.outerHTML = newhtml;
}
z = obj;
});
}
if(typeof(console)=='undefined' || console==null) { console={}; console.log=function(){}}
$(document).ready(ReplaceCustomTags);
</script>
</html>
Update to the question:
Let me explain a bit further on this. Please assume that JavaScript is enabled on the browser - i.e application is not supposed to run without javascript.
I have seen libraries that use custom attributes to define custom behavior in specified tags. For example Angular.js heavily uses custom attributes. (It also has examples on custom-tags). Although my question is not from a technical strategy perspective - I fail to understand why it would strategically cause problems in scalability/maintainability of the code.
Per me code like <ns:contact .....> is more readable than something like <div custom_type="contact" ....> . The only difference is that custom tags are ignored and not rendered, while the div type gets rendered by the browser
Angular.js does show a custom-tag example (pane/tab). In my example above I am using outerHTML to replace these custom tags - whilst I donot see such code in the libraries - Am I doing something shortsighted and wrong by using outerHTML to replace custom-tags?
I can't think of a reason why you'd want to do this.
What would you think if you had to work on a project written by someone else who ignored all common practices and conventions? What would happen if they were no longer at the company to find out why they did something a certain way?
The fact that you have to just go through with JavaScript to make it work at all should be a giant red flag. Unless you have a VERY good reason to, do yourself a favor and use the preexisting tags. Six months from now, are you going to remember why you did things that way?
It may well work, but it's probably not a good idea. Screen readers and search engines may have a hard/impossible time reading your page, since they may not interpret the JavaScript. While I can see the point, it's probably better to use this template to develop with, then "bake" it to HTML before putting it on the server.

Why can only forms be referenced by dot notation?

It seems like a simple beginners question, but I'm unable to find an answer anywhere.
Let's say I have this HTML:
<form name="myForm">
<input type="text" name="myTxt">
</form>
then I can use the following javascript
document.myForm.myTxt.value = 'foo';
But what if I have a div instead of a form?
<div name="myDiv">
<span name="mySpan"></span>
</div>
Why can't I do the same thing here, like
document.myDiv.mySpan.innerHTML = "bar";
Seems like it should be possible to do, instead of having to use getELementById(), but I can't make it work.
As designed by W3C.
There's really nothing to argue about. You can access the an HTMLCollection of all the forms on the page through document.forms, much like you can images with document.images, applets with document.applets, links with document.links and anchors with document.anchors.
http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-1689064
The syntax you've posted is for form, to be specific.. It will work only with forms..
You will need to use following line to make it work for divs...
document.getElementsByName("myDiv")[0].getElementsByTagName("span")[0].innerHTML = "bar";
There are other ways to do this too...

Can't fire click event on the elements with same id

Could you help me to understand - where I made the mistake. I have the following html code:
<div id="container">
Info mail.ru
</div>
<div id="container">
Info mail.com
</div>
<div id="container">
Info mail.net
</div>
and the following js code (using jQuery):
$('#getInfo').click(function(){
alert('test!');
});
example here
"Click" event fired only on first link element. But not on others.
I know that each ID in html page should be used only one time (but CLASS can be used a lot of times) - but it only should (not must) as I know. Is it the root of my problem?
TIA!
upd: Big thx to all for explanation!:)
Use a class for this (and return false in your handler, not inline):
<div id="container">
Info mail.ru
</div>
<div id="container">
Info mail.com
</div>
<div id="container">
Info mail.net
</div>
$('.getInfo').click(function(){
alert('test!');
return false;
});
http://jsfiddle.net/Xde7K/2/
The reason you're having this problem is that elements are retrieved by ID using document.getElementById(), which can only return one element. So you only get one, whichever the browser decides to give you.
While you must, according to the W3 specifications, have only one element with a given id within any document, you can bypass this rule, and the issues arising from the consequences if document.getElementById(), if you're using jQuery, by using:
$('a[id="getInfo"]').click(function() {
alert('test!');
return false;
});
JS Fiddle demo.
But, please, don't. Respect the specs, they make everybody's life easier when they're followed. The above is a possibility, but using html correctly is much, much better for us all. And reduces the impact of any future changes within the browser engines, jQuery or JavaScript itself.
It must only be used once or it will be invalid so use a class instead, return false can also be added to your jQuery code as so: -
$('.getInfo').click(function(){
alert('test!');
return false;
});
<a href="#info-mail.net" **class**="getInfo" ....
First id's are for one element only, you should have same id for several divs.
you can make it class instead.
your example changed:
<div class="container">
<a href="#info-mail.ru" class="getInfo" >Info mail.ru</a>
</div>
<div class="container">
<a href="#info-mail.com" class="getInfo" >Info mail.com</a>
</div>
<div class="container">
<a href="#info-mail.net" class="getInfo" >Info mail.net</a>
</div>
$('.getInfo').click(function(ev){
ev.preventDefault(); //this is for canceling your code : onClick="return false;"
alert('test!');
});
You can use the same id for several element (although the page won't validate), but then you can't use the id to find the elements.
The document.getElementById method only returns a single element for the given id, so if you would want to find the other elements you would have to loop through all elements and check their id.
The Sizzle engine that jQuery uses to find the elements for a selector uses the getElementById method to find the element when given a selector like #getInfo.
I know this is an old question and as everyone suggested, there should not be elements with duplicate IDs. But sometimes it cannot be helped as someone else may have written the HTML code.
For those cases, you can just expand the selector used to force jQuery to use querySelectorAll internally instead of getElementById. Here is a sample code to do so:
$('body #getInfo').click(function(){
alert('test!');
});
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>
<body>
<div id="container">
Info mail.ru
</div>
<div id="container">
Info mail.com
</div>
<div id="container">
Info mail.net
</div>
</body>
However as David Thomas said in his answer
But, please, don't. Respect the specs, they make everybody's life easier when they're followed. The above is a possibility, but using html correctly is much, much better for us all. And reduces the impact of any future changes within the browser engines, jQuery or JavaScript itself.

Categories