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

JavaScript

Jim老丝梅

2020-03-09

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

这在页面准备就绪时发生,并且工作正常。

我的问题是,在初始循环之后,我通过Ajax或DOM添加的所有选择框都没有事件绑定。

我已经找到了这个插件(jQuery Live Query Plugin),但是在我使用插件向页面添加另一个5k之前,我想看看是否有人知道直接使用jQuery或通过其他方法做到这一点的方法。

第234篇《在动态创建的元素上进行事件绑定?》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

10个回答
樱GO 2020.03.09

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

$(document).on("click", "selector", function() {
    // Your code here
});
null 2020.03.09

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

从1.9版开始,.live()方法也被删除。

TonyItachi 2020.03.09

绑定事件时存在的任何内容并且如果您的页面正在使用类名按钮动态创建元素则会将事件绑定到已存在的父对象上

$(document).ready(function(){
  //Particular Parent chield click
  $(".buttons").on("click","button",function(){
    alert("Clicked");
  });  
  
  //Dynamic event bind on button class  
  $(document).on("click",".button",function(){
    alert("Dymamic Clicked");
  });
  $("input").addClass("button");  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="buttons">
  <input type="button" value="1">
  <button>2</button>
  <input type="text">
  <button>3</button>  
  <input type="button" value="5">  
  </div>
<button>6</button>

梅猿 2020.03.09

这就是为什么动态创建的元素不响应点击的原因:

var body = $("body");
var btns = $("button");
var btnB = $("<button>B</button>");
// `<button>B</button>` is not yet in the document.
// Thus, `$("button")` gives `[<button>A</button>]`.
// Only `<button>A</button>` gets a click listener.
btns.on("click", function () {
  console.log(this);
});
// Too late for `<button>B</button>`...
body.append(btnB);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>

解决方法是,您必须听所有点击并检查source元素:

var body = $("body");
var btnB = $("<button>B</button>");
var btnC = $("<button>C</button>");
// Listen to all clicks and
// check if the source element
// is a `<button></button>`.
body.on("click", function (ev) {
  if ($(ev.target).is("button")) {
    console.log(ev.target);
  }
});
// Now you can add any number
// of `<button></button>`.
body.append(btnB);
body.append(btnC);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>

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

var i = 11;
var body = $("body");
body.on("click", "button", function () {
  var letter = (i++).toString(36).toUpperCase();
  body.append($("<button>" + letter + "</button>"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>

猴子Davaid 2020.03.09

我更喜欢以模块化功能的方式部署事件监听器,而不是编写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);
}

function myButtonWasClicked(e) {
    console.log(e.target); //access to this specific button
}

Stafan樱 2020.03.09

当使用进行动态创建时,可以将事件附加到元素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("<select>", {
    html: $.map(Array(3), function(_, index) {
      return new Option(index, index)
    }),
    on: {
      change: handleDynamicElementEvent
    }
  })
  .appendTo("body");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>

A小卤蛋Pro 2020.03.09

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

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

例如:

$(document).on("click", $(selector), function() {
    // Your code here
});
A达蒙 2020.03.09

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

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

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

// ... add elements ...
addCallbacks($(".myNewElements"))
老丝Eva 2020.03.09

尝试使用.live()代替.bind(); .live()将结合.hoverAjax请求执行后,您的复选框。

Winter 2020.03.09

的文档中有很好的解释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,并且事件仅需要起泡一个级别(从click trtbody)。

注意:委托事件不适用于SVG

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android