views:

71

answers:

3

I am using Raphael.js library for a specific work. I am creating circles and binding hover event that show/hide text. The problem is that only the text over last circle is shown/hidden, even i am hovering over other circles. plz chk this code

for(var i=0; i<feedData.length; i++){               
                var x = ((i+1)*diff);
                var t = r.text(x, 120, feedData[i].title).hide();

                var c = r.circle(x,150,10);
                c.attr({fill: "red"});
                c.attr({stroke: "red"});
                c.attr({title: feedData[i].title});             
                c.hover(function (event) {
                    this.animate({r: 13}, 200);
                    t.show();
                }, function (event) {
                    this.animate({r: 10}, 200);
                    t.hide();
                });             
            }

for Raphael.js reference

http://raphaeljs.com/reference.html#events

A: 

it seems that if you place the text creation inside the hover event itself, it might work a little bit better.

jonbro
+3  A: 

Well, I don't know anything about raphael library, but it would seem that you could wrap your c.hover in a self calling function in order to create a closure that references the proper value of t.

(function( local_t ) {
    c.hover(function (event) {
        this.animate({r: 13}, 200);
        local_t.show();
    }, function (event) {
        this.animate({r: 10}, 200);
        local_t.hide();
    });
})( t );

This way, when you create your hover event handler, it will pass in the value of t, and reference it inside as the local variable t_local (or whatever name you give it), which will persist until (and after) the handler is called.

So the full code would be:

for(var i=0; i<feedData.length; i++){               
    var x = ((i+1)*diff);
    var t = r.text(x, 120, feedData[i].title).hide();

    var c = r.circle(x,150,10);
    c.attr({fill: "red"});
    c.attr({stroke: "red"});
    c.attr({title: feedData[i].title});             
    (function( local_t ) {
        c.hover(function (event) {
            this.animate({r: 13}, 200);
            local_t.show();
        }, function (event) {
            this.animate({r: 10}, 200);
            local_t.hide();
        });
    })( t );         
}

EDIT: You could wrap the entire inside of the for() statement instead, but I don't think it will make a difference to the specific Chrome issue you mentioned in your comment below.

for(var i = 0; i < feedData.length; i++){
     (function( local_i ) {
        var x = ( ( local_i + 1) * diff );
        var t = r.text(x, 120, feedData[ local_i ].title).hide();

        var c = r.circle(x, 150, 10);
        c.attr({fill: "red"});
        c.attr({stroke: "red"});
        c.attr({title: feedData[ local_i ].title});             

        c.hover(function (event) {
            this.animate({r: 13}, 200);
            local_t.show();
        }, function (event) {
            this.animate({r: 10}, 200);
            local_t.hide();
        });
    })( i );         
}
patrick dw
not working in chrome
coure06
@coure06 - What part isn't working? This technique is a basic part of javascript. Shouldn't be any different in Chrome. Are you sure it isn't some other issue with the `raphael.js` library?
patrick dw
check it at http://bit.ly/bhLoNG [not working in chrome]
coure06
@coure06 - Could you please tell me specifically *what* isn't working?
patrick dw
please mouseover circles, a text will appear above it. onmouseout it will hide. Its working in FF but not in Chrome
coure06
@coure06 - This doesn't appear to be part of the scoping issue your originally had. Perhaps there's a Chrome bug in Raphael. I'll add another solution to my answer that wraps the entire inside of the `for()` statement in a closure, but I don't think that will help. If not, you should probably start another question that addresses the Chrome issue directly. I'll update in a minute.
patrick dw
A: 

It looks like variable t isn't just the object, it's also got hide(). Just looking at the code, I'm not sure what to expect from calling a show() or hide() method on it elsewhere.

for(var i=0; i<feedData.length; i++){               
            var x = ((i+1)*diff);
            var t = r.text(x, 120, feedData[i].title); //remove hide() method
            var c = r.circle(x,150,10);
            c.attr({fill: "red"});
            c.attr({stroke: "red"});
            c.attr({title: feedData[i].title});
            t.hide() //try it here instead?
            c.hover(function (event) {
                this.animate({r: 13}, 200);
                t.show();
            }, function (event) {
                this.animate({r: 10}, 200);
                t.hide();
            });             
        }
Isaac Lubow