您的位置:首页 > Web前端 > JavaScript

【JS难题】循环内绑定对象事件

2008-01-09 11:54 1066 查看
导读:

  o.attachEvent("onclick", function(){ doClick(i); });

  document.body.appendChild(o);

  }

  alert出来都是10,要达到的目的很简单,一眼看出,但结果不如所想。如何解决?

  ---------------------------------------------------------------

  I dont't know the reason exactly, but I can tell you that 'i' seems to be a Global variable even if you put the codes in a function.

  use my code:

  

  

  Function.prototype.getHandler = function (obj) {

  var oThis = this;

  var argu = Array.prototype.slice.call(arguments, 1);

  return function (){

  oThis.apply(obj, argu);

  };

  };

  function doClick(x) {

  alert(x);

  };

  for (var i=0;i<10;i++) {

  var o = document.createElement("input");

  o.attachEvent("onclick", doClick.getHandler(null,i));

  document.body.appendChild(o);

  }

  
  

  If you don't know about "call","apply", you can see the Javascript Reference, or

  http://community.csdn.net/Expert/topic/3191/3191873.xml?temp=.337063

  Good luck.

  ---------------------------------------------------------------

  是这样的,attachEvent虽然把执行定义好了,但是,并没有执行。

  而当真正click的时候,这时i的值已经是10了,所以,会alert出来10。

  function(){}相当于Function()函数,以下这么写估计就会很清楚了。

  

  function doClick(x) {

  alert(x);

  }

  for (var i=0;i<10;i++) {

  var o = document.createElement("button");

  o.onclick = Function("doClick(i);");

  document.body.appendChild(o);

  }

  
  ---------------------------------------------------------------

  菜鸟也插插话啦

  首先,javascript只有两种级别变量:scripting级就相当于public,所有想象得到的地方都可以访问;另一种就是函数内,仅函数内可访问,而for,if等语句中定义的变量同样只属于这两种,未定义的变量全部被认为是scripting级的

  如:for (var i=0; i<5; i++){} alert(i);

  function f(){ for (var i=0; i<5; i++){} alert(i); }

  
  function f(){ for (i=0; i<5; i++){} }

  
  其次,runming给出了正确的答案,但是他并没有说清为什么原来的是错的

  function doClick(x) {

  alert(x);

  };

  for (var i=0;i<10;i++) {

  var o = document.createElement("input");

  o.attachEvent("onclick", function(){ doClick(i); });

  document.body.appendChild(o);

  }

  在o.attachEvent中创建的function并没有任何参数,i不过是for创建的一个变量而已,这就相当于function在函数体{}中的语句中直接使用变量i来调用函数doClick,因此i的任何改动都将反应出来,跟i是引用还是值并没有关系,而runming的答案正是改正了这个问题

  function doClick(x) {

  alert(x);

  }

  function mapping(element, value)

  {

  element.attachEvent("onclick", function()

  {

  doClick(value);

  })

  }

  for (var i=0;i<10;i++) {

  var o = document.createElement("input");

  mapping(o, i);

  document.body.appendChild(o);

  }

  for中创建函数时i的值已赋值给value,如是引用,则value也已得到i的引用,这样,即使i已改变,也不会影响到value的值

  再次,为了验证function中确实是使用变量i直接调用doClick,改代码如下

  >
  function doClick(x) {

  alert(x);

  };

  function f()

  {

  for (var i=0;i<10;i++) {

  var o = document.createElement("input");

  o.attachEvent("onclick", function(){ doClick(i); });

  document.body.appendChild(o);

  }

  }

  >
  此时,alert的值依然是10,这可以说明function确实是使用了i,这个i在这里虽然是函数级变量,但是由于function创建于f,所以i对于function来说仍然是全局的,也就是创建的每个function都使用变量i来调用doClick,因此仍然是一样的

  最后,说说所谓的“投机”做法

  

  function doClick(x) {

  alert(x);

  };

  for (var i=0;i<10;i++) {

  var o = document.createElement("input");

  eval("o.attachEvent(/"onclick/", function(){doClick(" + i + ");});")

  document.body.appendChild(o);

  }

  
  很明显,在for中创建的function 本身就使用常数了,i的位置其实变成一个字符串常数,也就是说function的内容就是doClick(某常数),自然这个常数是不会被i影响的,所以在值类型的时候,此方法是可行的,而使用引用类型时则不行

  

  function doClick(x) {

  alert(x);

  };

  for (var i=0;i<10;i++) {

  var d = new Date(2000,i+1,i+1);

  var o = document.createElement("input");

  eval("o.attachEvent(/"onclick/", function(){doClick(" + d + ");});")

  document.body.appendChild(o);

  }

  
  上面的代码是错误的,因为d是对象而不是值

  总结:严重同意runming中

  给朵鲜花(1)扔个鸡蛋(1)

本文转自

http://faq.csdn.net/read/202764.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: