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

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

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

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

<ul id="ulDemo">
  <li>数据</li>
  <li>数据</li>
  <li>数据</li>
  <li>数据</li>
  <li>数据</li>
</ul>

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

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

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

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

其他写法

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

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

示例代码:

//初始化mescroll1
function initmescroll1(){
	var mescroll1 = new MeScroll("mescroll1", {
		up: {
			auto: true, //是否在初始化时以上拉加载的方式自动加载第一页数据; 默认false
			isBounce: false, //此处禁止ios回弹,解析(务必认真阅读,特别是最后一点): http://www.mescroll.com/qa.html#q10
			callback: upCallback, //上拉回调,此处可简写; 相当于 callback: function (page) { upCallback(page); }
			clearEmptyId: "dataList", //1.下拉刷新时会自动先清空此列表,再加入数据; 2.无任何数据时会在此列表自动提示空
			page: {
				num: 0, //当前页 默认0,回调之前会加1; 即callback(page)会从1开始
				size: 10 //每页数据条数,默认10
			},
			toTop:{ //配置回到顶部按钮
				src : "../images/mescroll-totop.png", //默认滚动到1000px显示,可配置offset修改
				offset : 1000
			}
		}
	});

	/*上拉加载的回调 page = {num:1, size:10}; num:当前页 从1开始, size:每页数据条数 */
	function upCallback(page){
		ajaxSyncRequest(getContextPath() + "getServiceRecord", {"phone": userPhone, "pageNo": page.num}, function(data){
			if(data.success){
				//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
				//mescroll会根据传的参数,自动判断列表如果无任何数据,则提示空;列表无下一页数据,则提示无更多数据;
				//方法一(推荐): 后台接口有返回列表的总页数 totalPage
				mescroll1.endByPage(data.data.rows.length, data.data.totalPage); //必传参数(当前页的数据个数, 总页数)
				//方法二(推荐): 后台接口有返回列表的总数据量 totalSize
				//mescroll.endBySize(curPageData.length, totalSize); //必传参数(当前页的数据个数, 总数据量)
				//方法三(推荐): 您有其他方式知道是否有下一页 hasNext
				//mescroll.endSuccess(curPageData.length, hasNext); //必传参数(当前页的数据个数, 是否有下一页true/false)
				//方法四 (不推荐),会存在一个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据当前页的数据个数判断,则需翻到第三页才会知道无更多数据,如果传了hasNext,则翻到第二页即可显示无更多数据.
				//mescroll1.endSuccess(curPageData.length);
				//设置列表数据
				if(data.data.totalPage == "1" && data.data.rows.length == 0){
					$("#mescroll1 .app_empty").show();
				}else{
					$("#mescroll1 .app_empty").hide();
					setListData(data.data.rows);
				}
			}else{
				//联网失败的回调,隐藏下拉刷新的状态
	            mescroll1.endErr();
			}
		});
	}
	
	/*设置列表数据*/
	function setListData(curPageData){
		var listDom = document.getElementById("dataList");
		for (var i = 0; i < curPageData.length; i++) {
			var data = curPageData[i];
			var str='<p class="app_dl_t">'+data.station_name+'-'+data.charge_id+'<span class="fr col_ob">'+data.order_status+'</span></p>';
			str+='<p class="app_dl_i">';
			str+='<label>充电电量:'+data.charged_capacity+'度'+'</label>';
			str+='<label>开始时间:'+data.start_time+'</label>';
			str+='<label>结束时间:'+data.end_time+'</label>';
			str+='<i><font class="col_oo">'+data.money+'</font>元</i></p>';
			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>';
			var liDom = document.createElement("li");
			liDom.innerHTML = str;
			addClickListener(liDom, data);
			listDom.appendChild(liDom);
		}
	}
	
	/*添加列表点击事件*/
	function addClickListener(el, data){
		$(el).on('click', function(){
			alert(data.order_num);
		});
	}
}

完!!!

发布了106 篇原创文章 · 获赞 65 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/xialong_927/article/details/88991309