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