JAVALin 2013-05-29
今天遇到一个问题,因业务需求的变化需要动态的加载一些Dom节点,而初始化时的绑定事件对新加载的Dom节点不起作用,后来查询发现::事件的绑定需要给每个元素单独绑定事件,而事件的初始化时只给存在的Dom节点绑定事件了,而新加载的Dom节点是没有绑定事件的。
<body>
<div class="">
<p id="p1">p1</p>
<p id="p2">p2</p>
<p id="p3">p3</p>
</div>
</body>
如下实例重现该问题:
<script type="text/javascript">
$(document).ready(function(){
$('p').hover(function(){
var pContent = $(this).html(); // !!!!!!!!!!!!!! this指Dom元素-----打印是Object #
<HTMLParagraphElement> $(this)------jquery对象
alert(pContent);
});
var addPDom = '<p class="p4">p4</p>';
$('div').append(addPDom); // 动态新添加的Dom元素就没有绑定事件
});
</script>
比较常用的解决办法:见文件【jquery 新建的元素事件绑定问题】
其中,使用在新增加的Dom上添加点击onclick事件:
var radioInitClick=function(){ var layer = $("#layer_dept_list"); var ref = $("#dept_uid"); layer.find("input[type='radio']").on("click",function(){ var deptUid = $(this).attr("action-uid"); var deptName = $(this).val(); setDept(ref,deptName,deptUid); hideLayer(layer,ref); }); } //点击上下级 var reSetDept = function(deptPid,nowDeptUid){ deptShow(dept_list,deptPid,nowDeptUid); } var showLayer = function(layer,ref){ layer.show(); //layer.alignTo(ref,"tl-tl"); }; var hideLayer = function(layer,ref){ layer.hide(); ref.blur(); }; var setDept = function(ref,deptName,deptUid){ ref.val(deptName); ref.attr("action-uid",deptUid); }; var initLayerEvent = function(layer,ref){ layer.attr("action-event","ok"); layer.find(".layer_close").on("click",function(){ hideLayer(layer,ref); }); radioInitClick(); } $("#dept_uid").on("focus",function(){ $(this).blur(); var layer = $("#layer_dept_list"); if(layer.attr("action-event") == "none"){ initLayerEvent(layer,$(this)); } showLayer(layer,$(this)); }); var deptShow=function(dept_list,pid,nowDeptUid){ var tempPid = 0; var tempUid = 0; var tempNickName = 0; var parentDept = ""; var parentDept = ""; var nowDept = ""; var childrenDept = ""; for(index in dept_list){ tempPid = dept_list[index]['pid']; tempUid = dept_list[index]['uid']; tempNickName = dept_list[index]['nick_name']; //父级 if(pid != -1 && pid == tempUid){ parentDept = '<LABEL style="color: #666;" title="'+tempNickName+'">' + '<A href="javascript:reSetDept('+tempPid+','+tempUid+');" style="font-weight: normal; color:#666 ;padding-right:0px;" class="dept-link" action-uid="' + tempUid+'" hidefocus>'+tempNickName+'</A>' + '</LABEL>' + '<span> >> </span>'; } //当前级 if(tempUid == nowDeptUid){ nowDept = '<LABEL title="'+tempNickName+'">' + '<INPUT class="input_checkbox" type="radio" hidefocus value="'+ tempNickName +'" action-uid="' + tempUid+'"name="dept-items" />' + '<span>'+ tempNickName +'</span>'; + '</LABEL>'; } //下级 if(tempPid == nowDeptUid){ childrenDept = childrenDept +'<LI><LABEL style="color: #666;" title="'+tempNickName+'">' + '<INPUT class="input_checkbox" type="radio" hidefocus action-uid="' + tempUid+'" value="'+tempNickName+'" name="dept-items"/>' + '<A href="javascript:reSetDept('+nowDeptUid+','+tempUid +');" class="dept-link" hidefocus>'+tempNickName+'</A>' + '</LABEL></LI>'; } } $("#layer_title").html(parentDept); $("#layer_title").append(nowDept); $("#layer_all_list").html(childrenDept); radioInitClick(); }; //初始化pid=-1最上级 if(dept_list != null){ deptShow(dept_list,-1,sessionUid); }
可以在加载完Dom节点之后再重复初始化已绑定事件:
例如 $('a').on('click',function(){
//注意:其中,此处使用this指A节点的Dom元素节点,如果在html里面onclick=function(this---window窗口),可以将需要的参数使用 属性的形式放在A节点的属性里,然后在funcction里使用this的Dom元素获取需要的参数
})
var showLayer = function(layer,ref){ layer.show(); //layer.alignTo(ref,"tl-tl"); }; var hideLayer = function(layer,ref){ layer.hide(); ref.blur(); }; var setDept = function(ref,deptName,deptUid){ ref.val(deptName); ref.attr("action-uid",deptUid); }; var initLayerEvent = function(layer,ref){ layer.attr("action-event","ok"); layer.find(".layer_close").on("click",function(){ hideLayer(layer,ref); }); } $("#dept_uid").on("focus",function(){ $(this).blur(); var layer = $("#layer_dept_list"); if(layer.attr("action-event") == "none"){ initLayerEvent(layer,$(this)); } showLayer(layer,$(this)); }); var deptShow=function(dept_list,pid,nowDeptUid){ var tempPid = 0; var tempUid = 0; var tempNickName = 0; var parentDept = ""; var parentDept = ""; var nowDept = ""; var childrenDept = ""; for(index in dept_list){ tempPid = dept_list[index]['pid']; tempUid = dept_list[index]['uid']; tempNickName = dept_list[index]['nick_name']; //父级 if(pid != -1 && pid == tempUid){ parentDept = '<LABEL style="color: #666;" title="'+tempNickName+'">' + '<A href="javascript:void(0);" style="font-weight: normal; color:#666 ;padding-right:0px;" class="dept-link" action-uid="' + tempUid+'" action-pid ="'+tempPid+'" hidefocus>'+tempNickName+'</A>' + '</LABEL>' + '<span> >> </span>'; } //当前级 if(tempUid == nowDeptUid){ nowDept = '<LABEL title="'+tempNickName+'">' + '<INPUT class="input_checkbox" type="radio" hidefocus value="'+ tempNickName +'" action-uid="' + tempUid+'"name="dept-items" />' + '<span>'+ tempNickName +'</span>'; + '</LABEL>'; } //下级 if(tempPid == nowDeptUid){ childrenDept = childrenDept +'<LI><LABEL style="color: #666;" title="'+tempNickName+'">' + '<INPUT class="input_checkbox" type="radio" hidefocus action-uid="' + tempUid+'" value="'+tempNickName+'" name="dept-items"/>' + '<A href="javascript:void(0);" class="dept-link" action-pid ="'+nowDeptUid+'" action-uid ="'+tempUid+'" hidefocus>'+tempNickName+'</A>' + '</LABEL></LI>'; } } $("#layer_title").html(parentDept); $("#layer_title").append(nowDept); $("#layer_all_list").html(childrenDept); //初始化上下级链接的绑定事件 $('.dept-link').on('click',function(){ var deptPid = $(this).attr('action-pid'); var ownDeptUid = $(this).attr('action-uid'); deptShow(dept_list,deptPid,ownDeptUid); }); $('.input_checkbox').on('click',function(){ var deptUid = $(this).attr("action-uid"); var deptName = $(this).val(); var layer = $("#layer_dept_list"); var ref = $("#dept_uid"); setDept(ref,deptName,deptUid); hideLayer(layer,ref); }); }; //初始化pid=-1最上级 if(dept_list != null){ deptShow(dept_list,-1,sessionUid); }
Vue和React是数据驱动视图,如何有效控制DOM操作?能不能把计算,更多的转移为js计算?因为js执行速度很快。patch函数-->patch,对比tag,对比tag与key,对比children