Check out this fiddle (partial code snippet below): http://jsfiddle.net/QJJb8/
<button id='mybutton'>MY BUTTON</button>
mybutton.addEventListener('click', mybuttonClick, false);
function mybuttonClick(e){
alert(e.target.textContent+' WAS CLICKED!');
}
Note how I'm not using getElementById() to get a reference to the button. Why does it still work? (Tested in Firefox, Chrome and IE9 & 10.)
Is it bad-practice/quirk, or is it built in functionality for button elements? If the latter, that's an awesome perk/shortcut when using button elements! Or perhaps I've just been over-using getElementById() all this time?
//ANSWER UPDATE//////////////////////////////////////////////////////////////////////
After some research it seems the behavior discussed above is in fact part of the HTML5 spec. In addition to RobG's answer below, see also the following links for more insight:
http://tjvantoll.com/2012/07/19/dom-element-references-as-global-variables/
https://stackoverflow.com/a/3434388/2434324 (link supplied by yoelp)
http://jsperf.com/named-access-on-the-window-object
Because way back at the begining of browser scripting, IE decided to make element names and IDs global variables that referenced the element. Everyone else thought that was a bad idea (it was) and didn't do it.
However, IE grabbed about 95% of the browser market and developers developed for IE's quirks, so other browsers implemented the same behaviour but didn't advertise it (same with support for document.all). So now all browsers do it, but (almost) no one uses it.
Except when someone stumbles across it…
So where you have:
<button id='mybutton' ...>
browsers create a global mybutton variable that references the element.
This works on all DOM elements, not only buttons, Its probably a bad practice since any one may change mybutton to something else (ie.mybutton = "BLABLA") then your code breaks
also see this
Related
I have a form which submits via ajax to the back-end and I'm writing a general disable function in javascript that I can use to set the onclick of an element. Typing this into the browser so ignore any syntax errors in the following.
function(elementID , processingText) {
var element = document.getElementById(elementID);
if (element) {
element.setAttribute("onClick", "alert('test')");
}
}
So basically the element should have an onclick event to set an alert. I can confirm that the onclick attribute is being set correctly and it fires in IE8+, Chrome and Firefox. It will not fire in IE7.
The element I'm testing on is a submit button in a form (one form on the page). It has many fields and one submit button.
EDIT The code dispatches with an action so it should submit anyway but not until after the alert has been acknowledged /EDIT
I've trawled the net for the past two hours and the following solutions do not work or are not an option-
Add a hidden input field to form.
Wrap submit button in tag and set the onclick in this tag.
Changing case of onclick to onClick
Any solutions which involve altering the html without using javascript are not an option, I'm trying to create a general disableElement function. I can target the script at IE7 so it does not have to work in all browsers, just IE7.
Any help would be greatly appreciated
IE7 has a lot of compatibility issues, of which this is just one. If you're writing javascript that needs to be compatible with IE7, you will end up writing a lot of redundant code that does the same thing in two different ways to cater for different browsers you're supporting.
Issues like this in old browsers are precicely the reason why libraries like jQuery exist. jQuery does a lot of things, but one thing it does very well is iron out many of these nasty little quirks that crop up when writing cross-browser javascript.
The cross-browser issues have become less important in recent years, as modern browsers (including IE) have much better standards support, but if you're supporting old browsers , and old IE versions in particular, my recommendation is to use jQuery (or a similar library), because they have already solved this problem, and plenty of others that will catch you out.
If you do use jQuery, your code will become:
$(element).click(function() {alert('test');});
Before anyone points it out, yes I know the OP didn't specify jQuery in the question, and may not want a jQuery answer, but in this case I would say it is the best answer available, because if you don't use it, you will end up having to write much of the same compatibility code yourself that is already in jQuery.
IE 7 does support setAttribute method but it seems that it is not possible to change an onclick attribute with it. For more info about this issue check this: Why does an onclick property set with setAttribute fail to work in IE?
Cheers
I'm working on a website which was coded a while ago.
I've found a Javascript function that uses the following syntax to set a value for a text box
document.myForm.myText.value = "value";
I've tested this code and it works in IE, Firefox and Chrome.
My question is whether this way of setting/selecting DOM elements is ok going forward (ie. is it going to get depreciated)? Should I change instances of this type of element selecting to the more standard (in my experience) code below?
document.getElementById("myText").value = "value";
Thanks in advance.
I don't think it'll make a difference cause the browsers dom representation will have change to break the code; That'll probably break half the web pages on the internet.
Your code is better than the first because you will then be coding to the contract of the method getElementById, which returns the HTMLElement you need. This means that the JS Engine has to adhere to the standards of ECMAScript and return the exact element. Hence your code doesn't need to worry if tomorrow a browser changes it's structure and your element is now document.forms.myForm.myText.value instead of what you anticipated.
I've seen several threads about reading contents, but nothing on writing to noscript.
$('body').append('<noscript><div></div></noscript>');
In Chrome and IE9 I get a noscript-element with a empty div inside like I expect, but in IE7 and IE8 I just get a empty noscript-element without the div inside.
Example: http://jsfiddle.net/cEMNS/
Is there a way to add HTML inside the noscript-tag that works in all browsers? What I need is to add some tracking code into a noscript-element at the end of the page, but the info I need isn't available until after document ready.
Edit: I'm getting a lot of comments on "why". It's some poorly done tracking library that requires this. We don't have access to the code to change it. Regardless, I find it interesting that it works in some browsers and not in others since jQuery was supposed to work equally in all browsers. Is it simply a bug?
Edit2: (2 years later) Adding a noscript on the browser doesn't make sense, I know. My only excuse not the question the task I had was because of lack of sleep, like everyone else in the project. But my rationale was that jQuery should behave the same on all browsers and someone might want to do this on the server.
Regardless of the tracking code, what you are doing (or are required to do) makes no sense!
Why? There are two cases possible here:
user has JavaScript enabled in which case the NOSCRIPT get's inserted into the DOM but is ignored by the browser (does nothing)
user does not have JavaScript enabled, NOSCRIPT does not get inserted and does not "execute"
The end result of both cases is that nothing actually happens.
Just an idea: You could try giving your noscript tag an ID, and then try to use native js.
for example:
$('body').append('<noscript id="myTestNoScript"></noscript>');
document.getElementById('myTestNoScript').innerHTML = '<div></div>';
I would claim that if it does not work with native js, it will not work with any library (feel free to correct me on this one).
I tried following simple HTML code:
<html>
<body>
<noscript>I'm a noscript tag.</noscript>
</body>
</html>
Then I did analyse this with IE8 (in IE7 mode) and his integrated code insprector. Apparently the IE7 checks are script allowed. If so he declared it as empty. And empty tags will be ignored. Unfortunatly I could not try that with disabled script option, because only the Systemadministrator can change the settings (here at my work).
What I can assure you, the noscript does exists. If you add
alert($('noscript').size());
after the creation, the result will be 1.
The following piece of code, works correctly in Firefox and Chrome, but it gives me a headache in IE.
var anotherDiv= document.getElementById("anotherDiv");
var destination = document.getElementById("mySourceDiv");
destination.appendChild(anotherDiv);
I'm trying to get a Div element and place it inside another div.
I get an error message (in the debug console in IE) similar to "interface not supported", and points me to the appendChild line.
What I've seen is that the type of the destination variable is an object rather then a DOM element.
What can I do to append the anotherDiv to mySourceDiv?
I'm trying this in IE 8.
You probably will need something like an importNode, there are various cross browser solutions around. The issue is that each node has a corresponding document object on it, in IE and so called security doesn't play nice moving things from one document to another.
So, essentially it's doing a deep clone, but the difference between using cloneNode is that cloneNode also sets the document which you don't want.
This might get you going in the right direction:
IE support for DOM importNode
I'd recommend using a library designed to sort through the browser incompatibilities for you. I've personally found jQuery to be quite good. jQuery has an append function.
I have the following:
Test
When run in Chrome, it functions as expected and turns the page red. However, in Opera I get:
[object Object]
Closer inspection reveals that Opera thinks that javascript:Query('body')... is some kind of URL. What am I doing wrong? Doesn't Opera recognize javascript: links in the href attribute?
jsFiddle: http://jsfiddle.net/9CZZL/
Edit: seems to be a Firefox problem too...
The issue is that the return value of jQuery('body').css('backgroundColor','red') is an object, which some browsers interpret as the new content for the web page. To fix this, you can use the JavaScript void operator to turn it into undefined, which FF and Opera (and potentially others) will handle as you intended. You will notice that this issue is also described on that page, since it's the premier use-case of the void operator (other than code golf where void 0 is less characters than undefined).
Test
This should give the intended result: http://jsfiddle.net/9CZZL/13/
It should be noted that handling clicks this way is considered bad practice. Instead, using event handlers in JavaScript is recommended. This helps separate the different layers of your web app, which in turn will make debugging in the future easier.
I just did a google search and no, apparently Opera does not recognise "javascript:" href values. You would have to implement an onClick or similar solution.
Does it in Firefox too.... not quite sure why. But I never liked putting JavaScript right in the URL... you could try putting it in the onclick event or pull the whole thing out and separate it:
http://jsfiddle.net/mnbayazit/6d5An/
These all work as href values for me in Opera 10.1:
javascript:void(0)
javascript:alert("Hello")
javascript:window.location.href = 'http://www.google.com'
Your snippet does not though.
A viable work around is:
Test
Or even:
Test
...since that seems to work.