Reputation: 5061
I had a function in which I had to attach event on an element newElement
I checked the condition whether its IE or Firfox based on attachEvent
property (works only in IE).
if ( typeof(newElement.attachEvent) != "undefined" )
{
newElement.attachEvent("onclick", deleteRow) ;
newElement.attachEvent("onclick", customDeleteScript) ;
}else
{
newElement.addEventListener("click", deleteRow, false) ;
newElement.addEventListener("click", customDeleteScript, false) ;
}
The required flow was deleteRow
to execute first followed by customDeleteScript
It is working fine in Firefox/Chrome but the flow changes in IE customDeleteScript
executes before deleteRow
in IE. So I had to do as follows:
if ( typeof(newElement.attachEvent) != "undefined" )
{
newElement.attachEvent("onclick", customDeleteScript) ;
newElement.attachEvent("onclick", deleteRow) ;
}else
{
newElement.addEventListener("click", deleteRow, false) ;
newElement.addEventListener("click", customDeleteScript, false) ;
}
The question here lies is this property of IE or it is just a random hit and trial kind of scenario for IE always?
EDIT: What in case my function contains some parameters like this
and others and I don't know which function takes which parameters.
Upvotes: 0
Views: 105
Reputation: 146191
If you want to execute the customDeleteScript() function after deleteRow() has been executed than you can simply add a return true statement at the end of the deleteRow() function like
function deleteRow()
{
// other code
return true;
}
and call customDeleteScript() like
if(deleteRow()) customDeleteScript();
You can use jfriend00's answer for event registering, it's more dynamic and registering two separate event handlers for that reason (as you described in your question) is not an appropriate way.
Update: After some research I've found that IE fires registered event handlers "last in first out(in reverse order)" for an element which has multiple events. Try this fiddle in both IE and Chrome/FF. For example
function addEventHandler(to_element,event,handler)
{
if (to_element.addEventListener) to_element.addEventListener(event,handler,false);
else if (to_element.attachEvent) to_element.attachEvent("on"+event,handler);
else return false;
}
function function1()
{
alert("first alert");
}
function function2()
{
alert("second alert");
}
var obj=document.getElementById('obj');
addEventHandler(obj,"click",function1);
addEventHandler(obj,"click",function2);
In Chrome function1 will be fired first and then function2 will be fired but in IE function2 will be fired first and then function1 (reverse order). So according to the question I think only one event should be registered and call both functions in the same handler like
function deleteRow()
{
// other code here
return true;
}
function customDeleteScript()
{
// code here
}
addEventHandler(obj,"click",myHandler);
function myHandler()
{
if(deleteRow()) customDeleteScript();
}
Upvotes: 1
Reputation: 104770
the order of events attached with attachEvent to the same element and type is not guaranteed to be the order in which they are declared. This is not the behavior of addEventListener, which does execute in the declared order. If the order is important, you may have to call the second function from the first, or combine them into one.
Another difference is attachEvent will attach the same handler as many times as it is called, so that the same function can be called many times instead of only once. addEventListener only assigns it once, no matter how many times you call it with the same arguments.
Since IE9+ does support addEventListener, change the order of your assignment, and account for multiple assignments (it does no harm to attempt to delete a nonexistant handler):
if (newElement.addEventListener ){
newElement.addEventListener("click", deleteRow, false) ;
newElement.addEventListener("click", customDeleteScript, false) ;
}
else if(newElement.attachEvent){
newElement.detachEvent("onclick", customDeleteScript) ;
newElement.detachEvent("onclick", deleteRow);
newElement.attachEvent("onclick", customDeleteScript) ;
newElement.attachEvent("onclick", deleteRow) ;
}
Upvotes: 0
Reputation: 707288
If order is important, you should not use separate event handlers. Call both functions in the desired order from one event handler like this:
function delete() {
deleteRow();
customDeleteScript();
}
if ( typeof(newElement.attachEvent) != "undefined" )
{
newElement.attachEvent("onclick", delete) ;
}else
{
newElement.addEventListener("click", delete, false) ;
}
FYI, a generic event handler function that you can reuse works like this:
function addEvent(elem, event, fn) {
if (elem.addEventListener) {
elem.addEventListener(event, fn, false);
} else {
elem.attachEvent("on" + event, function() {
// set the this pointer same as addEventListener when fn is called
return(fn.apply(elem, arguments));
});
}
}
Note, it's better to check for addEventListener
first so if both methods exist (like in IE9), your code will use the standard way.
So, your code can work like this:
addEvent(newElement, 'click', function() {
deleteRow();
customDeleteScript();
});
Upvotes: 1
Reputation: 4180
you can solve it by putting those two handlers in one function and set that one function as the handler:
function handler() {
deleteRow();
customDeleteScript();
}
if (typeof(newElement.attachEvent) != "undefined") {
newElement.attachEvent("onclick", handler) ;
} else {
newElement.addEventListener("click", handler, false) ;
}
Upvotes: 0