views:

956

answers:

4

I've just built an SVG map of New Zealand for use with the excellent javascript library Raphael, but unfortunately have stumbled upon what I can only imagine is a bug or syntactic variation in IE's javascript interpreter.

In Firefox and other browsers the onlick and onmouseover events work perfectly - however they do not fire in IE (tested in IE 7). Unfortunately there is no javascript error to help me debug this, so I can only assume IE handles these events in some fundamentally different way.

<script type="text/javascript" charset="utf-8">
    window.onload = function() {
     var R = Raphael("paper", 450, 600);
     var attr = {
      fill: "#3f3f40",
      stroke: "#666",
      "stroke-width": 1,
      "stroke-linejoin": "round"
     };
     var nz = {};
     nz.northland = R.path(attr, "M 193.34222,3.7847503 C 194.65463");
                // SVG data stripped for sake of brevity
     var current = null;
     for (var region in nz) {
      nz[region].color = Raphael.getColor();
      (function(rg, region) {
       rg[0].style.cursor = "pointer";
       rg[0].onmouseover = function() {
        current && nz[current].animate({ fill: "#3f3f40", stroke: "#666" }, 500) && (document.getElementById(current).style.display = "");
        rg.animate({ fill: rg.color, stroke: "#ccc" }, 500);
        rg.toFront();
        R.safari();
        document.getElementById(region).style.display = "block";
        current = region;
       };
       rg[0].onclick = function() {
        alert("IE never gets this far.");
        //window.location.href = "my-page.aspx?District=" + region;
       };
       rg[0].onmouseout = function() {
        rg.animate({ fill: "#3f3f40", stroke: "#666" }, 500);
       };
       if (region == "northland") {
        rg[0].onmouseover();
       }
      })(nz[region], region);
     }
    };
</script>

Many thanks :)

+1  A: 

Have you tried attaching the events?

if (rg[0].attachEvent)
    rg[0].attachEvent("onclick", function(){ /* IE */ });
else
    rg[0].addEventListener("click", function(){ /* other */ }, false);
Joel Potter
I like that this is more inline with recommendations from the W3C, but unfortunately the same problem persists. The following does work however:if (rg[0].attachEvent)rg[0].attachEvent("onmousedown", function() { /* IE */ });
Bayard Randel
It's been awhile since I worked with the native event handles in javascript. Libraries like JQuery are making me spoiled. ;)
Joel Potter
A: 

IE is not exactly known for working correctly. It would help if you mentioned which IE version you are using.

Zifre
Clarified in the post thanks - tested in IE 7
Bayard Randel
+2  A: 

The fix appears to be using the onmousedown event instead of onclick.

Changing:

rg[0].onclick = function() {
alert("IE never gets this far, but Firefox is happy.");
};

to

rg[0].onmousedown = function() {
alert("This works in IE and Firefox.");
};

resolved the issue. Thanks for everyone's input - got there in the end. If anyone actually knows why IE doesn't like onclick, I'd be interested to hear!

Bayard Randel
You could avoid a lot of problems like this by simply adopting a framework which has solved the cross browser issues for you, such as jQuery, dojo, mootools, or prototype/scriptaculous.
tvanfosson
Good suggestion - clearly a good time to improve my jquery-fu. Thanks :)
Bayard Randel
That's a more specific case: you're looking at event support for SVG elements. This isn't the same as cross browser event support on standard HTML elements. It just may be (I haven't verified) that IE doesn't support the mousedown and mouseup events on a SVG element.
faB
A: 

Generally an abstraction framework, like jquery or prototype is your best bet. They handle the browser differences for you. Also, you can subscribe to your events at a higher level... it's less expensive in the browser to subscribe to the mousemove/click, and determine what you're over, or clicking on from the event bubble than to many objects.

Joel Potter mentioned the subscriber model, using the dom and IE methods, which is better practice than the method assignment is.

Tracker1