无法将函数作为值传递给setAttribute

时间:2012-01-03 02:07:17

标签: javascript svg

我有一些工作的SVG代码,通过在形状上设置属性来处理鼠标事件:

function plot() {
  ...
  shape.setAttributeNS(null, "onmouseover", "popup_on (evt,"+sindex+","+month+")");
  shape.setAttributeNS(null, "onmouseout",  "popup_off(evt,"+sindex+")");
}

但是,我需要更改此代码,因为popup_onpopup_off不再是静态函数,并且需要大量上下文,具体取决于它们的调用位置。我正在通过定义一个闭包并将函数名称作为属性值传递来处理它:

function plot(popup_on, popup_off) {
  ...
  shape.setAttributeNS(null, "onmouseover", popup_on  + "(evt,"+sindex+","+month+")");
  shape.setAttributeNS(null, "onmouseout",  popup_off + "(evt,"+sindex+")");
}

但是,这不起作用 - 弹出代码永远不会被触发。如果我检查Firebug或Dragonfly中的'shape'属性,它们似乎是正确的。 'shape'具有'onmouseover'和'onmouseout'属性,属性的值是popup_onpopup_off函数的完整源文本:

onmouseover=function popup_on(evt, sindex, month) {
  ...
} 

但实际上并没有运行这些功能。 知道我做错了什么吗?感谢。

更新

感谢所有反馈。马克的答案不起作用; 'function'被标记为语法错误。 'popup_on'和'popup_off'不是字符串 - 它们实际上是闭包中的函数。不过,Sime和Erik的答案都有效,但有一个问题。

如果我将代码更改为:

shape.addEventListener("mouseover", function() {popup_on (evt, sindex, month);}, false);

然后firebug抱怨'evt'在尝试执行popup_on时(鼠标点击时)未定义。如果我将evt更改为window.evtevt || window.evt,那么我不会收到此错误,但我仍然无法访问弹出处理程序中的事件:

   // popup handler in closure
   o["popup_on"] = function(evt, sindex, month) {
      // both evt and window.evt are undefined on entry
      evt = evt || window.evt;
      // so evt is still undefined, but...
      ...
      // I need to do this
      var upright = (evt.clientY >= cy);

知道为什么吗?感谢。

UPDATE2

好的 - 修好了。答案是:

shape.addEventListener("mouseover", function(evt) {popup_on (evt, sindex, month);}, false);
shape.addEventListener("mouseout",  function(evt) {popup_off(evt, sindex);}, false);

2 个答案:

答案 0 :(得分:1)

popup_on  + "(evt,"+sindex+","+month+")"

被视为“函数popup_on加上字符串'(evt,'加上sindex的值加上......”

它不被解释为构建函数调用。

如果你需要动态构建其参数,你应该做更像

的事情
shape.setAttributeNS(null, "onmouseout",  function() {
    popup_off(evt,sindex);
});

答案 1 :(得分:1)

为什么不使用shape.addEventListener("mouseout", function() {...}, false)?有关示例,请参阅here

如果您希望在您的函数中将事件对象命名为“evt”,您可以为其命名(您可以为其指定任何名称),如下所示:shape.addEventListener("mouseout", function(evt) {...}, false)

否则,事件变量默认在侦听器函数中名为'event',而不是'evt'。这是一些混乱的根源。