假如有一个页面a.html,会随机返回几组li,现在要
1.把返回的数据加载到containter里
2.计算返回li的数量
3.给每个li绑定事件。
这里使用jQuery,如下:
<ul id="containter"> </ul> <script src="http://lib.sinaapp.com/js/jquery/1.12.4/jquery-1.12.4.min.js"></script> <script> $.get('a.html',function(msg){ //msg值为:<li>aa</li> <li>bb</li> <li>cc</li> $('#containter').html(msg); }); //containter 中li的数量 var liCount = $('#containter li').size(); console.log('li数量:' + liCount); //给li绑定事件,点击输出内部内容 $('#containter li').click(function(){ console.log( $(this).html() ); }); </script>
结果:
输出li的数量为0
点击aa、bb、cc无反应
原因:
由于异步,元素加载不保证顺序,ajax里的containter还没加载完li,就已经执行到下面的计算li数量和绑定事件了。依赖的元素还没出来,就对其进行操作,自然得不到预想的结果。
加载顺序肉眼看不出来,输出点+++ --- 测试下加载顺序:
<ul id="containter"> </ul> <script src="http://lib.sinaapp.com/js/jquery/1.12.4/jquery-1.12.4.min.js"></script> <script> $.get('a.html',function(msg){ $('#containter').html(msg); console.log('+++'); }); //containter 中li的数量 var liCount = $('#containter li').size(); console.log('li数量:' + liCount); //给li绑定事件,点击输出内部内容 $('#containter li').click(function(){ console.log( $(this).html() ); }); console.log('---'); </script>
打开控制台,可以看到先输出了---,然后才输出+++。
解决方法就是等li加载成功后,再来操作li
方法一:
使用setTimeout延迟加载(不推荐)
既然---加载更快,那我们就想办法让它加载慢一点,等ajax加载完再来加载。
<ul id="containter"> </ul> <script src="http://lib.sinaapp.com/js/jquery/1.12.4/jquery-1.12.4.min.js"></script> <script> $.get('a.html',function(msg){ $('#containter').html(msg); console.log('+++'); }); //延迟0.5秒 setTimeout(function(){ //containter 中li的数量 var liCount = $('#containter li').size(); console.log('li数量:' + liCount); //给li绑定事件,点击输出内部内容 $('#containter li').click(function(){ console.log( $(this).html() ); }); console.log('---'); },500); </script>
此时打开控制台,可以看到
li数量:3
点击aa、bb、cc也能看到输出了
方法二:
把操作内容放到ajax里加载li的下面。虽然是异步的,但ajax里面是按顺序执行的。
<ul id="containter"> </ul> <script src="http://lib.sinaapp.com/js/jquery/1.12.4/jquery-1.12.4.min.js"></script> <script> $.get('a.html',function(msg){ $('#containter').html(msg); console.log('+++'); //containter 中li的数量 var liCount = $('#containter li').size(); console.log('li数量:' + liCount); //给li绑定事件,点击输出内部内容 $('#containter li').click(function(){ console.log( $(this).html() ); }); console.log('---'); }); </script>
方法三:
这既然是由ajax的异步引起的问题,那我们把它改为同步好了。
<ul id="containter"> </ul> <script src="http://lib.sinaapp.com/js/jquery/1.12.4/jquery-1.12.4.min.js"></script> <script> //换一个写法设置同步异步。 $.ajax({ url:"a.html" ,type:"GET" ,async:true ,success:function(msg){ $('#containter').html(msg); console.log('+++'); } }); //containter 中li的数量 var liCount = $('#containter li').size(); console.log('li数量:' + liCount); //给li绑定事件,点击输出内部内容 $('#containter li').click(function(){ console.log( $(this).html() ); }); console.log('---'); </script>
参数async是异步的意思,默认为true异步,把它设为false,表示不异步(同步)执行。
方法四:(推荐)
使用jQuery的on的方式绑定事件。
<ul id="containter"> </ul> <script src="http://lib.sinaapp.com/js/jquery/1.12.4/jquery-1.12.4.min.js"></script> <script> $.get('a.html',function(msg){ $('#containter').html(msg); console.log('+++'); //containter 中li的数量 var liCount = $('#containter li').size(); console.log('li数量:' + liCount); }); //给li绑定事件,点击输出内部内容 $('#containter li').on('click',function(){ console.log( $(this).html() ); }); console.log('---'); </script>
这种方法结合了方法二,只是把绑定事件拿出来用on代替了,早期的jQuery用的是live的方法。
另:
其实还有个方法,可以在外面写个函数,然后把onclick事件加到a.html的li中,直接 <li onclick="xx(this)"></li>
function xx(that){ console.log( $(that).html() ); }