jQuery/javaScript-click/onclick事件监听器在循环内不工作,尽管关闭了

jQuery/javaScript-click/onclick事件监听器在循环内不工作,尽管关闭了,javascript,jquery,loops,closures,event-listener,Javascript,Jquery,Loops,Closures,Event Listener,我和我的循环再次。。。 我试图在几个divs上运行for循环,每个都在类“tooltipBox”中,但具有不同的ids。在每个divs中都有一个类为“tttFalloutOrder”的输入文本字段。我想在for循环中做的是在每个.tttFalloutOrder输入字段上附加一个click事件侦听器 这是我目前的代码: function installListener(elementId) { $( "div#" + elementId + " > .tttFalloutOrder"

我和我的循环再次。。。 我试图在几个
div
s上运行
for
循环,每个都在类“
tooltipBox
”中,但具有不同的
id
s。在每个
div
s中都有一个类为“
tttFalloutOrder
”的输入文本字段。我想在for循环中做的是在每个
.tttFalloutOrder
输入字段上附加一个click事件侦听器

这是我目前的代码:

function installListener(elementId) {
    $( "div#" + elementId + " > .tttFalloutOrder" ).on("click", function() {
        alert("clicked on " + elementId);
    });
}

function runSimulation() {
    alert("running simulation...");

    $( "#lContent h2" ).html("Simulation <b>in progress...</b>");

    var agents = $( "div.tooltipBox" );
    var rFOs = $( ".rFO" );

    var i, j = 0;

    for(i = 0, j = 0; i < agents.length, j < rFOs.length; i++, j++) {
        var ttl = rFOs[j].value;

        if((ttl == "undefined") || (ttl == "n")) {
            continue;
        } else {
            // function-factory als gscheite closure,
            // siehe http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example
            // und http://stackoverflow.com/questions/3572480/please-explain-the-use-of-javascript-closures-in-loops?answertab=votes#tab-top
            (function(i, ttl) {
                var agentId = agents[i].id;

                installListener(agentId);

                /*
                $( "div#" + agentId + " > .tttFalloutOrder" ).on("change keypress paste focus textInput input", function() {
                    alert(agentId + "just got changed!");
                });
                */
                setTimeout(function() {
                    $("div#" + agentId + " > div.offlineCover").fadeIn(500);
                }, ttl*1000);
            })(i, ttl);
        }
    }
    $( "#lContent h2" ).html("Simulation <b>complete</b>");
}

您会发现使用
jQuery.each()
循环比使用
for()
更容易。
.each()
回调函数将自动捕获所需的变量,因此无需进行另一个内部闭包

最有可能阻止单击处理程序工作的是
listenerKind
。如果不存在这样的成员,那么将抛出一个错误,事件线程将死亡

您最大的问题是知道何时将“正在进行”消息更改为“完成”。目前,消息将立即更改回原来的状态,而无需等待任何设置超时完成,更不用说所有设置超时

就个人而言,我会这样做(参见代码中的注释):

函数运行模拟(){
var$agents=$(“div.tooltipBox”),
$rFO=$(“.rFO”),
$message=$(“#lContent h2”);
如果($agents.filter('.running')。长度>0){
//如果早期模拟的任何部分仍在运行,则禁止模拟。
返回;
}
$message.html(“正在进行的模拟…”);
$agents.每个(功能(i,agent){
var-ttl,$agent;
如果(i>=$rFOs.length){
return false;//从.each()中断
}
ttl=Number($rFOs.eq(i).val());//任何转换为Number的失败都将导致NaN。
if(伊斯南(ttl)){
返回true;//继续使用.each()
}
$agent=$(agent.addClass('running');//提供一个可测试的状态(见下文和上文)
$agent.children(“.tttFalloutOrder”).on('click.sim',function(){//注意:命名空间的单击事件允许。off('click.sim')不影响可能附加的任何其他单击处理程序。
警报(“单击”+$agent.attr('id'));
});
setTimeout(函数(){
$agent.children(“.tttFalloutOrder”).off('click.sim');//分离与.on('click.sim')连接的处理程序。
$agent.removeClass('running')。children('offlineCover')。fadeIn(500);
if($agents.filter('.running').length==0){//如果此代理或任何其他代理均未“运行”
$message.html(“模拟完成”);//所有部分完成时表示完成
}
},ttl*1000);
});
}
未经测试

如果单击操作仍然不起作用,那么我会怀疑
$agent.children(“.tttFalloutOrder”)
选择器不正确


还有其他方法可以做这类事情,特别是利用延迟/承诺和
jQuery.when()
,但是上面的代码(经过适当调试)就足够了。

。设置断点,检查变量。确保调用了
installListener
(毕竟有一个
if…else
语句),并且选择了正确的元素。添加侦听器工作正常。。什么是RFo?问题在于您的其余代码和逻辑。非常感谢您的帮助,同时我为浪费您的时间表示歉意,因为主要问题确实是jQuery选择器不正确……我用工作代码更新了我的问题。再次感谢,尽管如此,答案还是解释得很好!在我的回答中有一些相关的特征,你可能会考虑。第一种是,如果模拟已经在进行中,则禁止模拟。第二种是决定显示“模拟完成”的方式;您的
waitUntilEvaluate=waitUntilEvaluate+ttl*1000
是另一种方法,但我认为您需要
waitUntilEvaluate=Math.max(waitUntilEvaluate,ttl*1000)
;这是因为所有设置超时延迟在(几乎)同一时间开始,并并行运行,而不是顺序运行。
function runSimulation() {
    alert("running simulation...");

    $( "#lContent h2" ).html("Simulation <b>in progress...</b>");

    var agents = $( "div.tooltipBox" );
    var rFOs = $( ".rFO" );

    var waitUntilEvaluate = 0;

    var i, j = 0;

    for(i = 0, j = 0; i < agents.length, j < rFOs.length; i++, j++) {
        var ttl = rFOs[j].value;

        if((ttl == "undefined") || (ttl == "n")) {
            continue;
        } else {
            // function-factory als gscheite closure,
            // siehe http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example
            // und http://stackoverflow.com/questions/3572480/please-explain-the-use-of-javascript-closures-in-loops?answertab=votes#tab-top
            (function(i, ttl) {
                var agentId = agents[i].id;

                $( "div#" + agentId + " .tttFalloutOrder" ).on("input", function() {
                    alert(agentId + "just got changed!");
                    $( "div#" + agentId + " .wasChanged" ).prop("checked", true);
                });

                setTimeout(function() {
                    $("div#" + agentId + " > div.offlineCover").fadeIn(500);
                }, ttl*1000);

                waitUntilEvaluate = waitUntilEvaluate + ttl * 1000;
            })(i, ttl);
        }
    }

    console.log(waitUntilEvaluate);
    setTimeout(function() {
        $( "#lContent h2" ).html("Simulation <b>complete</b>");
        evaluate();
    }, waitUntilEvaluate);
}
function runSimulation() {
    var $agents = $("div.tooltipBox"),
        $rFOs = $(".rFO"),
        $message = $("#lContent h2");
    if($agents.filter('.running').length > 0) {
        //Inhibit simulation if any part of an earlier simulation is still running.
        return;
    }
    $message.html("Simulation <b>in progress...</b>");
    $agents.each(function(i, agent) {
        var ttl, $agent;
        if(i >= $rFOs.length) {
            return false;//break out of .each()
        }
        ttl = Number($rFOs.eq(i).val());//Any failure to cast as Number will result in NaN.
        if(isNaN(ttl)) {
            return true;//continue with .each()
        }
        $agent = $(agent).addClass('running');//Provide a testable state (see below and above)
        $agent.children(".tttFalloutOrder").on('click.sim', function() {//Note: namespaced click event allows .off('click.sim') without affecting any other click handlers that might be attached.
            alert("click on " + $agent.attr('id'));
        });
        setTimeout(function() {
            $agent.children(".tttFalloutOrder").off('click.sim');//detach the handler attached with .on('click.sim') .
            $agent.removeClass('running').children(".offlineCover").fadeIn(500);
            if($agents.filter('.running').length == 0) {//if neither this nor any other agent is "running"
                $message.html("Simulation <b>complete</b>");//Signify complete when all parts are complete
            }
        }, ttl*1000);
    });
}