/    Sign up×
Community /Pin to ProfileBookmark

Is there a way to change the order of execution of event handlers?

Is there a way to change the order of execution of event handlers? ?

to post a comment
JavaScript

7 Comments(s)

Copy linkTweet thisAlerts:
@ScriptageFeb 02.2006 — You need to look up event bubbles:

http://www.quirksmode.org/js/events_order.html
Copy linkTweet thisAlerts:
@felgallFeb 02.2006 — You mean like being able to release a key or mouse button before you press it? Events trigger in the order they actually occur.

As for the order in which they trigger for nested objects you need to decide whether to attach the event to the capture or bubble phase of the processing.
Copy linkTweet thisAlerts:
@slip777authorFeb 03.2006 — No, you don't understand me right.

For example:

var div = document.getElementById(someId);

function click1(ev) {

alert("1");

}

function click2(ev) {

alert("2");

}

div.addEventListener("click", click1, true);

div.addEventListener("click", click2, true);


In Gecko it will be executed in the following order:

click1

click2

I need to change THIS order!
Copy linkTweet thisAlerts:
@KravvitzFeb 03.2006 — Although all EventListeners on the EventTarget are guaranteed to be triggered by any event which is received by that EventTarget, no specification is made as to the order in which they will receive the event with regards to the other EventListeners on the EventTarget.[/quote]
http://www.w3.org/TR/DOM-Level-2-Events/events.html

You could try using removeEventListener() and then add them again with addEventListener(). However, like the quote says, the order is not guaranteed.
Copy linkTweet thisAlerts:
@ScriptageFeb 04.2006 — I've knocked something up in about half an hour that sort of does what you want... at the moment the code is ie specific and really really messy, it can be easily modified to check the browser version and then call either attachEvent or addEventListener. If you like you can take the basic idea and elaborate or I can throw together a cross browser version... At the moment there isn't a way to change the order of events once they have been set, but you can regulate the precise order in which they occur when you add the listener. As I said before the code is messy so it will take me a little time to add a fix to change the order of events dynamically, it just needs a function in the listenerObject() to reorder the listeners array:

[code=php]
<div id="someid">la la la laaaa laa dee da</div>
<script>
var cache = document.getElementById;

document.getElementById = function(id){

this.getId = cache;
this.domObject = this.getId(id);

this.domObject.addListenerObject = function(){

return new listenerObject(id);

}

function listenerObject(id){

this.id = id;
this.listeners = new Array();
this.add = addListener;
this.eventHandler = myEventHandler;
return this;

}

function addListener(type, func, bool, index){

with(this);


var myEvent = type;
type = type.replace(/on/, "")


if(!this.listeners[type]){
this.listeners[type] = new Array();
this.listeners[type][index] = func;

var listeners = this.listeners;

var myFunc = function(ev){

myEventHandler(ev.type.toString(), listeners);

}

document.getElementById(this.id).detachEvent(myEvent, myFunc)
document.getElementById(this.id).attachEvent(myEvent, myFunc);

}else{

this.listeners[type][index] = func;

}

}

function myEventHandler(ev, listeners){

for(var i=0; i<listeners[ev].length; i++){

eval(listeners[ev][i] + "()");



}

}



return this.domObject;
}

function click1(){

alert("click1");

}

function click2(){

alert("click2");

}


var myListener = document.getElementById("someid").addListenerObject();
myListener.add("onclick", "click1", true, 0);
myListener.add("onclick", "click2", true, 1);


</script>

[/code]


I will continue to work on this if you like, let me know.

Regards

Carl
Copy linkTweet thisAlerts:
@ScriptageFeb 05.2006 — Right I've updated the script, it's now cross browser compatible, alot cleaner and has a remove method for the listeners. Function still in progress are:

push - Increase listeners position

shift - Decrease listeners position

move - Move the listener to a specific index

switch - Switch one listener with another

Here's the code so far:

[code=php]
<div id="text">

Some text
<br />
Goes here

</div>

<script>
var cache = document.getElementById;
var isIE = 0;

if(navigator.appName == "Microsoft Internet Explorer"){
isIE=1;
}

document.getElementById = function(id){ // Override the document.getElementById function to add the addEventListener function

this.getId = cache; // Copy the native document.getElementById into this objects getId variable
this.domObject = this.getId(id); // Assign this.domObject to the object that you are getting by id

this.domObject.addListenerObject = function(){ // Add the addListenerObject method to the document.getElementById method

return new listenerObject(id);

}

return this.domObject;
}

function listenerObject(id){

this.id = id;
this.listeners = new Array(); // Array of event listeners
this.eventHandler = myEventHandler;
this.add = addListener; // Method to add an event listener
this.remove = removeListener; // Method to remove an event listener
this.push = pushListener; // Method to increase the listeners precedence
this.shift = shiftListener; // Method to decrease listeners precedence
this.moveTo = moveListener; // Method to move a listener to a specific index
this.eventHandler = myEventHandler // Event Handling method

return this;
}


function addListener(type, func, bool, index){ // Method for adding event listeners

with(this);

if(isIE){

type = "on" + type; // Append on to the event type, IE handles events differently to mozilla

}


if(!this.listeners[type]){ // If there hasn't been an array defined for the event type
this.listeners[type] = new Array(); // Create one

if(!index){ // If the index argument has been ommited
index = this.listeners[type].length; // add the listener object to the end
}


this.listeners[type][index] = func; // Add an event listener to the events list


var thisEventListener = this; // Reference this so the anonymous function can access it

var eventHandler = function(ev){ // Capture the events

thisEventListener.eventHandler(ev.type.toString(), thisEventListener.listeners); // Pass events to the event handler

}

if(isIE){

document.getElementById(this.id).attachEvent(type, eventHandler); // Add the event listener to the element

}else{

document.getElementById(this.id).addEventListener(type, eventHandler, bool); // Add the event listener to the element

}


}else{

if(!index){ // If the index argument has been ommited
index = this.listeners[type].length; // add the listener object to the end
}

this.listeners[type][index] = func; // Add an event listener to the events list

}

return this;
}


function removeListener(ev, func){ // Method for removing an event listener

with(this);

if(isIE){

ev = "on" + ev;

}


var tempArray = new Array(); // Create a temporary array to store the listeners

for(var i=0; i<this.listeners[ev].length; i++){ // Iterate through the listeners

if(this.listeners[ev][i] != func){

tempArray[tempArray.length] = this.listeners[ev][i]; // Store the data from the listener array n a temporary array (I had to do it this way as I was getting unexpected results with splice)

}

}

this.listeners[ev] = tempArray; // Update the listeners array

return this;

}

function pushListener(func){ // Function still in progress

with(this);

if(isIE){

ev = "on" + ev;

}



}

function shiftListener(){ // Function still in progress


with(this);

if(isIE){

ev = "on" + ev;

}


}

function moveListener(index){ // Function still in progress

with(this);

if(isIE){

ev = "on" + ev;

}



}

function myEventHandler(ev, listeners){

if(isIE){

ev = "on" + ev;

}


for(var i=0; i<listeners[ev].length; i++){

eval(listeners[ev][i] + "()");

}

}

function click1(){
alert("I'm click 1");
}

function click2(){
alert("I'm click 2");
}

function click3(){
alert("I'm click 3");
}

var myListener = document.getElementById("text").addListenerObject();
myListener.add("click","click1",true);
myListener.add("click","click2", true)
myListener.add("click","click3", true)
myListener.remove("click","click2");
</script>
[/code]
Copy linkTweet thisAlerts:
@ScriptageFeb 06.2006 — Try this code out, I think it will be to your liking. I'm going to add support for event bubbling and catching next... let me know what you think about the code so far:

Usage:

var myListener = document.getElementById("id").addListenerObject();

myListener.add(event, function, bool)

myListener.remove(event, function);

myListener.push(event, function);

myListener.shift(event, function);

myListener.move(event, function, index);

myListener.swap(event, function1, function2);

var myArrayOfListeners = myListener.list(event);

[code=php]

<div id="text">

Some text
<br />
Goes here

</div>

<script>
var cache = document.getElementById;
var isIE = 0;

if(navigator.appName == "Microsoft Internet Explorer"){
isIE=1;
}

document.getElementById = function(id){ // Override the document.getElementById function to add the addEventListener function

this.getId = cache; // Copy the native document.getElementById into this objects getId variable
this.domObject = this.getId(id); // Assign this.domObject to the object that you are getting by id

this.domObject.addListenerObject = function(){ // Add the addListenerObject method to the document.getElementById method

return new listenerObject(id);

}

return this.domObject;
}

function listenerObject(id){

this.id = id;
this.listeners = new Array(); // Array of event listeners
this.eventHandler = myEventHandler;
this.add = addListener; // Method to add an event listener
this.remove = removeListener; // Method to remove an event listener
this.push = pushListener; // Method to increase the listeners precedence
this.shift = shiftListener; // Method to decrease listeners precedence
this.move = moveListener; // Method to move a listener to a specific index
this.swap = switchListeners; // Method to switch the position of two listeners
this.list = list; // Method to retrieve the event handlers i array format
this.eventHandler = myEventHandler // Event Handling method

return this;
}


function addListener(type, func, bool, index){ // Method for adding event listeners

with(this);

if(isIE){

type = "on" + type; // Append on to the event type, IE handles events differently to mozilla

}


if(!this.listeners[type]){ // If there hasn't been an array defined for the event type
this.listeners[type] = new Array(); // Create one

if(!index){ // If the index argument has been ommited
index = this.listeners[type].length; // add the listener object to the end
}


this.listeners[type][index] = func; // Add an event listener to the events list


var thisEventListener = this; // Reference this so the anonymous function can access it

var eventHandler = function(ev){ // Capture the events

thisEventListener.eventHandler(ev.type.toString(), thisEventListener.listeners); // Pass events to the event handler

}

if(isIE){

document.getElementById(this.id).attachEvent(type, eventHandler); // Add the event listener to the element

}else{

document.getElementById(this.id).addEventListener(type, eventHandler, bool); // Add the event listener to the element

}


}else{

if(!index){ // If the index argument has been ommited
index = this.listeners[type].length; // add the listener object to the end
}

this.listeners[type][index] = func; // Add an event listener to the events list

}

return this;
}


function removeListener(ev, func){ // Method for removing an event listener

with(this);

if(isIE){

ev = "on" + ev;

}


var tempArray = new Array(); // Create a temporary array to store the listeners

for(var i=0; i<this.listeners[ev].length; i++){ // Iterate through the listeners

if(this.listeners[ev][i] != func){

tempArray[tempArray.length] = this.listeners[ev][i]; // Store the data from the listener array in a temporary array (I had to do it this way as I was getting unexpected results with splice)

}

}

this.listeners[ev] = tempArray; // Update the listeners array

return this;

}

function pushListener(ev, func){ // Function still in progress

with(this);

if(isIE){

ev = "on" + ev;

}

var index;
var tempValue;

if(this.listeners[ev][0] != func){ // Make sure we aren't trying to push the listener off of the end of the array

for(var i=this.listeners[ev].length-1; i>0; i--){ // Iterate through the array

if(this.listeners[ev][i] == func){ // If we have found the function

index = i; // Make a note of it's index

}

}

tempValue = this.listeners[ev][index-1]; // Store the listener to be shifted

this.listeners[ev][index-1] = this.listeners[ev][index]; // Switch
this.listeners[ev][index] = tempValue; // the values at the index

return this;

}

}

function shiftListener(ev, func){ // Function to decrease the listeners index


with(this);

if(isIE){

ev = "on" + ev;

}


var tempArray = new Array(); // Define a temporary array to store the new listeners array

if(this.listeners[ev][this.listeners[ev].length-1] != func){ // Make sure we aren't trying to shift the listener off of the end of the array

for(var i=0; i<this.listeners[ev].length; i++){ // Iterate through the array

if(this.listeners[ev][i] == func){ // If we have found the function

tempArray[i] = this.listeners[ev][i+1]; // Switch
tempArray[i+1] = this.listeners[ev][i]; // the listeners
i++;

}else{

tempArray[i] = this.listeners[ev][i];

}



}

this.listeners[ev] = tempArray; // Overwrite the listeners array

return this;

}

}

function moveListener(ev, func, index){ // Method to move a listener to a specific location

with(this);

if(isIE){

ev = "on" + ev;

}

if(index > -1 && index < this.listeners[ev].length){ // Don't allow listeners to be moved from the extremeties of the array

var functionIndex;
var found = false;
var tempArray = new Array();

for(var i=0; i<this.listeners[ev].length; i++){ // Iterate through the array

if(!found){ // If we have not yet found the listener index in the listeners array

if(this.listeners[ev][i] == func){ // Check to see if we are at the index of the listener

found = true; // Set the flag telling the loop that we have found the funtion's index
// Notice how we ignore the listener, it does not get copied

}else{

tempArray[i] = this.listeners[ev][i]; // Copy the function into the temporary array

}

}else{

tempArray[i-1] = this.listeners[ev][i]; // Shift the rest of the listeners up in the array

}

}

var finalArray = new Array(); // Define an array to store our final listeners list
var isIndex = false; // Flag that determines if we are at the desired index

for(var k=0; k<this.listeners[ev].length-1; k++){ // Iterate through the array

if(!isIndex){ // If we have not yet passed the listener index

if(k == index){ // Check to see if we are at the index of the listener

isIndex = true; // Set the flag telling the loop that we have passed the index
finalArray[k] = func; // Add the function to the array at the index point
finalArray[k+1] = tempArray[k]; // Shift the next listener up


}else{

finalArray[k] = tempArray[k]; // Copy the listener into the new array


}

}else{

finalArray[k+1] = tempArray[k]; // Shift the rest of the listeners up

}

}

this.listeners[ev] = finalArray; // Overwrite the listeners array

return this;

}

}

function myEventHandler(ev, listeners){

if(isIE){

ev = "on" + ev;

}


for(var i=0; i<listeners[ev].length; i++){

eval(listeners[ev][i] + "()");

}

}

function switchListeners(ev, func1, func2){

with(this);

if(isIE){

ev = "on" + ev;

}

var index1;
var index2;

for(var i=0; i<this.listeners[ev].length; i++){

if(this.listeners[ev][i] == func1){

index1 = i;

}


if(this.listeners[ev][i] == func2){

index2 = i;

}

}

this.listeners[ev][index2] = func1;
this.listeners[ev][index1] = func2;

return this;

}

function list(type){

with(this);

if(isIE){

type = "on" + type; // Append on to the event type, IE handles events differently to mozilla

}

return this.listeners[type]; // return the listeners array

}

function click1(){
alert("I'm click 1");
}

function click2(){
alert("I'm click 2");
}

function click3(){
alert("I'm click 3");
}

function click4(){
alert("I'm click 4");
}

function click5(){
alert("I'm click 5");
}


var myListener = document.getElementById("text").addListenerObject();
myListener.add("click","click1",true);
myListener.add("click","click2", true);
myListener.add("click","click3", true);
myListener.add("click","click4", true);
myListener.add("click","click5", true);


alert(myListener.list("click"));


myListener.swap("click","click2","click5");


alert(myListener.list("click"));


myListener.remove("click","click1");


alert(myListener.list("click"));


myListener.push("click","click4");


alert(myListener.list("click"));


myListener.shift("click","click3");


alert(myListener.list("click"));


myListener.move("click","click2", 1);

alert(myListener.list("click"));

</script>

[/code]
×

Success!

Help @slip777 spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.4,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,
)...