【问题标题】:JavaScript is duplicating elements returned by document get methods when I run the returned element collection through a loop当我通过循环运行返回的元素集合时,JavaScript 正在复制文档获取方法返回的元素
【发布时间】:2014-06-14 22:57:50
【问题描述】:

我需要遍历三个输入字段;所有三个共享同一个类,并且所有三个都具有相同的具有唯一 id 的祖父元素。

<div id="layout-fields">
    <div class="form-group">
        <div class="col-sm-4 layout-input-field-container">
            <input class="layout-input-fields" id="id_layout_1" maxlength="50" name="layout_1" type="text" />
        </div>
        <div class="col-sm-4 layout-input-field-container">
            <input class="layout-input-fields" id="id_layout_2" maxlength="50" name="layout_2" type="text" />
        </div>
        <div class="col-sm-4 layout-input-field-container">
            <input class="layout-input-fields" id="id_layout_3" maxlength="50" name="layout_3" type="text" />
        </div>
    </div>
</div>

当用户点击一组图标时,会调用以下事件处理程序:

$(".layout-icons").click(function(){
    selectLayout(this);
});

调用此方法(简称相关代码):

var selectLayout = function(obj){
    var selectedLayoutValue = $(obj).siblings(".layout-image-description").text();
    var layout_fields_container = document.getElementsByClassName('layout-input-fields');
    var filledInputs = 0;
    var selectedValueAlreadyAssignedInputField = false;

    console.log(layout_fields_container.length);

    for(lfc in layout_fields_container){
        console.log(layout_fields_container[lfc]);
        if(layout_fields_container[lfc].value == selectedLayoutValue) {
            selectedValueAlreadyAssignedInputField = true;
            layout_fields_container[lfc].value = '';

        if(layout_fields_container[lfc].value != '' && typeof layout_fields_container[lfc].value !== "undefined"){
            if(layout_fields_container[lfc].value.length > 0){
                filledInputs++;
            }
        }
    }
}

好的,这就是问题所在。控制台日志说 layout_fields_container.length = 3。所以这是有道理的。但是 for 循环迭代了 12 次!它到底在迭代什么,我怎样才能将它限制在输入元素上?

这正是它的执行方式:

  1. 干净运行三个输入字段,以便控制台日志干净地显示 field1、field2、field3。该初始控制台日志语句显示 layout_fields_container 的长度为 3
  2. 当循环结束时,它显然会回到 selectLayout 方法的开头。所以调用了初始的console.log,长度仍然是3。
  3. 它再次回到循环中,这次它遍历每个输入字段两次。所以 console.log 在 for 循环中打印 field1, field1, field2, field2, field3, field3
  4. 仍在循环中,它会打印另外两行 1) "function item() { [native code] } 和 2) function namedItem() { [native code] }

为什么它会通过循环返回?集合中这些额外的项目是从哪里来的?

【问题讨论】:

  • 哇。这样的不一致。很多bug。做循环。所以 Jquerascript。
  • 除了 Jon 提供的解决方案之外,您能否解释一下您正在谈论的其他错误?我很想修复它们,但我需要先知道它们是什么。
  • 对不起,我只是喜欢 Doge meme!你没有那么多错误,因为它只是不一致的编码风格。您使用 jQuery 设置一个变量,然后使用 JS 设置下一个变量,使用 CamelCase 命名一个变量,然后使用 under_score 命名。在您的if 语句中,您与松散(!=)和严格(!==)进行比较(严格是要走的路)。然后你想要一个值的typeof(冗余检查)......这将永远返回String,永远不会“未定义”。您在 jquery 函数中使用 this 而不是 $(this) (允许事件委托)。但是整个功能毫无意义,您的第二个 if 永远不会触发。

标签: javascript loops


【解决方案1】:

您正在使用for...in 迭代某些内容。以惊人的百分比执行时间是错误的,在这里也是错误的:您还将迭代非数字索引。

将您的循环转换为标准的for

for(var i = 0; i < layout_fields_container.length; ++i) {
     // do stuff with layout_fields_container[i]
}

【讨论】:

  • 知道了。谢谢你。但是为什么当集合中有更多项目时长度会返回 3 呢?我假设那些非数字索引是列表中的项目?
  • @BrianKempf:不,它们是对象的属性。试试这个:var arr = [0, 1, 2]; arr.whatever = "surprise!"; 然后for...in 超过arr。除了明显的索引之外,您还将获得密钥whatever
  • 哦,有道理;显然,我错误地阅读了文档。谢谢
  • 还有一个问题。 9/12 的迭代是在集合中的项目上。我打算在集合中有 3 个项目(.length 返回 3)。为什么它会再重复两次迭代这些项目?
  • @BrianKempf:也许你不小心嵌套了循环? 3 * 3 = 9?
猜你喜欢
  • 1970-01-01
  • 2019-06-26
  • 2011-07-10
  • 1970-01-01
  • 1970-01-01
  • 2021-10-17
  • 2013-11-29
  • 2016-05-27
  • 1970-01-01
相关资源
最近更新 更多