当我声明它时,onclick方法被执行

Big*_*c66 1 javascript raphael

我试图声明一个onclick方法,该方法将调用一个清除和重建显示的函数,显示所单击项目的更多细节.问题是onclick我尝试分配的方法在分配时执行,所以我看到的是其中一个项目的详细视图.

如果删除该i.node.onclick行,则会看到5个随机放置的项目,您可以将其悬停但不会单击.

HTML

<html>  
   <head>  
      <title>Raphael Play</title>  
      <script type="text/javascript" src="Raphael.js"></script>  
      <script type="text/javascript" src="Test.js"></script>  
      <style type="text/css">  
        #map 
        {  
           width: 500px;  
           border: 1px solid #aaa;  
        }  
      </style>  
   </head>  
   <body>  
      <div id="map"></div>  
   </body>  
</html>  
Run Code Online (Sandbox Code Playgroud)

JavaScript的

var map;
var items = new Array();

window.onload = function() 
{  
   map = new Raphael(document.getElementById('map'), 500, 500);  

   for(cnt = 0; cnt < 5; cnt++)
   {
      var x = 5 + Math.floor(Math.random() * 490);
      var y = 5 + Math.floor(Math.random() * 490);

      items[cnt] = new Item(x, y);

      var i = map.circle(items[cnt].x, items[cnt].y, 8).attr({fill: "#000", stroke: "#f00", title: items[cnt].name}); 
      i.node.onclick = detailView(items[cnt]);
   }
} 

function Item(x, y)
{
   this.x = x;
   this.y = y;
   this.name = "Item[" + x + "," + y + "]";
}

function detailView(dv)
{
   map.clear();

   map.circle(250, 250, 25).attr({fill: "#0f0", stroke: "#f00", title: dv.name});
}
Run Code Online (Sandbox Code Playgroud)

Poi*_*nty 5

首先,您需要一个辅助函数:

  function detailViewer(item) {
    return function() { detailView(item); };
  }
Run Code Online (Sandbox Code Playgroud)

然后你就像这样设置点击处理程序:

  i.node.onclick = detailViewer(items[cnt]);
Run Code Online (Sandbox Code Playgroud)

辅助函数构建一个函数,在调用它时,调用"detailView()"函数,传入与节点相关的项.正如您所注意到的那样,在执行初始化时,您编写的代码简称 "detailView()"."onclick"属性需要是一个函数本身,这就是我上面提到的辅助函数会给你的.

  • @Platinum Azure的问题是变量"cnt"将由所有处理程序**共享** - 在该函数中只有其中一个,因此每个闭包都会引用相同的值.因此,当处理程序实际运行时,"cnt"的值将是错误的!这是JavaScript中的经典陷阱,因为只有函数引入了新的范围.您可以通过将函数包装在**另一个**函数中来"内联",以复制"cnt". (2认同)