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

发布于 2024-09-27 15:24:50 字数 845 浏览 10 评论 0 原文

发现 IE 不处理 javascript onmouseout 后,我决定使用 jQuery 来代替,这样跨浏览器兼容性就会自动得到处理。我正在制作一个由 svg 路径定义的区域,当鼠标悬停在其上方时,该区域会亮起,并且我改编了 Raphael 网站上提供的代码 澳大利亚示例

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

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

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

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

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

为了将 onmouseover 替换为 jQuery 等效项(我认为是 .mouseout()),我需要为 st[0] 分配一个类code> 这样我就可以用 jQuery 引用它。我的问题是,我该怎么做?如果代码是 st.onmouseover ,那就很简单了,但为什么路径 (st) 是一个数组呢? st[0] 到底是什么?我到底该怎么做呢?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

青丝拂面 2024-10-04 15:24:50

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


其缺点是:

只需包装 DOM 对象即可从中创建 jQuery 对象,或者使用Raphael内置的自定义事件处理程序:

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

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

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

或者,使用 Raphael 内置事件处理方法

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

长话短说:

您可以使用 节点 [0],因为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");    
    });
});​

用这个 jsFiddle 尝试一下

此外,Raphael .hover() 方法似乎也可以在 IE 中工作。

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.

葬花如无物 2024-10-04 15:24:50

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

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

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

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

You don't need to assign a class to it in order to expose it to jQuery. Certainly not. You can simply pass your DOM element to jQuery and it will do the magic for you...

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

You are seeing the array syntax because that is generally how Javascript libraries maintain a reference to the original element (essentially just "wrapping" it and adding functionality). Pseudo-code explanation...

st == Raphael element
st[0] == DOM element
与酒说心事 2024-10-04 15:24:50

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

在我敲了一段时间后,似乎悬停输入/输出函数中的 st.toFront() 取消了 IE 中的“鼠标移出”事件。从示例代码中删除这些行就可以了。

If you end up just copying the code that's used by the Australia demo, you'll run into IE trouble no matter which handler (hover, mouseover, etc) you use.

After banging my head on it for a while, it seems that the st.toFront() in the hover in/out functions cancel the "mouse out" event in IE. Delete those lines from the example code and you should be fine.

若无相欠,怎会相见 2024-10-04 15:24:50

这有点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

This is a bit of javascript trickery, st is passed in. Look at the JS code in the australia example.

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

So st[0] in this code refers to the path DOM node from aus[state].

Try it yourself with this simple example in a Firebug console:

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

hth

夜吻♂芭芘 2024-10-04 15:24:50

就我而言,实际的问题是每毫秒调用 .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) { }
);

In my case, the actual problem was with calling the .toFront every freakin millisecond, because .hover(fooFunction, outFunction) calls fooFunction with every mouse cursor shift. Actually, the name quite suggests that it's a hover call, not a mouseenter :)

So, the trick is to make sure your fooFunction, or the contents of it, is only executed once (onmouseenter). Even in IE this works perfectly for me, without accessing any DOM nodes or trying to access other stuff which I don't want to touch:

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

Then replace your hover calls like this:

var el = paper.rect(...);
MouseEventHelper.hover(
    el, 
    function (e) { 
        // do whatever you want!
        el.toFront();
    }
    function (e) { }
);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文