给元素注册事件时,事件函数中不能使用全局变量

      最近在做项目的过程中,遇到这样的需求(为了便于说明,我对源需求进行了简化):需要通过js创建新的file元素,并要对新建的元素注册事件和添加属性。(注册的事件是用来在客户端验证上传的文件的大小和格式的)。

 

      以下的代码并不是我项目中的代码,项目中的代码远比这个要复杂的多,而且摘下来的话,大家看的也费力。所以我就本着通俗易懂的原则,截取了一部分,并加工了一下。以便让大家更容易读懂!代码如下:

 

<script type="text/javascript>

    var  globalOne = 0;    // 全局变量

    var  globalTwo = 0;    // 全局变量

   

    /*在此方法中,给新建元素注册的事件函数要用到全局变量的当前*/

    function createElement(parentElement){

          globalOne++;

          globalTwo++;

 

          var tempOne = globalOne;   // 保存全局变量globalOne的当前值

          var tempTwo = globalTwo;   // 保存全局变量globalTwo的当前值

 

           parentElement.appendChild(document.createTextNode("图片:"));
          var textFiled3_pic = document.createElement("<input name=/"surveyOptPicfile_" + globalOne+ "_" +   (globalTwo+ 1) + "/" >");
          textFiled3_pic.setAttribute("type", "file");
          textFiled3_pic.className = "input200";
          textFiled3_pic.setAttribute("id", "surveyOptPicfile_" + globalOne+ "_" + (globalTwo + 1));

 

          // 注册onchange事件
          textFiled3_pic.attachEvent("onchange", function(){ var id = "surveyOptPicfile_" + globalOne+ "_" + (globalTwo+ 1); changeSrc(document.getElementById(id), id);});      // 此处不正确,不能用全局变量(本意是取得全局变量当时的值)

 

          textFiled3_pic.attachEvent("onchange", function(){ var id = "surveyOptPicfile_" + tempOne + "_" + (tempTwo + 1); changeSrc(document.getElementById(id), id);});      // 此处正确(本意是取得全局变量当时的值)


          parentElement.appendChild(textFiled3_pic);    // 把创建的元素追加到父元素中

    }

 

    function  changeSrc(obj, id){

     

        // 在此做一些验证

    }

 

</script>

 

      在上面的注册onchange事件代码中,为什么红色标明的部分不正确,而绿色标明部分正确呢!

      原因是在js中给新创建的元素注册事件时,注册的事件函数并不会在注册的时候就会被元素加载的,而是在元素的注册事件被触发的时候才加载,即执行事件定义的方法;但元素设置的属性,却会在元素定义之后立即被加载。大家可以通过在ie中用调试工具(或火狐的firebug)查看创建的元素的代码;代码中并不会显示事件。

      所以,如果大家以红色的代码注册事件。当触发onchange事件时,注册函数中定义的变量id的值并不是当时注册的时候的全局变量的值;而是全局变量的当前值。要想让id的值重现全局变量重现当时注册时候的值,就应该使用绿色标明部分的代码。

 

      说了这么多,也不知道我说明白了没有。下面我就给一简单的完整的例子——这样也算是对我上面说的一种解释吧。下面的代码兼容IE和火狐,其中蓝色标明部分的代码,请根据自己的浏览器注释掉不需要的部分。简单介绍下面的这段代码的作用:该段代码可以创建多个上传文件的file元素,在每个创建的file元素都注册一个onchange事件,用于验证上传的图片格式是否是.jpg或.gif或.png格式的。

 

<html>
<head>
<script type="text/javascript">
    var  globalOne = 0;    // 全局变量
    var  globalTwo = 0;    // 全局变量

    /*在此方法中,给新建元素注册的事件函数要用到全局变量的当前*/
    function createFileElement(parentElement){
          globalOne++;
          globalTwo++;

          var tempOne = globalOne;   // 保存全局变量globalOne的当前值
          var tempTwo = globalTwo;   // 保存全局变量globalTwo的当前值

   parentElement.appendChild(document.createTextNode("新增上传图片组件" + globalOne + ":"));
   /** IE创建新元素,并注册事件
          var textFiled3_pic = document.createElement("<input name=/"surveyOptPicfile_" + globalOne + "_" +  (globalTwo+ 1) + "/" >");
          textFiled3_pic.className = "input200";
          textFiled3_pic.setAttribute("id", "surveyOptPicfile_" + globalOne+ "_" + (globalTwo + 1));
          // 注册onchange事件
   textFiled3_pic.attachEvent("onchange", function(){ var id = "surveyOptPicfile_" + tempOne + "_" + (tempTwo + 1); changeSrc(document.getElementById(id), id);});
   */

 

   /** FF创建新元素,并注册事件*/
   var textFiled3_pic = document.createElement("input");
          textFiled3_pic.setAttribute("name", "surveyOptPicfile_" + globalOne+ "_" + (globalTwo+ 1));
          textFiled3_pic.setAttribute("type", "file");
          textFiled3_pic.setAttribute("class", "input200");
          textFiled3_pic.setAttribute("id", "surveyOptPicfile_" + globalOne+ "_" + (globalTwo+ 1));
          textFiled3_pic.addEventListener("change", function(){var id = "surveyOptPicfile_" + tempOne + "_" + (tempTwo + 1); changeSrc(document.getElementById(id), id);}, false);

         

   parentElement.appendChild(textFiled3_pic);    // 把创建的元素追加到父元素中
 
    }

 

// 验证文件格式(当然大家也可在这个函数中做其他一些操作)
function changeSrc(fileObj, fileElementId)
{
  var fileName = fileObj.value;
  if(!fileName.match(//.jpg|/.gif|/.png/ig)){
   alert("您上传的图片格式不正确!");
 return false;
  }
  return true;
}
</script>
</head>
<body>
<form name="form1" id="form1">
请选择图片:<input type="file" name="surveyOptPicfile_0_0" id="surveyOptPicfile_0_0" οnchange="changeSrc(this, 'surveyOptPicfile_0_0')">
<input type="button" value="增加上传组件" οnclick="createFileElement(document.form1);">

</form>
</body>
</html>

 

大家可以直接把上面的代码拷到本地执行!(如果在注册onchange事件的时候不是textFiled3_pic.addEventListener("change", function(){var id = "surveyOptPicfile_" + tempOne + "_" + (tempTwo + 1); changeSrc(document.getElementById(id), id);}, false);        而是使用全局变量textFiled3_pic.addEventListener("change", function(){var id = "surveyOptPicfile_" + globalOne+ "_" + (globalTwo+ 1); changeSrc(document.getElementById(id), id);}, false);   则用新创建的file组件上传图片,不能正确的验证上传的图片格式,即使你上传的格式正确,也会提示你格式错了!大家可以试试!

另:在注册事件中使用关键字this也将不起作用,而是会把它当做普通的字符串!

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值