在一次jsp页面加载json,在动态的生成Html页面后,想设置生成的html页面的下拉选框的值,结果怎么试都失败了。
$(function(){
var membersJson='<s:property value="membersJson" escape="false"/>';
if(membersJson!=''||membersJson!=""){
var jsonObject=JSON.parse(membersJson);
for(var i=0;i<jsonObject.length;i++){
insertMembersRow();//动态生成html的函数
var userName="userName"+i,idCard1="idCard1"+i,familyRelation="familyRelation"+i,nation1="nation1"+i;
$("#"+userName+"").textbox('setValue',jsonObject[i].userName);
$("#"+idCard1+"").textbox('setValue',jsonObject[i].idCard1);
$("#"+familyRelation+"").combobox({disabled:true});
$("#"+nation1+"").combobox({disabled:true});
$("#"+familyRelation+"").combobox("setValue",jsonObject[i].familyRelation);
$("#"+nation1+"").combobox("setValue",jsonObject[i].nation1);
$("#"+userName+"").textbox({disabled:true});
$("#"+idCard1+"").textbox({disabled:true});
}
}
});
js是基于事件驱动的单线程运行的,但是当js代码在浏览器执行时,浏览器内部是多线程的,其内部常驻5个线程:
1.浏览器 GUI 渲染线程 2.JavaScript 引擎线程 3.浏览器定时触发器线程 4.浏览器事件触发线程 5.浏览器 http 异步请求线程
当运行生成html的函数时,页面渲染 调用了GUI渲染 ,在常驻线程中 浏览器 GUI 渲染线程 和 JavaScript 引擎线程之间是互斥的 ,
当GUI渲染时,js逻辑会进入阻塞,直到渲染完成,当执行js逻辑时,GUI会停止渲染,在生成的html的动态函数中含有easyUI combobox加载json的部分
$("#"+familyRelation+"").combobox("setValue",jsonObject[i].familyRelation);在执行时,虽然页面渲染已经完成了,但是combobox
里的加载选项的json还没有结束,当设置下拉选的值时,还没有来的及加载完,所以设置选项无效,解决方案是设置了一下延迟设置值,这样可以等到页面渲染完后combobox里的
json可以加载完,代码如下:
$(function(){
var membersJson='<s:property value="membersJson" escape="false"/>';
if(membersJson!=''||membersJson!=""){
var jsonObject=JSON.parse(membersJson);
for(var i=0;i<jsonObject.length;i++){
insertMembersRow();
(function(i){
setTimeout(function(){
var userName="userName"+i,idCard1="idCard1"+i,familyRelation="familyRelation"+i,nation1="nation1"+i;
$("#"+userName+"").textbox('setValue',jsonObject[i].userName);
$("#"+idCard1+"").textbox('setValue',jsonObject[i].idCard1);
$("#"+familyRelation+"").combobox({disabled:true});
$("#"+nation1+"").combobox({disabled:true});
$("#"+familyRelation+"").combobox("setValue",jsonObject[i].familyRelation);
$("#"+nation1+"").combobox("setValue",jsonObject[i].nation1);
$("#"+userName+"").textbox({disabled:true});
$("#"+idCard1+"").textbox({disabled:true});
},10);
})(i);
}
}
});
浏览器在执行setTimeout时会交由浏览器定时触发器线程处理,javaScript引擎线程会跳过setTimeout的部分接着往下执行,当浏览器的定时触发器线程等到了setTimeout里
设置的值后,会重新将任务交由javaScript引擎处理,javaScript引擎的处理机制是由事件驱动的,事件排列在任务队列里等待执行,当到了setTimeout设定的延迟时间后,会将任务重新放入
任务队列里等待执行。
往setTimeout函数里传参有三种方式:
1. var a=50;
setTimeout("funA(a)",100);将执行函数部分加上引号
2. var a=50;
setTimeout(funB(a),100);
function funB(a){
return function(a){
funA(a);
}
},定义了一个函数funB,用于接收一个参数,并返回一个不带参数的函数
3.通过修改settimeout、setInterval实现参数传递,
参考代码:https://blog.youkuaiyun.com/qq_34131399/article/details/79221128var userName="jack";
//根据用户名显示欢迎信息
function hello(_name){
alert("hello,"+_name);
}
// 功能: 修改 window.setInterval ,使之可以传递参数和对象参数
// 方法: setInterval (回调函数,时间,参数1,,参数n) 参数可为对象:如数组等
var __sto = setInterval;
window.setInterval = function(callback,timeout,param){
var args = Array.prototype.slice.call(arguments,2);
var _cb = function(){
callback.apply(null,args);
}
__sto(_cb,timeout);
}
window.setInterval(hello,3000,userName);