jQuery点击事件立即触发

时间:2013-04-24 16:01:09

标签: javascript jquery onclick closures

我正在开发的网络应用程序中有以下代码:

var bgcolor = '';
var row = 0;
for(var i = 0; i < result.data.length; i++)
{
    // Set alternating background colors
    bgcolor = ( i%2 == 0) ? ' style=\'background-color: white;\'': ' style=\'background-color: whitesmoke;\'';
    $( "div.row" ).append("\
        <div class='search_container'"+bgcolor+">\
            <div class='search_result_client_heading'>"+result.data[i]['client_name']+"</div>\
            <div class='search_result_industry_heading'>"+result.data[i]['industry_name']+"</div>\
            <div class='search_result_yield_heading'>Saved: "+result.data[i]['actual_impact']+" "+result.data[i]['impact_type_name']+" / "+formatCurrency(String(result.data[i]['actual_savings']))+"</div>\
            <div class='search_result_problem_heading'>"+nl2br( result.data[i]['problem'] )+"</div>\
            <div class='detail_button_holder'>\
                <a class='btn search_result_button' id='view_results_"+result.data[i]['record_id']+"' href='#'>View details &raquo;</a>\
            </div>\
        </div>");

    $( "#view_results_"+result.data[i]['record_id'] ).click( show_result_dialog(i, result) );
}

然后是一个单独的命名函数,它根据单击的按钮简单地用不同的值填充创建的div:

function show_result_dialog(row, result)
{
    $( "#search-result-dialog-client" ).empty().append("<div class='search_result_label'>Client</div><div class='search_result_value'>"+result.data[row]['client_name']+"</div>");
    $( "#search-result-dialog-industry" ).empty().append("<div class='search_result_label'>Industry</div><div class='search_result_value'>"+result.data[row]['industry_name']+"</div>");
    $( "#search-result-dialog-contact" ).empty().append("<div class='search_result_label'>Contact</div><div class='search_result_value'>"+result.data[row]['contact_name']+"</div>");
    $( "#search-result-dialog-journey" ).empty().append("<div class='search_result_label'>Journey</div><div class='search_result_value'>"+result.data[row]['journey_name']+"</div>");
    $( "#search-result-dialog-focus_area" ).empty().append("<div class='search_result_label'>Focus Area</div><div class='search_result_value'>"+result.data[row]['focus_area']+"</div>");
    $( "#search-result-dialog-problem" ).empty().append("<div class='search_result_label'>Problem</div><div class='search_result_value'>"+result.data[row]['problem']+"</div>");
    $( "#search-result-dialog-approach" ).empty().append("<div class='search_result_label'>Approach</div><div class='search_result_value'>"+result.data[row]['approach']+"</div>");
    $( "#search-result-dialog-tactics" ).empty().append("<div class='search_result_label'>Tactics</div><div class='search_result_value'>"+result.data[row]['tactics']+"</div>");
    $( "#search-result-dialog-delivery_date" ).empty().append("<div class='search_result_label'>Delivery Date</div><div class='search_result_value'>"+result.data[row]['delivery_date']+"</div>");
    $( "#search-result-dialog-impact_type" ).empty().append("<div class='search_result_label'>Impact Type</div><div class='search_result_value'>"+result.data[row]['impact_type_name']+"</div>");
    $( "#search-result-dialog-estimated_impact" ).empty().append("<div class='search_result_label'>Estimated Impact</div><div class='search_result_value'>"+result.data[row]['estimated_impact']+" "+result.data[row]['impact_type_name']+"</div>");
    $( "#search-result-dialog-actual_impact" ).empty().append("<div class='search_result_label'>Actual Impact</div><div class='search_result_value'>"+result.data[row]['actual_impact']+" "+result.data[row]['impact_type_name']+"</div>");
    $( "#search-result-dialog-estimated_savings" ).empty().append("<div class='search_result_label'>Estimated Savings</div><div class='search_result_value'>"+formatCurrency(String(result.data[row]['estimated_savings']))+"</div>");
    $( "#search-result-dialog-actual_savings" ).empty().append("<div class='search_result_label'>Actual Savings</div><div class='search_result_value'>"+formatCurrency(String(result.data[row]['actual_savings']))+"</div>");
    $( "#search-result-dialog-nps" ).empty().append("<div class='search_result_label'>NPS</div><div class='search_result_value'>"+result.data[row]['nps']+"</div>");
    $( "#search-result-dialog-keywords" ).empty().append("<div class='search_result_label'>Keywords</div><div class='search_result_value'>"+result.data[row]['keywords']+"</div>");
    $( "#search-result-dialog" ).dialog( "open" );
    return false;
}
代码result中的

是AJAX调用返回的数据数组(此代码全部在成功函数中)

我的问题是点击处理程序在页面加载时立即触发。我希望有人可以向我解释为什么会这样,如果有办法,因为我需要从循环传递该函数i值,所以如果我在click事件中包含一个匿名函数,然后我有关闭的问题,并总是最后一个i值,所以每个按钮打开相同的数据。我已经尝试了各种各样的技术,但没有成功,包括在主匿名函数内返回一个匿名函数,反之亦然。我花了最近两天在谷歌试图找到解决方案,到目前为止没有任何工作。

2 个答案:

答案 0 :(得分:1)

您在这里自己调用此功能.click( show_result_dialog(i, result) ); 调用函数show_result_dialog()和传递其引用show_result_dialog之间存在差异。

您需要将参数作为事件数据传递:

.click( {index: i, result: result}, show_result_dialog );

或简单地将其包装在匿名函数中:

.click( function() { return show_result_dialog(i, result) });

答案 1 :(得分:0)

你至少有两个我能看到的问题。

第一个,正如其他海报所标识的那样,并未围绕function() { ... }的来电写show_result_dialog()

第二种方法是使用.click代替.on。前一种方法(混淆地)用于注册触发点击处理程序,而后者只能注册。如果您使用过.on,问题可能会更容易看到。

第三个是你试图在闭包中使用一个循环变量,它永远不会起作用。 i将具有循环结束时的最后一个值,而不是调用.click时的值。

对后一个问题最简单的解决方法是使用data参数.on()来传递所需的参数:

$("#view_results_" + result.data[i]['record_id'] ).on('click', {
   row: i, result: result
}, show_result_dialog);

function show_result_dialog(ev) {
    var row = ev.data.row;
    var result = ev.data.result;
    ...
}

其他(更有效的)方法可用于解决循环问题,但这样做是有效的,并且理解起来非常简单。