【问题标题】:Unable to reference to dynamically created element by name无法按名称引用动态创建的元素
【发布时间】:2014-11-02 05:16:51
【问题描述】:

创建页面时我有一个只有一行的表格:

<TD><INPUT type="text" name="when"/></TD>

所以当用户点击这个元素时,会出现一个日期选择器:

$(document).ready(function() {
    $('[name="when"]').datepicker();
});

当用户向该表添加新行时,我调用 setClass 函数在新行(所有行)上设置它:

function setClass() {
    $('[name="when"]').datepicker();
}

但这不适用于这些动态创建的行。为什么?

这就是我添加行的方式:

<INPUT type="button" value="Add Row" onclick="addRow('dataTable')" class="add_remove_row" />

function addRow(tableID) {
    var table = document.getElementById(tableID);

    var rowCount = table.rows.length;
    var row = table.insertRow(rowCount);

    var colCount = table.rows[1].cells.length;

    for(var i=0; i<colCount; i++) {
        var newcell = row.insertCell(i);

        newcell.innerHTML = table.rows[1].cells[i].innerHTML;


        switch(newcell.childNodes[0].type) {
            case "text":
                newcell.childNodes[0].value = "";
                break;

            case "checkbox":
                newcell.childNodes[0].checked = false;
                break;

            case "select-one":
                newcell.childNodes[0].selectedIndex = 0;
                break;
        }
    }
    setClass();
}

【问题讨论】:

  • @DavidThomas 他没有绑定事件,他正在初始化一个插件,所以委托不是答案。
  • @Barmar:好点子,不知怎的,我错过了setClass() 函数中的内容>。
  • 这似乎是一种非常类似于 jQuery 的方式来向表中添加新行(而不是说克隆)。您似乎还需要更具体地使用您的 setClass() 方法,以便仅针对新添加的行上的输入。现在,您将尝试在已初始化的输入上初始化日期选择器(不确定这可能会导致什么行为)。
  • @MikeBrant 这不会导致问题,因为 datepicker 会记住它已经初始化的元素,并且不会重新初始化它们。
  • 是的@Barmar,这种行为是问题的核心!打败你13秒!! :)

标签: javascript jquery html jquery-plugins


【解决方案1】:

您应该只在新添加的元素上初始化插件。不过,您需要采取一些特殊措施。

datepicker 插件在它已经初始化的元素上放置一个类hasDatepicker,并且不会重新初始化它们。由于您正在复制具有此类的元素,因此需要将其删除以便重新初始化。其次,如果元素没有 ID,则 datepicker 会为其添加一个随机 ID。 ID 必须是唯一的,但您的代码正在复制 ID。在下面的代码中,我只是从元素中删除了 ID,因此插件将添加一个新的、唯一的。如果我不这样做,新行上的日期选择器将填充第一行(因为在您从日期选择器中选择某些内容后查找要更新的输入时,它会在内部使用 ID)。

function addRow(tableID) {
    var table = document.getElementById(tableID);

    var rowCount = table.rows.length;
    var row = table.insertRow(rowCount);

    var colCount = table.rows[01].cells.length;

    for(var i=0; i<colCount; i++) {
        var newcell = row.insertCell(i);

        newcell.innerHTML = table.rows[1].cells[i].innerHTML;


        switch(newcell.childNodes[0].type) {
            case "text":
                newcell.childNodes[0].value = "";
                break;

            case "checkbox":
                newcell.childNodes[0].checked = false;
                break;

            case "select-one":
                newcell.childNodes[0].selectedIndex = 0;
                break;
        }
    }
    setClass(row);
}

function setClass(newrow) {
    $(newrow).find('.hasDatepicker').removeAttr('id').removeClass('hasDatepicker').datepicker();
}

DEMO

【讨论】:

  • 两种解决方案都很好,但这似乎更强一些。谢谢!
【解决方案2】:

知道了!!

问题在于,当 Jquery 的插件 datepicker 应用于元素时,会为名为 hasDatepicker 的输入设置一个类。

当你再次调用插件时,它首先检查类是否已经存在...如果存在,则 Jquery 不会应用日期选择器,因为它知道它已经应用了。

由于您要从预先存在的单元格中复制 innerHTML

newcell.innerHTML = table.rows[1].cells[i].innerHTML;

您正在复制已设置类hasDatepicker 的输入。所以 Jquery 不会实现这个插件。

一个简单的解决方法是在datepicker 调用之前删除类:

var setClass = function() {
    $('[name="when"]').removeClass("hasDatepicker").datepicker();
}

UPDATED FIDDLE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 2010-09-06
    • 1970-01-01
    相关资源
    最近更新 更多