延迟onChange javascript函数足够长的时间让另一个javascript完成

时间:2012-04-23 19:05:20

标签: javascript jquery delay onchange

我有3个带onChange函数的选择框来调用脚本来添加所有3个值并将它们放在隐藏字段中。问题是还有另一个脚本根据其他人的值更改框。脚本2在脚本1完成更改选择选项的值之前保存值。

脚本1根据年和月值更新日期值

<script type='text/javascript'>
    $().ready(function () { 
        $().dateSelectBoxes($('#release_month'),$('#release_day'),$('#release_year'),true);
    });
</script> 

脚本2抓住所有3个日期并完成1个完整日期。问题是,这是在脚本1更新当天之前执行的操作。

<script>
     function datepopulate(){
    var day = document.getElementById('release_day').value.substr(-2);
    var month = document.getElementById('release_month').value;
    var year = document.getElementById('release_year').value;
   var completedate = year+'-'+month+'-'+day;
   document.getElementById('releasedate_value').value = completedate;
      alert(document.getElementById('releasedate_value').value);
   return true;
}

</script>

脚本2就像这样调用。而脚本1是自动的

<select onChange="datepopulate();"> </select>

5 个答案:

答案 0 :(得分:1)

您可以使用datepopulate()函数附加jquery .change()事件作为回调选择框并将.ready(...)部分中的逻辑链接起来。

答案 1 :(得分:1)

听起来你只需要从你的jQuery插件中公开一个回调来在点击事件代码被触发后做额外的逻辑。所以你会有这样的事情:

<script type='text/javascript'>
    $().ready(function () { 
        $().dateSelectBoxes($('#release_month'),$('#release_day'),$('#release_year'),true, function()
            {
                // Do Stuff after this plugin does its stuff
            });
    });
</script> 

听起来你已经将两个事件连接到更改事件,并且因为它不是确定性的事件首先被触发,所以你遇到了同步问题。如果您可以通过回调机制对事件进行排序来强制执行此操作,则应解决问题。

编辑:要将代码转换为jQuery,它实际上非常简单。这将是jQuery版本:

var date = $('#release_year').val() + "-" + $('#release_month').val() + "-" + $('#release_day').val();

$('#releasedate_value').val(date);

val()函数将返回查询的元素值。由于您选择了Id,这意味着您将有效地获取元素的value。然后使用相同的方法将字符串连接并将其分配给隐藏值,但将值作为参数。

答案 2 :(得分:0)

向dateSelectBoxes添加一个函数参数,因此它将调用datepopulate本身而不是onchange。

 $().ready(function () { 
    $().dateSelectBoxes($('#release_month'),$('#release_day'),$('#release_year'),true, datepopulate);
});

答案 3 :(得分:0)

不要使用超时在JavaScript中等待事件完成。确保完成任务的唯一方法是回调,对此毫无疑问,否则你会遇到更多麻烦

试试这个:

<script type='text/javascript'>
$(document).ready(function () { 
    $.dateSelectBoxes($('#release_month'),$('#release_day'),$('#release_year'),true);
    $("select").on("change", function(){
            var day = document.getElementById('release_day').value.substr(-2),
        month = document.getElementById('release_month').value,
        year = document.getElementById('release_year').value,
        completedate = year+'-'+month+'-'+day;
        if(day > 0 && month > 0 && year > 0){
            document.getElementById('releasedate_value').value = completedate;
            alert(document.getElementById('releasedate_value').value);
        }
    });
});
</script>

但是,“正确”的方法是使用按钮<input type=button style="display:none">然后在更改时检查每个选择框的值是否为!= 0.然后,如果选择了所有选项,则执行此操作$("button").css("display", "block");然后

$("button").on('click', function(){
    var day = document.getElementById('release_day').value.substr(-2),
    month = document.getElementById('release_month').value,
    year = document.getElementById('release_year').value;
    document.getElementById('releasedate_value').value = year+'-'+month+'-'+day;
    alert(document.getElementById('releasedate_value').value);
}); 

答案 4 :(得分:0)

我认为有必要指出有时候这种方法无法正常工作(从jQuery 1.7开始):

$('#element').html(some_really_large_value);
console.log($('#element').html());

有时DOM更新不会阻止函数执行,控制台中显示的内容将是#element的先前内容。

如果在上面的例子中就是这种情况,那么即使向$ .dateSelectBoxes添加回调也可能无法解决问题。如果仍然没有返回正确的值:

$.dateSelectBoxes( ... $('#release_month') ... , function(){
   console.log($('#release_month').val());
});

然后我知道的唯一解决方案是添加竞争条件:

$.dateSelectBoxes( ... $('#release_month') ... , function(){
   setTimeout(function(){ console.log($('#release_month').val()) }, 100);
});

[UPDATE]

我最近发现这里的问题不是.html()方法不是阻止函数执行,而是浏览器按功能范围对DOM更新进行分组(或类似的东西,有点模糊在细节上)。

这意味着jQuery DOM使用.html()和.val()进行更新,执行阻止,但它们只会阻止使用浏览器调度DOM更新。因此,即使将set读取包装在setTimeout(fn,1)中也可以解决问题。

顺便说一句,这正是Frame.js旨在解决的问题。