【问题标题】:jQuery selector doesn't update after dynamically adding new elementsjQuery 选择器在动态添加新元素后不更新
【发布时间】:2012-03-09 22:06:12
【问题描述】:

我的选择器是:

$('section#attendance input:last')

但是,我将另一个输入附加到 section#attendance。我希望选择器现在选择该元素(因为:last,它应该选择该元素。但是,由于某种原因,它没有,我不太确定为什么?

这是我的完整代码:

$('section#attendance input:last').keydown(function(e) {
        if (e.which == 9)
        {
            var $this = $(this);
            var num = parseInt($this.attr('name').match(/\d+(,\d+)?/)[0]) + 1;
            $this.parent().append('<input type="text" name="attendance[' + num +']" value="Name and Position" class="medium" />');
        }
    });

新代码:

    $("section#attendance").on("keydown", "input:last", function(e) {
    if (e.which == 9) {
        var $this = $(this);
        var num = parseInt($this.attr('name').match(/\d+(,\d+)?/)[0]) + 1;
        $this.after('<input type="text" name="attendance[' + num +']" value="Name and Position" class="medium" />');
    }
});

编辑:问题似乎出在“输入:最后一个”上,因为如果我只使用输入,它就可以工作。此外,如果我将类“last”添加到最后一个元素,则当我使用“input.last”作为选择器时它会起作用。

【问题讨论】:

    标签: javascript jquery tabs


    【解决方案1】:

    根据您使用的 jQuery 版本,您应该使用.delegate()(jQuery 1.7 之前)或.on()(jQuery 1.7+)来进行委托事件处理,以处理动态添加的元素的事件。注意 .live() 已被所有版本的 jQuery 弃用,因此不应再使用它。

    使用.on(),你可以这样使用:

    $("#attendance").on("keydown", "input:last", function(e) {
        if (e.which == 9) {
            var $this = $(this);
            var num = parseInt($this.attr('name').match(/\d+(,\d+)?/)[0]) + 1;
            $this.parent().append('<input type="text" name="attendance[' + num +']" value="Name and Position" class="medium" />');
        }
    });
    

    使用.delegate() 是类似的(除了参数的顺序不同)。您可以在 jQuery 文档 .delegate().on() 中看到它们。

    委托事件处理使用某些 javascript 事件的“冒泡”功能。这允许您将事件处理程序附加到父对象(不会来去去去)并让它查看从子对象“冒泡”到它的每个事件,检查事件是否来自具有适当的选择器,如果是,则执行您的事件处理代码。这样,当对象来来去去时,它们的事件仍然得到适当的处理。

    正如您最初所做的那样,您将在事件绑定代码运行时将事件处理程序直接绑定到与选择器 'section#attendance input:last' 匹配的对象。从那时起,无论该对象是否仍然与选择器匹配,或者是否将新对象添加到与选择器匹配的 DOM,它都直接绑定到该特定对象。使用.delegate().on() 的委托事件处理允许事件处理行为更加动态 - 自动调整以适应 DOM 中的变化。您只需要将事件绑定到一个不会更改的公共父对象,它就可以自动监控它的所有子对象。

    【讨论】:

    • 嘿,我试过了,但由于某种原因,它似乎不起作用。我已经用新代码更新了我的帖子,并查看了 .on() 的文档,但我无法找出问题所在。为帮助干杯!
    • 问题是您添加的输入标签没有您的代码所期望的正确类型的名称属性。您没有透露您的 HTML,但在我看来,您的代码无法正常工作,因为它解析了 name 属性中的数字。您的正则表达式匹配两个中间有逗号的数字,但您添加的新输入标签没有这种格式。你可以在这里看到一个更简单的版本:jsfiddle.net/jfriend00/uVHwK。我们必须查看您的 HTML 才能提供更具体的建议。
    【解决方案2】:

    要对动态插入的内容做出反应,您必须使用委托事件。目前推荐的执行此操作的函数是 .on()live 已弃用,binddelegate 已被取代)。

    【讨论】:

    • binddelegate 未被弃用。
    • 你是对的。 live 已弃用,binddelegate 已被取代。
    【解决方案3】:

    不要使用直播!使用on

    live 方法由于性能不佳已被弃用,现在改用on 方法。

    $('section#attendance').on('keydown', 'input:last', function(e) {
        /* ... code ... */
    });
    

    另外,没有理由在您的 id 选择器前面加上 section 标签。

    【讨论】:

      【解决方案4】:

      问题很可能是因为您正在使用 keydown 事件。这实际上对选择器使用了绑定。仅绑定首次附加时存在的效果项目。 JQuery 文档说:

      bind() 将事件附加到在调用时存在或匹配选择器的元素。之后创建的任何元素或由于类更改而继续匹配的任何元素都不会触发绑定事件。

      您应该将 keydown 替换为以下内容:

      $('section#attendance).on("keydown", "input:last", function(e) {...});
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-10
        • 1970-01-01
        • 2018-01-06
        • 2018-09-11
        • 2015-03-01
        • 2016-08-13
        相关资源
        最近更新 更多