今天写原生javascript时,想利用绑定事件实现类似jquery中on方法的功能:于是有了for循环里绑定事件,无意中发现定义类能解决好多问题!

例如:一个不确定长度的列表,在鼠标经过某一条的时候改变背景

 1
 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 3 <html xmlns="http://www.w3.org/1999/xhtml" >
 4 <head>
 5 <title>Untitled Page</title>
 6 </head>  7 <body>  8 <ul id="list">  9 <li>第1条记录</li> 10 <li>第2条记录</li> 11 <li>第3条记录</li> 12 <li>第4条记录</li> 13 <li>第5条记录</li> 14 <li>第6条记录</li> 15 </ul> 16 <script type="text/javascript"> 17 var list_obj = document.getElementById("list").getElementsByTagName("li"); //获取list下面的所有li的对象数组 18 for (var i = 0; i <= list_obj.length; i++) { 19 list_obj[i].onmouseover = function() { 20 this.style.backgroundColor = "#cdcdcd"; 21 } 22 list_obj[i].onmouseout = function() { 23 this.style.backgroundColor = "#FFFFFF"; 24 } 25 } 26 </script> 27 </body> 28 </html> 

继续:添加一个显示“这是第几条记录”的功能

 1
 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 3 <html xmlns="http://www.w3.org/1999/xhtml" >
 4 <head>
 5 <title>Untitled Page</title>
 6 </head>  7 <body>  8 <ul id="list">  9 <li>第1条记录</li> 10 <li>第2条记录</li> 11 <li>第3条记录</li> 12 <li>第4条记录</li> 13 <li>第5条记录</li> 14 <li>第6条记录</li> 15 </ul> 16 <script type="text/javascript"> 17 var list_obj = document.getElementById("list").getElementsByTagName("li"); //获取list下面的所有li的对象数组 18 for (var i = 0; i <= list_obj.length; i++) { 19 list_obj[i].onmousemove = function() { 20 this.style.backgroundColor = "#cdcdcd"; 21 } 22 list_obj[i].onmouseout = function() { 23 this.style.backgroundColor = "#FFFFFF"; 24 } 25 list_obj[i].onclick = function() { 26 alert("这是第" + i + "记录"); 27 } 28 } 29 </script> 30 </body> 31 </html> 

运行后我们发现,一直不论点击哪个li都显示“这是第6条记录”。

其实这里for循环已将整个列表循环了一遍,并执行了i++,所以这里i变成了6。

有什么好的办法解决这个问题吗?  
  看看什么是闭包:
  闭包时是指内层的函数可以引用存在与包围他的函数内的变量,即使外层的函数的执行已经终止。
  这个例子中我们可以这样做:

 1
 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 3 <html xmlns="http://www.w3.org/1999/xhtml" >
 4 <head>
 5 <title>Untitled Page</title>
 6 </head>  7 <body>  8 <ul id="list">  9 <li>第1条记录</li> 10 <li>第2条记录</li> 11 <li>第3条记录</li> 12 <li>第4条记录</li> 13 <li>第5条记录</li> 14 <li>第6条记录</li> 15 </ul> 16 <script type="text/javascript"> 17 function tt(nob) { 18 this.clickFunc = function() { 19 alert("这是第" + (nob + 1) + "记录"); 20 } 21 } 22 var list_obj = document.getElementById("list").getElementsByTagName("li"); //获取list下面的所有li的对象数组 23 for (var i = 0; i <= list_obj.length; i++) { 24 list_obj[i].onmousemove = function() { 25 this.style.backgroundColor = "#cdcdcd"; 26 } 27 list_obj[i].onmouseout = function() { 28 this.style.backgroundColor = "#FFFFFF"; 29 } 30 var col = new tt(i); 31 list_obj[i].onclick = col.clickFunc; 32 } 33 </script> 34 </body> 35 </html> 

  经过以上文章可以得知,引起这个问题的原因其实是因为js的闭包难题。按照面向对象的JAVA语言的理解可以解释为:js循环动态绑定带参数函 数中的参数,其实相当于java中的引用传递,而非值传递。传递进来的引用只相当于一个指针,指向的是一个内存地址,这个内存地址存放的才是具体的值,而 外面的循环会不断的修改这个存放地址中的值,所以最后循环结束之后,参数的值只能找到最后一个。
知道了原因就很好解决了。New一个新的“函数类”(姑且这么称呼吧)。测试OK。一下是修改后的代码:

 1
 2 //在新增按钮上绑定函数
 3 document.getElementById("add").attachEvent("onclick",addFunction);  4 var jc_count = 0;//定义需要改变第几行的值  5 function txzmcFunction(x,y){//下拉框中绑定的函数  6 var sql="select txzjc from dm_txzmc where dm='"+x.value+"'";//取得下拉框中的代码,通过ajax获得相应的中文名称  7 jc_count = y;//定义当前行是第几行  8 ajaxSelect(sql,"txzjcFunction");//封装的ajax函数  9 } 10 function txzjcFunction(x){//接收封装的ajax函数返回值,并赋值 11 document.getElementById("_subarea_hxax_clzjxxb_hxax_txzxxb_update_txzjc_"+jc_count).value=x; 12 } 13 function bb(dx,sz){//解决动态绑定闭包问题要用到函数 14 this.clickFunc=function(){ 15 txzmcFunction(dx,sz);//调用相应的函数 16 } 17 } 18 function addFunction(){ //动态循环绑定 19 var count=document.getElementById("_subarea_hxax_clzjxxb_hxax_txzxxb_update_maxcount").value;//获取最大的行数 20 for (var i=0;i<count ;i++ )//循环绑定 21 { 22 var obj=document.getElementById("_subarea_hxax_clzjxxb_hxax_txzxxb_update_txzmc_" +i); 23 var tp = new bb(obj,i);//解决闭包问题,new一个新的函数类 24 obj.onchange = tp.clickFunc; 25 } 26 } 27 //显示页面时执行一次 28 addFunction(); 

转载于:https://www.cnblogs.com/zhhc/p/4704481.html

js循环动态绑定带参数函数遇到的问题及解决方案[转]相关推荐

  1. js setTimeout 传递带参数的函数的2种方式

    js setTimeout 传递带参数的函数的2种方式 Created by Marydon on 2018年9月14日 1.准备工作 function sayYourName(param) {ale ...

  2. JS调用后台带参数的方法

    JS调用后台带参数的方法 对于前台调用后台的方法,我们想到最多的就是用AJAX,这个是毋庸置疑的, 我就不再这里多说了.我今天主要想说的是用JS调用后台的方法. 对于后台往前台传值,用这种<%= ...

  3. SQLAlchemy中模糊查询;JS中POST带参数跳转;JS获取url参数

    SQLAlchemy中模糊查询,如何like多个关键字 JS中POST带参数跳转 一个项目中要跳转到另外一个项目,还需要带参数 考虑到安全性的问题,最好是用POST跳转,不能再URL中拼参 所以找到了 ...

  4. python怎么来算面积_Python实现计算长方形面积(带参数函数demo)

    Python实现计算长方形面积(带参数函数demo) 如下所示: # 计算面积函数 def area(width, height): return width * height def print_w ...

  5. python装饰器带参数函数_python带参数装饰器的两种写法

    python带参数装饰器的两种写法 前言 最近在实现一个装饰器的过程中发现了一个很有意思的地方,在博客里面分享出来 不同的写法 三层函数嵌套,实现了可传参数的一个装饰器. import logging ...

  6. c# 多线程 调用带参数函数

    线程操作主要用到Thread类,他是定义在System.Threading.dll下.使用时需要添加这一个引用.该类提供给我们四个重载的构造函数(以下引自msdn). Thread (Paramete ...

  7. bat循环执行带参数_C++:main处理命令行选项/main函数的参数

    main函数参数 通常,定义main函数形参列表都是空的,遇到有参数的main函数到不知道怎么理解了. 给main函数传递实参,常见的情况是传递命令参数. int main(int argc, cha ...

  8. bat循环执行带参数_wxappUnpacker的bingo.bat脚本逐行解读

    点击上方"蓝字"关注我们 之前发过一篇文章小程序反编译工具在windows系统下的调用脚本提到了Windows平台下的脚本,但是对脚本没有做详细说明.本文就是针对脚本做的讲解.对批 ...

  9. python装饰器带参数函数二阶导数公式_SICP Python 描述 1.6 高阶函数

    1.6 高阶函数 我们已经看到,函数实际上是描述复合操作的抽象,这些操作不依赖于它们的参数值.在square中, >>> def square(x): return x * x 我们 ...

最新文章

  1. opencv函数总结
  2. Jira接入钉钉机器人
  3. 浅谈TCP/IP网络编程中socket的行为
  4. adb server is out of date killing
  5. 51单片机蜂鸣器播放音乐
  6. 重磅来袭,机器人四大家族财务报表大揭秘
  7. 游戏策划学习(一)游戏研发基础
  8. 阿里云主机项目根目录指向public目录下
  9. python_大智慧SAR指标编写
  10. 大数据是让人幸福的科学
  11. IT出路:跳出TCO,着眼TVO(总体拥有价值)
  12. linux 多核cpu监控,Linux 下多核CPU知识
  13. 整除7,9,11的数的性质
  14. Legolas工业自动化平台入门(二)数据响应动作
  15. [转]手机号码归属地接口
  16. ibatis Clob
  17. 电子拍卖系统开发第二天
  18. python opencv 直方图均衡_Python+OpenCV:全局直方图均衡化、局部直方图自适应均衡化、直方图比较(Python版)...
  19. threejs加载obj文件
  20. 从零开始搭建游戏服务器 第一节 创建一个简单的服务器架构

热门文章

  1. 2022-2028年中国地铁广告行业研究及前瞻分析报告
  2. Mysql,SqlServer,Oracle主键自动增长的设置
  3. kali2020进入单模式_蚂蚁集团技术专家山丘:性能优化的常见模式及趋势
  4. Ubuntu 打 deb 包报错(fpm not found、dos2unix not found)
  5. 用python快速画小猪佩奇
  6. centos7下selinux永久关闭
  7. pycharm重点插件
  8. Bert系列(二)——源码解读之模型主体
  9. Java基本数据之间的类型转换
  10. 功率半导体碳化硅(SiC)技术