【问题标题】:Why is my click event handler not firing for a dynamically added link?为什么我的点击事件处理程序没有为动态添加的链接触发?
【发布时间】:2012-08-26 12:38:55
【问题描述】:

我正在努力在页面上的一系列跨度标签之后动态添加带有点击事件处理程序的链接。该链接正在添加到页面中,但单击时事件处理程序未触发。 Web 控制台中没有记录错误。我确信我在下面的代码中遗漏了一些明显的东西:

function changeClicked (e) {
    e.preventDefault();
    console.log('should work');
}

function initChangeOwner() {
    var changeLink = $('<a />', {
        href: '#',
        text: 'change',
        'class': 'changeLink',
        click: changeClicked
    });

    var licenseFor = $('[id*="LicenseFor"]').after(changeLink);
}

$(document).ready(function () {
    initChangeOwner();
    // other inits
});

为什么我的点击事件处理程序没有触发?对于那些喜欢摆弄的人,我已经设置了an example on jsFiddle

* 这是一个使用 jQuery 1.4.1 的旧应用程序。不幸的是,现在不是将引用更新到新版本的时候。

【问题讨论】:

  • 实际问题令人困惑,在我看到不同版本的工作答案后,它更加令人困惑:P

标签: jquery jquery-1.4


【解决方案1】:

通常我会说使用.on(),但看起来你使用的是 jQuery 1.4.4。

像这样为点击添加一个.live() 事件:一切正常:

$('.changeLink').live('click', function (e) {
   changeClicked(e); 
});

看起来在 1.4.4 中存在某种错误,因为您无法将这些 click / onclick 属性添加到元素中。 (附带说明::不想在元素上使用click/onclick/onmouseover/etc,无论如何,每个单独(每个元素)都会创建一个脚本文件在 IE 中(降低性能)。看起来你的原始代码在更高版本的 jQuery 中也可以工作,只是在 1.8 中尝试过很好。

另外,在你的 changeClicked() 函数中使用return false;(它会同时为你执行stopPropagation &amp; preventDefault,之后的任何东西都不会运行,以及锚点的href="#" 属性。

function changeClicked(e) {
    console.log('here we are');

    return false; // stops link - preventDefault & stopPropagation
    console.log('it WONT get here');
}

jsFiddle DEMO

【讨论】:

  • 感谢return false 的提醒。忘记了它比preventDefault 更受欢迎。
  • @mcpDesigns:附带说明:在 jQuery 1.4.2 中,委托替换了 live 并且是首选的绑定方法(直到 1.7,它们都被 on() 取代)。虽然 live 工作得很好,但它确实会一直冒泡到文档中,并且有很多缺点,这些缺点在文档中列出。使用委托可以让您将事件绑定到最近的静态元素,并让您为其中的动态元素指定选择器。 $("#MyStaticElement").delegate(".changeLink", "click", function(){...}) 这只会冒泡到指定的最近的静态元素。
  • 非常真实!我将它切换到委托,忘记那个该死的东西哈哈
【解决方案2】:

在您的特定情况下,无需花心思在动态绑定上。 看到你在添加元素时可以控制并且你想在那个时候绑定事件你可以在附加元素后单独绑定你的点击事件。

function initChangeOwner() {
    var changeLink = $('<a />', {
        href: '#',
        text: 'change',
        'class': 'changeLink'
    });

    var licenseFor = $('[id*="LicenseFor"]').after(changeLink);

    // Now the elements exist and you can bind the click event using the 'changeLink' class as a selector.
    $(".changeLink").click(function(event){changeClicked(event);});

}

DEMO - 创建元素后绑定

【讨论】:

  • 所以那是did mcpDESIGNS answer。我知道为什么会这样,但我的初始版本有什么“问题”?
  • 看起来在 1.4.4 中存在某种错误,因为您无法将这些 click / onclick 属性添加到元素中。 (附带说明一下,您无论如何都不想使用它们,每个人都在 IE 中单独创建一个脚本文件(降低性能)。看起来您的原始代码也适用于更高版本的 jQuery,只是在 1.8 中尝试过很好。
  • @mcpDESIGNS 如果问题出在他附加 lcik 事件的方式上,那么这应该可以正常工作吗?但它不是jsfiddle.net/xUjTd/56
  • 是的,但正如@Francois 指出的那样,它需要放在 -after- var licenseFor (这是将它放入 DOM 时)。在我的版本中,我使用了 .live(),它只是等待事件冒泡,基本上是一样的。
  • @sabithpocker:这很有趣。当我回到家时,我会检查一下,如果你愿意,我们可以继续在聊天室中讨论这个问题,因为这很有趣。
【解决方案3】:

函数应该是这样的:

function initChangeOwner() {
  $('[id*="LicenseFor"]').each(function(index){
    var changeLink = $('<a />', {
    href: '#',
    text: 'change',
    'class': 'changeLink',
     click: changeClicked
   });

    $(this).after(changeLink);
  });
}

Working Demo

【讨论】:

    【解决方案4】:

    像这样重构你的代码:

    function initChangeOwner() {
        $('[id*="LicenseFor"]').each(function(){
            var changeLink = $('<a />', {
                href: '#',
                text: 'change',
                'class': 'changeLink',
                click: changeClicked
            });
           $(this) .after(changeLink);
        });
    }
    

    http://jsfiddle.net/xUjTd/48/这工作正常

    我认为问题在于首先将一个事件附加到 changeLink,然后将其多次插入 DOM。 http://jsfiddle.net/xUjTd/60/

    【讨论】:

    • .each 与使用 .after 有何不同?
    • 一件事是,之前您创建了一个多次插入的changeLink,现在您为每个LicenceFor 创建了一个changeLink。位,我仍在研究为什么它在您的情况下不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 2023-02-03
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多