Reputation: 4388
I am working on an old application for migrating it to Firefox from IE8/9. It should be compatible on both. As its a very old application, it does not uses jQuery. Client does not want to add jQuery also to this page. I found a strange issue. Here is the example in simple form:
<html>
<head>
<script>
function test(){
console.log(event);
}
</script>
</head>
<body >
<button onclick="test()">Test</button>
</body>
</html>
When I click on the Test
button Firefox show an error that there is no event
defined where as IE there is a default event it shows. My application uses this event object a lot. Any one having any idea how I can get this in Firefox?
Upvotes: 1
Views: 379
Reputation: 147453
Your code is dependent on the IE event model, which creates a global window.event object for each event. It is deprecated in favour of the W3C event model (supported by Firefox and others), but still supported in IE for backward compatibility.
You need to pass the event object to the function:
<button onclick="test(event)">Test</button>
then in the function:
function test(event){
alert(event);
}
If you attach the listener using addEventListner, the event object is passed to the listener as the first argument by default:
document.querySelector('#buttonID').addEventListener('click', test, false);
You can also add listeners directly as properties:
document.querySelector('#buttonID').onclick = test;
which passes the event object as the first parameter in the W3C event model, but not in IE so the function must test and use window.event if event is undefined:
function test(event){
event = event || window.event;
console.log(event);
}
A very simple function to add a listener that works in all browser is:
function addEvent(element, event, fn) {
if (element.addEventListener) {
element.addEventListener(event, fn, false);
} else if (element.attachEvent) {
element.attachEvent('on' + event, fn);
}
}
Note that in IE, this will not be set to the element that called the event. If you need to fix that, then the following will do that:
function addEvent(element, evt, fn) {
if (element.addEventListener) {
element.addEventListener(evt, fn, false);
} else if (element.attachEvent) {
element.attachEvent('on' + evt, function() {
fn.call(element, event);
});
}
}
And use it like:
addEvent(document.getElementById('buttonID', 'click', test);
There are more sophisticated versions, but the above should suffice. It creates unnecessary circular references though, you might want to avoid those. To do that, you need something like:
function addEvent(element, evt, fn) {
if (element.addEventListener) {
element.addEventListener(evt, fn, false);
} else if (element.attachEvent) {
element.attachEvent('on' + evt, (function(fn, element) {
return function() {
fn.call(element, event);
};
}(fn, element)));
}
// Remove obvious circular reference
element = null;
}
The bottom line is that in the vast majority of cases, adding listeners as properties is simple, cross browser and sufficient. It only falls down if you need to add more than one listener to an element for the same event, but even that is fairly easily accommodated.
Upvotes: 4
Reputation: 193291
There is a cross browser difference in implementation. IE used (and still uses) window.event
object, while Firefox never implemented it this way. Instead Firefox supported passing event object into event handler. Try this:
function test(event) {
console.log(event);
}
and in HTML:
<button onclick="test(event)">Test</button>
As the another possibility, since you have to support IE8, you could go with registering event as a property by directly assigning onclick
function:
buttonObject.onclick = test;
where buttonObject
is a reference to button HTMLElement obtained with some DOM method (document.getElementById
, document.querySelector
, etc).
Note, that in this case test function needs to use event fallback for window.event
object (to make IE8 happy):
function test(event) {
event = event || window.event;
console.log(event);
}
||
operator makes sure event will be populated properly: in Firefox and IE9+ event
argument will be available, and in IE<9 event
parameter will be undefined and window.event
will be used.
Upvotes: 3