Привязка прослушивателя к динамически созданному элементу

#javascript #jquery #bootstrap-4

#javascript #jquery #bootstrap-4

Вопрос:

Я использую группу списка bootstrap для создания ряда вкладок. Когда кто-то нажимает на элемент в таблице, он динамически создает новую вкладку и добавляет ее в эту группу списка.

         var newtext = "#" ticket " - " parele.find("td:nth-child(3) strong").html();
        var closebtn = $("<button>").addClass("close ml-2 mr-n2 newlyaddedclose").html("amp;times;");
        var newdiv = $("<div>").addClass("d-flex justify-content-between").append(newtext).append(closebtn);
        var newa = $("<a>").addClass("list-group-item list-group-item-action").attr("data-toggle","list").attr("href","#ticket" ticket).attr("id","ticket" ticket "-tab").append(newdiv);
        $("#ticketpanel").append(newa);
  

Проблема, с которой я сталкиваюсь, — это недавно созданная кнопка закрытия. Мне нужно привязать функцию, которая определяет, когда она нажата, для обработки закрытия этой вкладки, но, похоже, она не работает. В моем примере здесь я добавил класс «newlyaddedclose», чтобы помочь временно идентифицировать новый элемент, и я добавил следующий код ниже для привязки функции, которая определена в верхней части моего тега script:

 $(".newlyaddedclose").on("click",".close",closebtn).removeClass("newlyaddedclose");
  

Это все еще не работает. Когда я проверяю элемент кнопки закрытия, консоль показывает эту ошибку: ошибки API прослушивателей событий Framework:
обработчик прослушивателя событий не является функцией или empt

Я делаю это сложнее, чем нужно, или что я делаю не так? Я могу просто поместить в конце создания этого элемента это:

 $(".close").click(function() { ... });
  

Но выполнение этого начинает удваивать и утроять и т.д. Эти события на уже созданных вкладках.

РЕДАКТИРОВАТЬ: вот весь мой блок скрипта, чтобы устранить любую путаницу.

     $(function() {
  function closebtn() {
    alert("Close button clicked...");
  }
  $(".ticket-line").click(function() {
    var parele = $(this);
    var ticket = parele.data("tnum");
    // Check to see if ticket is already open in tabs
    if($("#ticket" ticket).length == 0) {
        // Create tab on ticket panel
        var newtext = "#" ticket " - " parele.find("td:nth-child(3) strong").html();
        var closebtn = $("<button>").addClass("close ml-2 mr-n2 newlyaddedclose").html("amp;times;");
        var newdiv = $("<div>").addClass("d-flex justify-content-between").append(newtext).append(closebtn);
        var newa = $("<a>").addClass("list-group-item list-group-item-action").attr("data-toggle","list").attr("href","#ticket" ticket).attr("id","ticket" ticket "-tab").append(newdiv);
        $("#ticketpanel").append(newa);
        $(".newlyaddedclose").on("click",".close",closebtn).removeClass("newlyaddedclose");
        // Create DIV with content
        var newdata = $("<div>").addClass("tab-pane").attr("id","ticket" ticket);
        $("#ticket-tabs").append(newdata);
        $("#ticket" ticket "-tab").tab("show");
    } else {
        // Ticket is already open, switch to it instead
        $("#ticket" ticket "-tab").tab("show");
    }
  });
})
  

Комментарии:

1. .on(«click»,».close»,closebtn) <— гм, вы говорите, что вызываемая функция — closeBtn …. но это ссылка на кнопку….

2. closebtn — это функция, которую я определил в другом месте в моем теге script. Именно там я создам обработчик при нажатии закрытых кнопок.

3. Ну, я предполагаю, что он перезаписывается closeBtn, на который вы ссылаетесь…. Невозможно определить с помощью предоставленного кода.

4. И вот, с помощью редактирования вы доказали, что у вас есть две переменные с одним и тем же.

Ответ №1:

В ошибке четко указано, что вы привязываете не функцию к прослушивателю событий. Итак, ошибка говорит, что closeBtn это не функция. Ваш код, который вы определили closeBtn как кнопку, к которой вы пытаетесь присоединить событие. Итак, измените closeBtn в прослушивателе событий щелчка имя функции, которую вы на самом деле пытаетесь вызвать. Если это то же имя функции, переименуйте что-нибудь.

Ваша проблема:

 var closeBtn = 1;
if (1===1) {
  var closeBtn = 2;
  console.log(closeBtn);
}
console.log(closeBtn);  

Непонятно, почему вы выбираете элемент, который вы только что добавили. Вы можете просто прикрепить событие при создании кнопки, не нужно искать элемент.

 var closebtn = $("<button>")...
closeBtn.on("click", function (){
  console.log('clicked', closeBtn);
});
  

Или используйте делегирование событий, чтобы любой добавленный вами элемент запускал функцию.

 $("#ticketpanel").on("click", ".close", function () {
  const closeBtn = $(this);
  console.log('clicked', closeBtn);
});
  

Комментарии:

1. Я попытался добавить .on(«щелчок» …. строка в переменную, где она тоже создается, но результат был одинаковым в любом случае.

2. поскольку, как я уже говорил, вы используете одно и то же имя переменной …. closeBtn снаружи перезаписывается closeBtn внутри. Назовите свои переменные тем, что они делают.

3. facepalm Я продолжал игнорировать ту переменную, которую я создал с тем же именем, что и функция. Изменение имени этой функции на что-то другое и добавление его в переменную, в которой я создаю кнопку, работает. Спасибо, что указали на это и показали различные способы сделать это!