动态定义硬编码的Javascript函数

时间:2015-08-18 09:55:02

标签: javascript function

我正在为数据库应用程序编写Web前端。我在html体中有几个函数调用,如:

<input type=button value="Set 1" id="btn1" onClick=edit_entry(this,"edit","title")>
<input type=button value="Set 2" id="btn2" onClick=edit_entry(this,"edit","name")>
<input type=button value="Set 3" id="btn3" onClick=edit_entry(this,"edit","gender")>

function edit_entry(src, action, arg1) {
  alert(src.onclick);
  src.onclick = function () { edit_entry( src, action, arg1 };
  alert(src.onclick);
}

单击“btn1”时,第一个警报返回硬编码的函数定义:function onclick(event) { edit_entry(this,"edit","title") }

但是第二个警报返回带有变量function onclick(event) { edit_entry(src, action, arg1) }

的函数定义

因此,当这些变量稍后更改时,函数会获得错误的值。如何将变量的内容应用于函数定义而不是变量本身,以便定义再次function onclick(event) { edit_entry(this,"edit","title") }

P.S。:我知道这段代码片段毫无意义,因为它只能尽可能简单地描述我的问题。

这是我所指的代码。我希望现在这一切都更有意义。很抱歉给您带来不便。

HTML正文:

<input type="button" value="Edit" id="group_1_button_edit" class="action_element" onClick=edit_entries(this,"edit","artnr","artalt","bez1","bez2","bez3")>
<input type="button" value="Edit" id="group_9_button_edit" class="action_element" onClick=edit_entries(this,"edit","dok1","dok2","dok3","dok4","dok5")>

“编辑”背后的值是将从中读取内容的输入文本框的ID。

function edit_entries(caller,action,opt1,opt2,opt3,opt4,opt5,opt6,opt7,opt8,opt9,opt10,opt11,opt12) {

caller_id = caller.id.split("_");
id = caller_id[1];

switch(action) {
    case "edit":

        //Making textboxes writeable for changing values
        //[...]

        document.getElementById("group_"+id+"_button_edit").value="Save";
        document.getElementById("group_"+id+"_button_edit").onclick=function(){ edit_entries(this,"save",opt1,opt2,opt3,opt4,opt5,opt6,opt7,opt8,opt9,opt10,opt11,opt12); };
    break;
    case "save":
        if (confirm("Datensatz wirklich aktualisieren?")) {
            artnr_key = XML_OBJ.getElementsByTagName("artnr")[0].textContent;

            string = "";
            //Building the AJAX Request String: textbox id = value
            url = 'mysql_req_n1.php?type=edit_entries&'+string;
            send_request(url);
        }
    break;
}
}

//called by AJAX handler
function edit_entries_unlock() {

//Getting "id" by value check
counter_a = 1;
while (counter_a <= 9) {
    if (document.getElementById("group_"+counter_a+"_button_edit").value == "Save") id = counter_a;
    counter_a++;
}


//Getting textbox IDs located in the AJAX response
opts = XML_OBJ.getElementsByTagName("opts")[0].textContent;
options = opts.split(",");

//Making textboxes readonly again
//[...]

document.getElementById("group_"+id+"_button_edit").value="Edit";
document.getElementById("group_"+id+"_button_edit").onclick=function(){ edit_entries(this,"edit",options[0],options[1],options[2],options[3],options[4],options[5],options[6],options[7],options[8],options[9],options[10],options[11]); };

}

这就是发生的事情:

我点击第一个按钮(group_1_button_edit)。它跳转到切换块“编辑”,使文本框可写,并将编辑按钮更改为保存按钮。工作正常。

我点击保存。切换块“save”构建请求字符串并启动ajax请求。

当响应存在时,ajax处理程序启动edit_entries_unlock()。 XML Response的一部分是我之前使用过的文本框ID。 onclick函数再次更改为“编辑”函数,其中包含XML对象中的相应文本框ID。

现在我点击第二个按钮“group_9_button_edit”。一切都像上面提到的那样工作。没问题。第9组的文本框解锁,根据需要再次保存并锁定。

但是现在的错误:我再次单击第一个按钮“group_1_button_edit”,现在使用更改的函数定义。它启动开关块“编辑”,但带有GROUP 9(我之前编辑过)的文本框ID的值,而不是GROUP 1。

我想这与变量opt1-opt12有关。它们始终包含最后一次“edit_entries_unlock()”运行的值。由于所有已编辑的函数定义也使用opt1-opt12,因此它们从上次运行的值开始,而不是在重新创建函数定义时使用的值。

出于这个原因,我问如何在函数创建过程中使用变量的内容而不是执行过程中的内容来构建函数定义。

我希望现在更有意义。对不起文字墙。

3 个答案:

答案 0 :(得分:2)

这是传递数据的一种非常糟糕的方式。

您应该避免使用内联代码

<input type=button value="Set 1" id="btn1" onClick=edit_entry(this,"edit","title")>
<input type=button value="Set 2" id="btn2" onClick=edit_entry(this,"edit","name")>
<input type=button value="Set 3" id="btn3" onClick=edit_entry(this,"edit","gender")>

应该是

<input type=button value="Set 1" id="btn1" data-field-name="title">
<input type=button value="Set 2" id="btn2" data-field-name="name">
<input type=button value="Set 3" id="btn3" data-field-name="gender">
<script>
(function(){  // or use on load event

    // define the click function
    var clickFunction = function(event){  
        // get the element data
        var fieldName = event.target.attributes["data-field-name"].value;
        // do what you need to do.....
    }

    // query the DOM to get the elements you are after.
    var el = document.getElementsByTagName("input");

    // iterate them and add the event handler to each.
    for(var i = 0; i < el.length; i++){
         el[i].addEventListener("click",clickFunction,false);
    }
})();
</script>

至于你在给出的例子中你想做什么,我没有任何线索,所以这可能会对你有所帮助。

答案 1 :(得分:0)

你onclick处理程序创建一个闭包。因此,下面的值srcactionarg1(来自您的edit_entry函数)将是创建/重新创建此函数时的值(后者适用于您下次点击它)

src.onclick = function () { edit_entry( src, action, arg1 };

您只能在同一方法(或其子方法)中修改这些内容。请注意,由于您将onclick设置为上面的内容,因此您在下次单击时基本上将相同的变量传递到处理程序中。

您在这些变量中看到的任何更改都来自您的onclick处理程序(而不是外部的)

答案 2 :(得分:0)

最后在T.J.Crowder的帮助下,我能够修复代码。 我需要解决的问题是

options = opts.split(",");

var options = opts.split(",");

我不知道在没有var的函数内声明变量会使它们成为窗口对象的一部分,从而使它成为一个全局变量。所以我的闭包是访问全局变量而不是本地变量。

一个小词,但影响很大。