js动态循环绑定事件的变量问题,动态循环添加元素并绑定事件出现重复的问题

迷南。 2022-02-24 06:00 376阅读 0赞

在编写JS的时候我们经常会遇到要对一系列元素进行事件绑定,循环对元素的事件进行赋值,在这个过程中我们会遇到一个问题,那就每个元素事件运行的时候变量怎么都是相同的值。

这里涉及到变量的作用域的问题,可以用闭包来解决这个问题。

这里举个简单的列子来说明:


      
  • 数据

  •   
  • 数据

  •   
  • 数据

  •   
  • 数据

  •   
  • 数据

我们来给这些li添加一个onclick事件,弹出li是第几条数据

  1. var list = document.getElementById("ulDemo").getElementsByTagName("li");
  2. for (var i = 0; i < list.length; i++) {
  3. var li = list[i];
  4. li.onclick= function () {
  5. alert("第" + (i + 1) + "条" + this.innerHTML);
  6. }
  7. }

结果弹出的都是第6条数据,这里的onclick函数中的变量i指向的内存地址,经过循环之后i变成了5,所有的li的点击事件都在同一个作用域中,我们可以通过闭包把i的作用域独立出来。

  1. var list = document.getElementById("ulDemo").getElementsByTagName("li");
  2. for (var i = 0; i < list.length; i++) {
  3. var li = list[i];
  4. li.onclick= (function (index) {
  5. return function () { alert("第" + (index + 1) + "条" + this.innerHTML) };
  6. })(i);
  7. }

其他写法

  1. for (var i = 0; i < list.length; i++) {
  2. var li = list[i];
  3. var addClick = function (el, index) {
  4. el.onclick= function () { alert("第" + (index + 1) + "条" + this.innerHTML) };
  5. };
  6. addClick(li, i);
  7. }

  1. for (var i = 0; i < list.length; i++) {
  2. var li = list[i];
  3. (function (el,index) {
  4. el.onclick= function () { alert("第" + (index + 1) + "条" + this.innerHTML) };
  5. })(li,i);
  6. }

示例代码:

  1. //初始化mescroll1
  2. function initmescroll1(){
  3. var mescroll1 = new MeScroll("mescroll1", {
  4. up: {
  5. auto: true, //是否在初始化时以上拉加载的方式自动加载第一页数据; 默认false
  6. isBounce: false, //此处禁止ios回弹,解析(务必认真阅读,特别是最后一点): http://www.mescroll.com/qa.html#q10
  7. callback: upCallback, //上拉回调,此处可简写; 相当于 callback: function (page) { upCallback(page); }
  8. clearEmptyId: "dataList", //1.下拉刷新时会自动先清空此列表,再加入数据; 2.无任何数据时会在此列表自动提示空
  9. page: {
  10. num: 0, //当前页 默认0,回调之前会加1; 即callback(page)会从1开始
  11. size: 10 //每页数据条数,默认10
  12. },
  13. toTop:{ //配置回到顶部按钮
  14. src : "../images/mescroll-totop.png", //默认滚动到1000px显示,可配置offset修改
  15. offset : 1000
  16. }
  17. }
  18. });
  19. /*上拉加载的回调 page = {num:1, size:10}; num:当前页 从1开始, size:每页数据条数 */
  20. function upCallback(page){
  21. ajaxSyncRequest(getContextPath() + "getServiceRecord", {"phone": userPhone, "pageNo": page.num}, function(data){
  22. if(data.success){
  23. //联网成功的回调,隐藏下拉刷新和上拉加载的状态;
  24. //mescroll会根据传的参数,自动判断列表如果无任何数据,则提示空;列表无下一页数据,则提示无更多数据;
  25. //方法一(推荐): 后台接口有返回列表的总页数 totalPage
  26. mescroll1.endByPage(data.data.rows.length, data.data.totalPage); //必传参数(当前页的数据个数, 总页数)
  27. //方法二(推荐): 后台接口有返回列表的总数据量 totalSize
  28. //mescroll.endBySize(curPageData.length, totalSize); //必传参数(当前页的数据个数, 总数据量)
  29. //方法三(推荐): 您有其他方式知道是否有下一页 hasNext
  30. //mescroll.endSuccess(curPageData.length, hasNext); //必传参数(当前页的数据个数, 是否有下一页true/false)
  31. //方法四 (不推荐),会存在一个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据当前页的数据个数判断,则需翻到第三页才会知道无更多数据,如果传了hasNext,则翻到第二页即可显示无更多数据.
  32. //mescroll1.endSuccess(curPageData.length);
  33. //设置列表数据
  34. if(data.data.totalPage == "1" && data.data.rows.length == 0){
  35. $("#mescroll1 .app_empty").show();
  36. }else{
  37. $("#mescroll1 .app_empty").hide();
  38. setListData(data.data.rows);
  39. }
  40. }else{
  41. //联网失败的回调,隐藏下拉刷新的状态
  42. mescroll1.endErr();
  43. }
  44. });
  45. }
  46. /*设置列表数据*/
  47. function setListData(curPageData){
  48. var listDom = document.getElementById("dataList");
  49. for (var i = 0; i < curPageData.length; i++) {
  50. var data = curPageData[i];
  51. var str='<p class="app_dl_t">'+data.station_name+'-'+data.charge_id+'<span class="fr col_ob">'+data.order_status+'</span></p>';
  52. str+='<p class="app_dl_i">';
  53. str+='<label>充电电量:'+data.charged_capacity+'度'+'</label>';
  54. str+='<label>开始时间:'+data.start_time+'</label>';
  55. str+='<label>结束时间:'+data.end_time+'</label>';
  56. str+='<i><font class="col_oo">'+data.money+'</font>元</i></p>';
  57. str+='<p class="app_dl_b"><a href="javascript:void(0);" class="fr curr_bt">申请售后</a><a href="javascript:void(0);" class="fr curr_bt">服务评价</a></p>';
  58. var liDom = document.createElement("li");
  59. liDom.innerHTML = str;
  60. addClickListener(liDom, data);
  61. listDom.appendChild(liDom);
  62. }
  63. }
  64. /*添加列表点击事件*/
  65. function addClickListener(el, data){
  66. $(el).on('click', function(){
  67. alert(data.order_num);
  68. });
  69. }
  70. }

完!!!

发表评论

表情:
评论列表 (有 0 条评论,376人围观)

还没有评论,来说两句吧...

相关阅读

    相关 jQuery动态事件

    jquery中绑定事件一般使用bind,或者click,但是这只能是对已经加载好的元素定义事件,那些后来添加插入的元素则需要另行绑定。在1.7版本以前使用live。但是在1.8

    相关 js动态循环事件变量问题

    在编写JS的时候我们经常会遇到要对一系列元素进行事件绑定,循环对元素的事件进行赋值,在这个过程中我们会遇到一个问题,那就每个元素事件运行的时候变量怎么都是相同的值。 这里涉及