结合Raphael和jQuery实现浏览器兼容性

时间:2010-10-11 18:08:37

标签: jquery path raphael

发现IE不处理javascript onmouseout后,我决定使用jQuery,以便自动处理跨浏览器兼容性。当鼠标悬停在svg路径上时,我正在创建一个由svg路径定义的区域,并且我从Australia example调整了Raphael网站上提供的代码。

在此代码中,澳大利亚的每个州都由拉斐尔路径定义,例如塔斯马尼亚:

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

然后将此路径('st')传递给函数:

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

与我的预期相反,代码为st[0].onmouseover,而不仅仅是st.onmouseover。因此,路径实际上必须是一个数组,而st[0],无论是什么,都是悬停的东西。

为了用jQuery等价物替换onmouseover(我认为是.mouseout()),我需要为st[0]分配一个类,所以我可以用jQuery来引用它。我的问题是,我该怎么做?如果代码是st.onmouseover,那么它会很简单,但为什么路径(st)是一个数组?究竟是什么st[0]?我到底怎么了?

5 个答案:

答案 0 :(得分:19)

注意:该演示是使用旧版本的Raphael制作的。现在Raphael有自己的自定义事件处理程序,包括.mouseover() and .hover()


缺点:

只需将DOM对象包装成一个jQuery Object,或者使用Raphael内置的自定义事件处理程序:

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

或者,可能更方便,并支持IE:

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

或者,使用 Raphael built in event handler method

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

长篇大论:

您可以使用 node [0]获取对DOM对象的引用,因为RaphaelObject[0]总是对DOM元素的引用:

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() {
    ...
});

所以,有了你的功能:

(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);

此外,我建议查看jQuery .hover() 函数,该函数可以很好地处理IE:

(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);

作为简化演示,以下是如何使用mouseentermouseout.hover()绑定到Raphael元素(在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.

答案 1 :(得分:7)

您不需要为其分配类,以便将其公开给jQuery。当然不是。你可以简单地将你的DOM元素传递给jQuery,它将为你带来魔力......

$(st[0]).mouseout(function() {
  alert("That mouse is outta here!");
};

您正在看到数组语法,因为这通常是Javascript库如何维护对原始元素的引用(基本上只是“包装”它并添加功能)。伪码解释......

st == Raphael element
st[0] == DOM element

答案 2 :(得分:5)

如果您最终只是复制了澳大利亚演示所使用的代码,那么无论您使用哪种处理程序(悬停,鼠标悬停等),都会遇到IE问题。

在我的头上敲了一会儿后,似乎hover in / out函数中的st.toFront()取消了IE中的“mouse out”事件。从示例代码中删除这些行,你应该没问题。

答案 3 :(得分:1)

这是一些javascript技巧,st传入。请查看澳大利亚示例中的JS代码。

(function (st, state) {
                    .. some code referring to st[0] in here .. 
                })(aus[state], state);

因此 st [0] 在此代码中指的是来自aus [state] 的路径DOM节点。

在Firebug控制台中使用这个简单的示例自己尝试一下:

(function(a,b) {alert(a); })("hello", "b");

HTH

答案 4 :(得分:1)

在我的情况下,实际问题是每隔一个毫秒调用.toFront,因为.hover(fooFunction,outFunction)在每次鼠标光标移动时调用fooFunction。实际上,这个名字相当暗示它是一个悬停调用,而不是一个mouseenter:)

因此,诀窍是确保你的fooFunction或其内容只执行一次(onmouseenter)。即使在IE中,这对我来说也很完美,无需访问任何DOM节点或尝试访问其他我不想触摸的内容:

var MouseEventHelper = {
    hover: function (el, funcIn, funcOut) {
        var entered = false;

        el.hover(
            function (e) {
                if (entered) {
                    return;
                }

                funcIn(e);
                entered = true;
            },
            function (e) {
                funcOut(e);
                entered = false;
            }
        );
    }
}

然后替换你的悬停调用:

var el = paper.rect(...);
MouseEventHelper.hover(
    el, 
    function (e) { 
        // do whatever you want!
        el.toFront();
    }
    function (e) { }
);