easyUi combobox setValue 引起的关于js的坑

解决JS在动态生成HTML页面时,设置下拉选框值无效的问题,通过使用setTimeout延迟设置值,确保页面渲染和下拉框加载完成后进行设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在一次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/79221128

     var 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);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值