Jquery 异步触发 2 个触发事件

Jquery fire 2 trigger events asynchronously

我有 2 个事件需要异步触发,因为第二个事件依赖于第一个事件。

目前我有:

$(document).ready(function() {
    $("#CourseID").trigger('change');
    $("#ClearAll").trigger('click');
});

这是 2 个事件:

    $('#CourseID').change(function() {
alert('Inside CourseID change event');
        Required(document.getElementById('CourseID').value, 'CourseID', 'err_CourseID');
        // Get Hole information & display in Holes
        var CourseID = document.getElementById('CourseID').value;
        document.getElementById('db_CourseID').value = CourseID;
        if(CourseID.length<1) { 
            var holes = document.getElementById('num_holes').value;
            for(i=1; i<=holes; i++) {
                id = "holes_"+i;
                $('#'+id).prop('checked', false);
            }
            document.getElementById('num_holes').value = 0;
            document.getElementById('hole_error').style.display = "inline";
            document.getElementById('holes').style.display = "none";
            document.getElementById('front9').style.display = "none";
            document.getElementById('mid9').style.display = "none";
            document.getElementById('back9').style.display = "none";
            document.getElementById('ClearAll').style.display = "none";
            document.getElementById('SelectAll').style.display = "none";
            chkCheckboxes();
            return; 
        } else {
            document.getElementById('hole_error').style.display = "none";
            document.getElementById('holes').style.display = "inline";
            // Select All Holes
            var holes = document.getElementById('num_holes').value;
            for(i=1; i<=holes; i++) {
                id = "holes_"+i;
                $('#'+id).prop('checked', true);
            }
        }

        $.ajax({
            url: "/P3Live/_includes/php/get_playable_holes.php",
            type: "post",
            dataType: 'json',
            data: {CourseID: CourseID},
            success: function(response) {
                if (response.status == "success") {
                    // We need to clear the existing div so when we append it is doing so to an empty field
                    $('#holes').empty();
                    var str = response.message + ''; /* We add the blank space to assure it is recognized as a string */
                    var holes = str.split(",");
                    var sections = holes.length/9;
alert('Setting num_holes');
                    document.getElementById('num_holes').value = holes.length;
                    for(i=0; i<sections; i++) {
                        for(j=0; j<9; j++) {
                            holeNum = (i*9)+j;
                            if(holes.length<holeNum) { continue; }
                            addCheckbox(holes[holeNum]);
                            id='holes_'+holes[holeNum];
                        }
                        var html = $("#holes").html();
                        html = html + "<br />"; // creates a new line after each section of 9 holes
                        $("#holes").html(html);
                    }
                    // We need to have the entire holes div populated before we can check the boxes
                    for(i=0; i<holes.length; i++) {
                        id='holes_'+holes[i];
                        $("#"+id).prop("checked", true);
                    }
                    chkCheckboxes();
                    // Now let's setup which buttons should be visible
                    switch (sections) {
                        case 0:
                            document.getElementById('front9').style.display = "none";
                            document.getElementById('mid9').style.display = "none";
                            document.getElementById('back9').style.display = "none";
                            document.getElementById('ClearAll').style.display = "none";
                            document.getElementById('SelectAll').style.display = "none";
                            break;
                        case 1:
                            document.getElementById('front9').style.display = "inline";
                            document.getElementById('mid9').style.display = "none";
                            document.getElementById('back9').style.display = "none";
                            document.getElementById('ClearAll').style.display = "inline";
                            document.getElementById('SelectAll').style.display = "inline";
                            break;
                        case 2:
                            document.getElementById('front9').style.display = "inline";
                            document.getElementById('mid9').style.display = "none";
                            document.getElementById('back9').style.display = "inline";
                            document.getElementById('ClearAll').style.display = "inline";
                            document.getElementById('SelectAll').style.display = "inline";
                            break;
                        case 3:
                            document.getElementById('front9').style.display = "inline";
                            document.getElementById('mid9').style.display = "inline";
                            document.getElementById('back9').style.display = "inline";
                            document.getElementById('ClearAll').style.display = "inline";
                            document.getElementById('SelectAll').style.display = "inline";
                            break;

                    }       
                } else {
                    alert(response.message);
                }
            },
            error: function(response) {
                for (var k in response){
                    if (typeof response[k] !== 'function') {
                         console.log("Key is " + k + ", value is " + response[k]);
                    }
                }
            }
        });
    })

此事件从另一个字段中获取 CourseID,并从数据库中检索有关孔数的信息。然后它为每个孔创建复选框并默认选中它们。它还设置某些按钮的显示状态。其中之一,是我要触发的次要事件。

    $("#ClearAll").click(function() {
        var holes = document.getElementById('num_holes').value;
alert('Inside ClearAll Event.  Holes:'+holes);
        for(i=1; i<=holes; i++) {
            id = "holes_"+i;
            $('#'+id).prop('checked', false);
        }
        chkCheckboxes();
    })

如您所见,我插入了警报以查看它们触发的顺序。我的问题是 ClearAll 事件在显示孔复选框之前触发('Setting num_holes' 警报显示在 'Inside ClearAll Event...' 之后)。

如果您能帮助我们异步触发,我们将不胜感激。我不想使用 SetTimeout(),因为时间可能因用户的计算机而异。

您可以将更改事件函数放入命名函数中并添加将在 ajax:

之后触发的回调
function OnChangeEvent(callback) {
    Required(document.getElementById('CourseID').value, 'CourseID', 'err_CourseID');
    ...
    $.ajax({
        url: "/P3Live/_includes/php/get_playable_holes.php",
        type: "post",
        dataType: 'json',
        data: {CourseID: CourseID},
        success: function(response) {
            ...
            if (typeof callback == 'function') {
                callback();
            }
        },
        error: function(response) {
            for (var k in response){
                if (typeof response[k] !== 'function') {
                     console.log("Key is " + k + ", value is " + response[k]);
                }
            }
            if (typeof callback == 'function') {
                callback();
            }
        }
    });
}

并且您将此函数用作:

$('#CourseID').change(OnChangeEvent);

$(document).ready(function() {
    OnChangeEvent(function() {
        $("#ClearAll").trigger('click');
    });
});

能否将 ClearAll 触发器移动到 $("#CourseID").trigger('change') 事件中 ajax 成功回调的末尾?

我通过执行以下操作解决了这个问题:

$(document).ready(function() {
    $("#CourseID").trigger('change'); 
    // Now that the course is displayed and set, let's set the default holes
    // First we will clear all holes
    $(document).ajaxStop(function(){
        // This all needs to be done ONLY after CourseID change event is done
        $("#ClearAll").trigger('click');
        var holes = [];
        holes = "<?php echo $row['holes']; ?>";
        holes = holes.split(",");
        for(i=0; i<holes.length; i++) {
            alert(holes[i]);
            id = "#holes_"+holes[i];
            $(id).prop("checked", true);
        }
    });
});

使用 .ajaxStop 确保 ajax 查询已完成。其余的发生得非常快,所以这不是问题。届时将我的辅助功能包含在 .ajaxStop 中 - 一切都按预期进行。