views:

20

answers:

2

I attach an onmouseout event to a Raphael circle element like this:

    (function(el,iElPos,col){
        el.mouseout(function elmouseout(){el.animate({"fill":col,"r":ELEMENT_RADIUS},150);
                               alert("first");
                               fadeTag();
                               });              
    )(c,i,elementColour);

c is the element. I then later wish to disconnect the event and attach another thuswise:

(function (el){
    el.attr("fill",EXCLUDED_COLOUR);
    el.unmouseout(elmouseout);
    el.mouseout(function elmouseout(){
                       alert("second");
                       el.animate({"fill":EXCLUDED_COLOUR,"r":ELEMENT_RADIUS},150);
                       fadeTag();
                       });
})(setMainSeries[iPos]);

But this attaches both events. Both alerts are firing, the later-attached event fires first. I want to disconnect the first event totally. Am I using unmouseout() incorrectly?

UPDATE

I tried suggestions from echo-flow and lincolnk but neither worked. I think echo-flow's may be more likely to work. I broke out the function as suggested like so...

function elmouseoutDefault(el){
    el.animate({"fill":ELEMENT_COLOUR,"r":ELEMENT_RADIUS},150);
    alert("first");
    fadeTag();
};

then attached the event like this as I created each element...

el.mouseout(elmouseoutDefault);

However this failed as I am not passing el. So I changed it to...

el.mouseout(elmouseoutDefault(el));

This seems to call elmouseoutDefault as it is being added. I only want it to trigger on the mouseout event.

A: 

it looks like an issue of where you're declaring the function name- I think things can get tricky when you define the function inline with a name. this should keep a function to the reference more reliably.

var elmouseout = null;

(function (el, iElPos, col) {

    elmouseout = function () {
        el.animate( {"fill": col, "r": ELEMENT_RADIUS }, 150);
        alert("first");
        fadeTag();
    };

    el.mouseout(elmouseout);

})(c, i, elementColour);


(function (el) {

    el.attr("fill", EXCLUDED_COLOUR);

    el.unmouseout(elmouseout);

    elmouseout = function () {
        alert("second");
        el.animate( { "fill": EXCLUDED_COLOUR, "r": ELEMENT_RADIUS}, 150 );
        fadeTag();
    };

    el.mouseout(elmouseout);

})(setMainSeries[iPos]);

edit: it's a scope thing- your definition of elmouseout exists only within the scope of the self-invoking function. i was thinking of a different issue concerning function names. the code should still work though.

lincolnk
There's nothing wrong with declaring a named function inline. This is just an inner function declaration, which is completely legal in js, and is the equivalent of creating an anonymous function, and assigning it to a local variable using "var". The issue is that the second scope attempts to reference a variable defined in the first scope. I think the code you've presented here would work correctly.
echo-flow
@echo-flow thanks, i had that in my head while i was writing this but it didn't click until i read your comment.
lincolnk
Hi, this still doesn't seem to disconnect the event. Same behaviour as before :(...
El Ronnoco
I think part of the problem is that I am applying this behaviour to multiple elements `c` and so if I have one global variable `elmouseout` this will be overwritten each time a new `c` has its event attached...
El Ronnoco
A: 

I'd like to verify this against your working code, but based on the code you posted, here's what I think is happening: in both code snippets, you are declaring a function "elmouseout". The function declaration syntax you are using declares the function in the local scope (the equivalent of writing "var elmouseout = function(){...}"), and because you are declaring each inside of a separate function closure, the variable "elmouseout" in the second code block refers to function "elmouseout" from the second code block, as opposed to the first code block, which would yield the desired behaviour. I would recommend breaking out the function declarations, as follows:

function elmouseout(e){e.target.animate({"fill":col,"r":ELEMENT_RADIUS},150);
                               alert("first");
                               fadeTag();
                               }

    (function(el,iElPos,col){
        el.mouseout(elmouseout);              
    )(c,i,elementColour);


function elmouseout2(e){
                       alert("second");
                       e.target.animate({"fill":EXCLUDED_COLOUR,"r":ELEMENT_RADIUS},150);
                       fadeTag();
                       }

(function (el){
    el.attr("fill",EXCLUDED_COLOUR);
    el.unmouseout(elmouseout);
    el.mouseout(elmouseout2);
})(setMainSeries[iPos]);
echo-flow
Hi this doesn't work, please see my update
El Ronnoco
I modified the event handlers to accept an event, and take the element target off of the event. I think the above code should now work correctly. If you like, feel free to link to a live sample so that I can verify it.
echo-flow
Thanks for your update. I haven't been able to try it yet as I have found a workaround. I will probably come back to this later in the week though and try your code out on my historic version. Thanks.
El Ronnoco