动态创建的元素上的事件绑定?

共23个回答,已解决, 标签: javascript jquery events unobtrusive-javascript

我有一点代码, 我在其中循环浏览页面上的所有选择框, 并 .hover 将事件绑定到它们, 以便对它们的宽度进行一些调整 mouse on/off

这发生在页面准备好, 工作得很好。

我遇到的问题是, 在初始循环之后通过 Ajax 或 DOM 添加的任何选择框都不会绑定事件。

我已经找到了这个插件 (Jquery 实时查询插件), 但在我用插件向我的页面添加另一个 5k 之前, 我想看看是否有人知道这样做的方法, 无论是直接使用 jquery 还是通过其他选项。

第1个答案(采用)

从 jQuery 1.7 开始, 您应该 jQuery.fn.on 使用:

$(staticAncestors).on(eventName, dynamicChild, function() {});

在此之前, 建议的方法是使用 live() :

$(selector).live( eventName, function(){} );

然而, live() 在 1.7 赞成的情况下被弃用, on() 在 1.9 中完全删除。live()签名:

$(selector).live( eventName, function(){} );

...可以替换为以下 on() 签名:

$(document).on( eventName, selector, function(){} );

例如, 如果您的页面正在动态创建具有类名的元素, dosomething 则您将将事件绑定到已存在的父级 (这是此处问题的核心, 则需要一些存在的内容来绑定, 不要绑定到动态内容), 这可以是 (和最简单的选择) 是 document 。虽然记住 document 可能不是最有效的选择

$(document).on('mouseover mouseout', '.dosomething', function(){
    // what you want to happen when mouseover and mouseout
    // occurs on elements that match '.dosomething'
});

在绑定事件时存在的任何父项都可以。例如,

$('.buttons').on('click', 'button', function(){
    // do something here
});

将适用于

第2个答案

有一个很好的解释 jQuery.fn.on 在文件中。

简而言之:

事件处理程序仅绑定到当前选定的元素;它们必须在您的代码调用时存在于页面 .on() 上。

因此, 在下面的示例 #dataTable tbody tr 中, 在生成代码之前必须存在。

$("#dataTable tbody tr").on("click", function(event){
    console.log($(this).text());
});

如果要将新 HTML 注入到页面中, 则最好使用委托事件附加事件处理程序, 如下所述。

委派事件的优点是, 它们可以处理以后添加到文档中的后代元素中的事件。例如, 如果表存在, 但使用代码动态添加行, 则下面将处理它:

$("#dataTable tbody").on("click", "tr", function(event){
    console.log($(this).text());
});

除了能够处理尚未创建的后代元素上的事件外, 委派事件的另一个优点是, 在必须监视许多元素时, 它们的开销可能会大大降低。在包含 1, 000 行的数据表上 tbody , 第一个代码示例将处理程序附加到 1, 000 个元素。

委托事件方法 (第二个代码示例) 仅将事件处理程序附加到一个元素, 该 tbody 元素和事件只需要冒泡一个级别 (从单击到 tr tbody )。

请注意:委派的事件不适用于Svg

第3个答案

这是一个纯粹的 JavaScript解决方案, 没有任何库或插件:

document.addEventListener('click', function (e) {
    if (hasClass(e.target, 'bu')) {
        // .bu clicked
        // Do your thing
    } else if (hasClass(e.target, 'test')) {
        // .test clicked
        // Do your other thing
    }
}, false);

在哪里 hasClass

function hasClass(elem, className) {
    return elem.className.split(' ').indexOf(className) > -1;
}

Live demo

功劳归戴夫和西姆·维达斯

使用更现代的 JS, hasClass 可以实现为:

function hasClass(elem, className) {
    return elem.classList.contains(className);
}
第4个答案

创建对象时, 可以向对象添加事件。如果要在不同时间向多个对象添加相同的事件, 则创建命名函数可能是最佳选择。

var mouseOverHandler = function() {
    // Do stuff
};
var mouseOutHandler = function () {
    // Do stuff
};

$(function() {
    // On the document load, apply to existing elements
    $('select').hover(mouseOverHandler, mouseOutHandler);
});

// This next part would be in the callback from your Ajax call
$("")
    s */ )
    .hover(mouseOverHandler, mouseOutHandler)
    .appendTo( /* Wherever you need the select box */ )
;
第5个答案

您可以简单地将事件绑定调用包装到函数中, 然后调用它两次: 一次在文档准备就绪时, 一次在事件之后添加新的 DOM 元素。如果这样做, 则需要避免在现有元素上绑定同一事件两次, 因此您需要取消绑定现有事件, 或者 (更好地) 只绑定到新创建的 DOM 元素。代码将如下所示:

function addCallbacks(eles){
    eles.hover(function(){alert("gotcha!")});
}

$(document).ready(function(){
    addCallbacks($(".myEles"))
});

// ... add elements ...
addCallbacks($(".myNewElements"))
第6个答案

尝试使用 .live() , 而不是 .bind() ; 将 .live() .hover 绑定到您的复选框后, ajax 请求执行。

第7个答案

可以使用 live () 方法将元素 (甚至是新创建的元素) 绑定到事件和处理程序, 如 onclick 事件。

下面是我编写的示例代码, 您可以在其中看到 live () 方法如何将选定的元素 (即使是新创建的元素) 绑定到事件:





        Untitled Document








            $(document).ready(function()
                {
                    $('.FOO').live("click", function (){alert("It Works!")});
                    var $dialog = $('<div></div>').html('<div id="container"><input type ="button" id="CUSTOM" value="click"/>This dialog will show every time!</div>').dialog({
                                                                                                         autoOpen: false,
                                                                                                         tite: 'Basic Dialog'
                                                                                                     });
                    $('#theButton').click(function()
                    {
                        $dialog.dialog('open');
                        return('false');
                    });
                    $('#CUSTOM').click(function(){
                        //$('#container').append('<input type="button" value="clickmee" class="FOO" /></br>');
                        var button = document.createElement("input");
                        button.setAttribute('class','FOO');
                        button.setAttribute('type','button');
                        button.setAttribute('value','CLICKMEE');
                        $('#container').append(button);
                    });
                    /* $('#FOO').click(function(){
                                                     alert("It Works!");
                                                 }); */
            });



第8个答案

动态创建的元素上的事件绑定

单个元素:

$(document.body).on('click','.element', function(e) {  });

子元素:

 $(document.body).on('click','.element *', function(e) {  });

请注意添加 * 的。将为该元素的所有子元素触发一个事件。

我注意到:

$(document.body).on('click','.#element_id > element', function(e) {  });

它不再起作用了, 但以前也在起作用。我一直在使用来自谷歌Cdn 的jquery, 但我不知道他们是否改变了它。

第9个答案

另一种解决方案是在创建元素时添加侦听器。而不是将侦听器放在正文中, 而是将侦听器放在创建该元素的时刻的元素中:

var myElement = $('', {
    text: 'Go to Google!'
});

myElement.bind( 'click', goToGoogle);
myElement.append('body');


function goToGoogle(event){
    window.location.replace("http://www.google.com");
}
第10个答案

我更喜欢使用选择器, 并将其应用于文档。

这将在文档上绑定自己, 并将适用于页面加载后将呈现的元素。

例如:

$(document).on("click", $(selector), function() {
    // Your code here
});
第11个答案

请注意放置元素的 "MAIN" 类, 例如,



          First
         Second


在上面的方案中, jQuery 将监视的 MAIN 对象是 "容器"。

然后, 您基本上将在容器下的元素名称, 如 ul li select , 和:

$(document).ready(function(e) {
    $('.container').on( 'click',".select", function(e) {
        alert("CLICKED");
    });
 });
第12个答案

动态 jQuery(html, attributes) 创建时, 可以将事件附加到元素。

从 jQuery 1.8 开始, 任何 jquery 实例方法 jQuery.fn (方法) 都可以用作传递给第二个参数的对象的属性:

function handleDynamicElementEvent(event) {
  console.log(event.type, this.value)
}
// create and attach event to dynamic element
jQuery("", {
    html: $.map(Array(3), function(_, index) {
      return new Option(index, index)
    }),
    on: {
      change: handleDynamicElementEvent
    }
  })
  .appendTo("body");
第13个答案

你可以用

$('.buttons').on('click', 'button', function(){
    // your magic goes here
});

$('.buttons').delegate('button', 'click', function() {
    // your magic goes here
});

这两种方法是等效的, 但参数顺序不同。

参见: Jquery 委托事件

第14个答案

在绑定事件时, 任何 p都不存在, 如果您的页面使用类名按钮**动态创建元素**, 则可以将事件绑定到已存在的父级

$(document).ready(function(){
  //Particular Parent chield click
  $(".buttons").on("click","button",function(){
    alert("Clicked");
  });

第15个答案

以下是动态创建的元素不响应点击的原因:

var body = $("body");
var btns = $("button");
var btnB = $("B");
// `B` is not yet in the document.
// Thus, `$("button")` gives `[A]`.
// Only `A` gets a click listener.
btns.on("click", function () {
  console.log(this);
});
// Too late for `B`...
body.append(btnB);

A

作为一种解决方法, 您必须侦听所有单击并检查源元素:

var body = $("body");
var btnB = $("B");
var btnC = $("C");
// Listen to all clicks and
// check if the source element
// is a ``.
body.on("click", function (ev) {
  if ($(ev.target).is("button")) {
    console.log(ev.target);
  }
});
// Now you can add any number
// of ``.
body.append(btnB);
body.append(btnC);

A

这称为 "事件委派"。好消息, 这是 jQuery 中的内置功能:-)

var i = 11;
var body = $("body");
body.on("click", "button", function () {
  var letter = (i++).toString(36).toUpperCase();
  body.append($("" + letter + ""));
});

A
第16个答案

尝试这样-

$(document).on( 'click', '.click-activity', function () { ... });
第17个答案

使用 .on() jQuery http://api.jquery.com/on/的方法将事件处理程序附加到活动元素。

此外, 从版本 1.9 方法开始 .live() , 该方法也将被删除。

第18个答案

这是由事件委派完成的。事件将绑定到包装类元素, 但将委托给选择类元素。这就是它的工作原理。

$('.wrapper-class').on("click", '.selector-class', function() {
    // Your code here
});

注意:

包装类元素可以是文档、正文或包装器等任何内容。包装器应该已经存在了。

第19个答案

将事件绑定到已存在的父项:

$(document).on("click", "selector", function() {
    // Your code here
});
第20个答案

我更喜欢以模块化函数的方式部署事件侦听器, 而不是编写 document 级别事件侦听器的脚本。所以, 我确实喜欢下面。请注意, 您不能过度订阅具有相同事件侦听器的元素, 因此不必担心多次附加侦听器-只有一个坚持.

var iterations = 4;
var button;
var body = document.querySelector("body");

for (var i = 0; i < iterations; i++) {
    button = document.createElement("button");
    button.classList.add("my-button");
    button.appendChild(document.createTextNode(i));
    button.addEventListener("click", myButtonWasClicked);
    body.appendChild(button);
}
第21个答案

创建元素和绑定事件的另一个灵活解决方案 ()

// creating a dynamic element (container div)
var $div = $("", {id: 'myid1', class: 'myclass'});

//creating a dynamic button
 var $btn = $("", { type: 'button', text: 'Click me', class: 'btn' });

// binding the event
 $btn.click(function () { //for mouseover--> $btn.on('mouseover', function () {
    console.log('clicked');
 });

// append dynamic button to the dynamic container
$div.append($btn);

// add the dynamically created element(s) to a static element
$("#box").append($div);

注意:这将为每个元素创建一个事件处理程序实例(在循环中使用时可能会影响性能)

第22个答案


        HTML Document





            Hello World



            jQuery(document).ready(function($){
                $(document).on('mouseover', '#hover-id', function(){
                    $(this).css('color','yellowgreen');
                });

                $(document).on('mouseout', '#hover-id', function(){
                    $(this).css('color','black');
                });
            });



第23个答案

我正在寻找一个解决方案, 以获得 $.bind $.unbind 和工作没有问题, 在动态添加的元素。

正如() 做的技巧附加事件, 为了创建一个假的取消绑定的那些我来到:

const sendAction = function(e){ ... }
// bind the click
$('body').on('click', 'button.send', sendAction );

// unbind the click
$('body').on('click', 'button.send', function(){} );

相关问题

如何从异步调用返回响应? 循环中的 JavaScript 闭包--简单的实际示例 如何从异步调用返回响应? 动态创建的元素上的事件绑定? JavaScript 将前 5 个字符替换为 * 浏览器后退/下一步按钮在标签之间导航