3

我正在使用 JavaScript/jQuery。我在遍历数组以显示数据以及通过单击按钮删除内容时遇到问题。

有问题的原始代码

HTML

<textarea id="sds">Apple
Banana
Grape
Orange</textarea>
<input type="hidden" id="sdh" />
Problem: Every button returns 5!
<div id="popup" title="Poof">
</div>

脚本

var sds = $("#sds").val();
var sda = sds.split("\n");
var sdi = "";
$.each(sda, function(k, s) {
    sdi += "<input type='text' id='sd" + k + "' value='" + s + "' /><button id='button" + k + "'>Click Me</button><br />";
    $("#sdh").val(k);
});
$("#popup").html(sdi);

var h = $("#sdh").val();
var i = 0;
while (i <= h) {
    $("#button" + i).click(function() {
        // Here is where I have a problem trying to manipulate the input associated to the button.
        alert(i); // Test to see what returns for the value of i.
        $("#sd" + i).val("Clicked button " + i);
    });
    i++;
}

CSS(感谢提供 CSS 以使演示看起来更好,Jose!)

#sds {
    display: none;
}

jsFiddle

修订代码

HTML

<textarea rows="4" cols="40" id="sds">Apple
Banana
Grape
Orange</textarea>
<input type="text" id="sd" value="Click here to verify" />
<input type="hidden" id="key" />
<div id="popup" title="Verify Multiple Fruits">
</div>

脚本

$(document).ready(function() {
    var sds = $("#sds").val();
    var sda = sds.split("\n");
    var sdi = "";
    $.each(sda, function(key, sd) {
        sdi += "<input type='text' id='sd" + key + "' value='" + sd + "' /><button id='button'" + key + "'>Remove</button><br />";
        alert(key); // Test to see what returns for the value of i.
        $("#button" + key).click(function() {
            // Here is where I have a problem trying to manipulate the input associated to the button.
            $("#sd" + key).val("Clicked button " + i);
        });
        $("#key").val(key);
    });
    $("#popup").html(sdi);
});
$(function() {
    $("#popup").dialog({
        autoOpen: false,
        buttons: {
            "Update": function() {
                var key = $("#key").val();
                var i = 0;
                var sds = "";
                while (i <= key) {
                    sds += $("#sd" + i).val() + "\n";
                    i++;
                }
                sds = sds.slice(0, -1);
                $("#sds").val(sds);
                $(this).dialog("close");
            },
            "Cancel": function() {
                $(this).dialog("close");
            }
        },
        close: function() {
        },
        height: 320,
        hide: {
            duration: 1000,
            effect: "explode"
        },
        modal: true,
        resizable: false,
        show: {
            duration: 1000,
            effect: "blind"
        },
        width: 480
    });
    $("#sd").focus(function() {
        $("#popup").dialog("open");
    });
});

CSS(再次感谢这里的 CSS,何塞!)

#sds {
    display: none;
}

#popup input,
#popup button {
    float: left;
    width: auto;
}

#popup input {
    clear: left;
}

jsFiddle

应用其中一个答案后的修订代码

HTML

<textarea rows="4" cols="40" id="sds">Apple
Banana
Grape
Orange
Pear
Strawberry</textarea>
<input type="text" id="sd" value="Click here to verify." />
<input type="hidden" id="key" />
<div id="popup" title="Verify Multiple Fruits"></div>

脚本

$(document).ready(function() {
    $.each($("#sds").val().split("\n"), function(key, sd) {
        $("#popup").append(        
            $("<input type='text' id='sd" + key + "' value='" + sd + "' />").add(
                $("<button id='button" + key + "'>Remove</button><br />").click(function() {
                    $("#sd" + key).val("");
                    $("key").val(key);
                })));
    });
});
$(function() {
    $("#popup").dialog({
        autoOpen: false,
        buttons: {
            "Update": function() {
                var key = $("#key").val();
                var i = 0;
                var sds = "";
                while (i <= key) {
                    sds += $("#sd" + i).val() + "\n";
                    i++;
                }
                sds = sds.slice(0, -1);
                $("#sds").val(sds);
                $(this).dialog("close");
            },
            "Cancel": function() {
                $(this).dialog("close");
            }
        },
        close: function() {
        },
        height: 320,
        hide: {
            duration: 1000,
            effect: "explode"
        },
        modal: true,
        resizable: false,
        show: {
            duration: 1000,
            effect: "blind"
        },
        width: 480
    });
    $("#sd").focus(function() {
        $("#popup").dialog("open");
    });
});

CSS(这真是太棒了,何塞!)

#sds {
    display: none;
}

#popup input,
#popup button {
    float: left;
    width: auto;
}

#popup input {
    clear: left;
}

jsFiddle

假设 sds 的值是 Apple、Banana、Grape 和 Orange 在不同的行上。.each() 循环创建的每个按钮都将分配正确的数字,但是当尝试更改值时,变量 i 在警报消息框上返回 5 而下一行似乎根本不起作用 - 由于索引关闭。

如何修改此代码以使其按预期工作?

纠正了有爱心的评论员提到的错误。还是行不通。显然这不是问题,因为我复制的原始代码正确关闭了括号。由于无法在此处复制和粘贴代码,因此我在这里手动干扰了代码,因此出现了一个小错字。我的问题是关于逻辑,而不是错字。谢谢!

为了尽量减少混淆,我修改了这个问题的代码部分以反映我的原始代码,因此它将显示与 Jose 下面提供的答案的一致性。

显然,修改后的代码也有更多的问题,所以我又做了一个新的修改。这是我到目前为止所得到的。它仍然很古怪,但在大多数情况下都有效。我将需要有关模式对话框上的取消操作的帮助,因为它不会从 textarea 标记中恢复以前的值。另外,请注意 jQuery 的版本更改以及在 JSFiddle 演示中添加 jQuery UI 以反映我的开发环境。

终极解决方案

HTML

<textarea rows="4" cols="40" id="sds">Apple
Banana
Grape
Orange
Pear
Strawberry</textarea>
<input type="text" id="sd" value="Click here to verify." />
<div id="popup" title="Verify Multiple Fruits"></div>

脚本

$(document).ready(function() {
    if ($("#sds").val()) {
        var i = 0;
        $.each($("#sds").val().split("\n"), function(key, sd) {
            $("#popup").append(        
                $("<input type='text' class='blah' id='sd" + key + "' value='" + sd + "' />").add(
                    $("<button id='button" + key + "'>Remove</button><br />").click(function() {
                        $("#sd" + key).val("");
                    })));
            i++;
            window["i"] = i;
        });
    }
});
$(function() {
    $("#popup").dialog({
        autoOpen: false,
        buttons: {
            "Update": function() {
                var i = window["i"];
                var sds = "";
                $(".blah").each(function(i) {
                    if ($(this).val()) {
                        sds += $("#sd" + i).val() + "\n";
                    }
                });
                sds = sds.slice(0, -1);
                $("#sds").val(sds);
                $(this).dialog("close");
            },
            "Cancel": function() {
                $(this).dialog("close");
            }
        },
        close: function() {
            $("#popup").html("");
            if ($("#sds").val()) {
                var i = 0;
                $.each($("#sds").val().split("\n"), function(key, sd) {
                    $("#popup").append(        
                        $("<input type='text' class='blah' id='sd" + key + "' value='" + sd + "' />").add(
                            $("<button id='button" + key + "'>Remove</button><br />").click(function() {
                                $("#sd" + key).val("");
                            })));
                    i++;
                    window["i"] = i;
                });
            }
        },
        height: 320,
        hide: {
            duration: 1000,
            effect: "explode"
        },
        modal: true,
        resizable: false,
        show: {
            duration: 1000,
            effect: "blind"
        },
        width: 480
    });
    $("#sd").focus(function() {
        if ($("#sds").val()) {
            $("#popup").dialog("open");
        }
    });
});

CSS

#sds {
    display: none;
}

#popup input,
#popup button {
    float: left;
    width: auto;
}

#popup input {
    clear: left;
}

jsFiddle

解决问题后的思考

我最初对那些指出错别字的人感到恼火,而不是试图查看整个图片以发现程序本身的“大”缺陷,因为我认为我会为那些向我寻求指导的人做这件事。然后,当我想到当我看到诸如拼写错误和语法错误之类的小错误时,我会如何反应时,这让我感到震惊。我承认我讨厌看到那些小错误,主要是因为我在写任何东西(包括代码)时都有强迫症。现在我已经了解了 JSFiddle,我将在那里测试我的代码,然后再尝试从现在开始在这里发布问题。这是一次很棒的学习经历,感谢大家的帮助。

4

2 回答 2

3

有几种方法可以解决这个问题。

使用闭包

在循环内部,声明一个匿名函数并立即调用它,i作为参数传入local_i。换句话说,i具有全局范围,但local_i具有仅限于匿名函数的范围。这样,点击事件“看到”该local_i值,而不是i您之前的 (5)。

while (i <= h) {
    (function (local_i) {
        $("#button" + local_i).click(function() {
            alert(local_i); // Test to see what returns for the value of i.
            $("#sd" + local_i).val("Clicked button " + local_i);
        });
    })(i); // <-- HERE I am calling the function
    i++;
}

点击此处观看现场演示


从按钮 id 获取索引

这里有一种模式:你想要i=0for #button0i=1for #button1。因此,只需从 id 获取索引。此解决方案不需要循环。

// select all buttons inside #popup, that have an id starting by "button"
$("#popup button[id^=button]").click(function() {
    var i = parseInt($(this).attr('id').replace('button', ''));
    alert(i); // Test to see what returns for the value of i.
    $("#sd" + i).val("Clicked button " + i);
});

现场演示


优化版,无循环,无全局变量

$.each($("#sds").val().split("\n"), function(k, s) {
    $("#popup").append(

        // append the text box
        $("<input type='text' id='sd" + k + "' value='" + s + "' />").add(

            // and the button with the click already defined
            $("<button id='button" + k + "'>Click Me</button>").click(function() {
                alert(k);
                $("#sd" + k).val("Clicked button " + k);
            }))
    );
});

现场演示


最终解决方案

全新的代码被粘贴到问题中。要解决该代码中的问题,只需更改

$("#button" + key).click(function() {
   // Here is where I have a problem trying to manipulate the input associated to the button.
   $("#sd" + key).val("Clicked button " + i);
});

$("#button" + key).click(function() {
   var i = $(this).attr('id').replace('button', '');
   $("#sd" + i).val("Clicked button " + i);
});

您可以使用我上面写的其他替代方案。希望这可以帮助。

于 2013-10-09T18:27:34.440 回答
1

你这里有一个错误

$("#button" + i.click(function() {

它应该是

$("#button" + i).click(function() {

正确的,它会起作用的。

于 2013-10-08T20:16:56.747 回答