Combining Raphael and jQuery to achieve browser compatibility

Bazley picture Bazley · Oct 11, 2010 · Viewed 10.9k times · Source

Having discovered that IE does not handle javascript onmouseout, I'm determined to use jQuery instead so the cross-browser compatibility would be taken care of automatically. I am making an area defined by an svg path light up when the mouse hovers over it, and I adapted the code provided on the Raphael website from the Australia example.

In this code, each state of Australia is defined by a Raphael path, for example Tasmania:

 aus.tas = R.path("...").attr(attr);

This path ('st') is then passed to the function:

st[0].onmouseover = function () {
    ...
};

Contrary to what I would have expected, the code is st[0].onmouseover as opposed to merely st.onmouseover. Thus, the path must actually be an array, and st[0], whatever that is, is the thing that is hovered over.

In order to replace onmouseover with the jQuery equivalent (which I believe is .mouseout()), I need to assign a class to st[0] so I can refer to it with jQuery. My question is, how do I do that? If the code was st.onmouseover it would be straightforward, but why is the path (st) an array? What exactly is st[0]? And how the heck do I get to it?

Answer

Peter Ajtai picture Peter Ajtai · Oct 11, 2010

Note: That demo was made with an old version of Raphael. Now Raphael has its own custom event handlers including .mouseover() and .hover().


The short of it:

Simply wrap the DOM Object to make a jQuery Object out of it, or use the Raphael built in custom event handlers:

$(st[0]).mouseover( ... );            // This uses the jQuery .mouseover() method

Or, probably more convenient, and IE supported:

$(st[0]).hover( ... );                //     This uses the jQuery .hover() method

Or, using a Raphael built in event handler method:

st.mouseover( ... );                 // This uses the Raphael .mouseover() method
st.hover( ... );                     //     This uses the Raphael .hover() method

The long of it:

You can get the reference to the DOM object to work on using node or [0], since RaphaelObject[0] is always the reference to the DOM element:

aus.tas = R.path("...").attr(attr);

// aus.tas is a Raphael object
// aus.tas[0] is aus.tas.node is the reference to the DOM Object

$(aus.tas[0]).mouseover(function() {          // Could have also use aus.tas.node
    ...
});

// Raphael now has custom event handlers
aus.tas.mouseover(function() {
    ...
});
aus.tas.hover(function() {
    ...
}, function() {
    ...
});

So, with you function:

(function (st, state) {
      // st is a Raphael Object
      // st[0] is st.node is the reference to the DOM Object

      // This is now using jQuery for mouseover!
    $(st[0]).mouseover(function() {
        ...
    });
    ...
})(aus[state], state);

Additionally, I would suggest looking into the jQuery .hover() function, which does handle IE quite nicely:

(function (st, state) {
      // This is now using jQuery not Raphael for hover!
    $(st[0]).hover(function() {
        ... // the mouseenter function
    }, function() {
        ... // the mouseleave function
    });
    ...
})(aus[state], state);

As a simplified demonstration, here is how to bind mouseenter and mouseout using .hover() to a Raphael element (tested in IE 8):

​$(function() {
    var elie, paper = Raphael("canvas", 500, 500); 

      // Create Raphael element
    elie = paper.rect(0,0,100,100).attr("fill","#000");

      // Get reference to DOM object using .node and bind
      //     mouseover and mouseout to it:
    $(elie[0]).hover(function() {
        elie.attr("fill","#FFF");
    },function() {
        elie.attr("fill","#000");    
    });
});​

Try it out with this jsFiddle

Additionally, the Raphael .hover() method seem to work in IE too.