0

我有 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>
4

5 回答 5

1

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

于 2012-04-23T19:12:18.983 回答
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元素。然后,您使用相同的方法将字符串连接并分配给您的隐藏值,但将值作为参数。

于 2012-04-23T19:14:41.600 回答
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);
});

[更新]

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

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

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

于 2012-04-23T20:16:43.637 回答
0

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

 $().ready(function () { 
    $().dateSelectBoxes($('#release_month'),$('#release_day'),$('#release_year'),true, datepopulate);
});
于 2012-04-23T19:12:58.607 回答
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);
}); 
于 2012-04-23T19:46:15.917 回答