循环通过循环按钮元素来操作循环输入

时间:2013-10-08 20:12:20

标签: javascript jquery html jquery-ui

我正在使用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以使演示看起来更好,何塞!)

#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,Jose!)

#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的版本更改以及jQuery UI添加到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." />
<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,我将在那里测试我的代码,然后在此尝试发布一个问题。这是一次非常棒的学习经历,感谢大家的帮助。

2 个答案:

答案 0 :(得分: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++;
}

Click here for a live demo


从按钮ID

获取索引

此处有一种模式:您希望i=0#button0i=1#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);
});

Live demo


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

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

Live demo


最终解决方案

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

即可
$("#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);
});

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

答案 1 :(得分:1)

你这里有错误

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

应该是

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

认为它会起作用。