Why does my jQuery event handler fail when attached to multiple elements?

ε祈祈猫儿з 提交于 2019-12-10 11:46:01

问题


I am using jquery to add mulitple new "addTask" form elements to a "ul" on the page every time a link is clicked.

  $('span a').click(function(e){
    e.preventDefault();

     $('<li>\
     <ul>\
     <li class="sTitle"><input type="text" class="taskName"></li>\
     <li><input type="button" value="saveTask" class="saveTask button"></li>\
     </ul>\
     </l1>')
     .appendTo('#toDoList');
    saveTask();
});

These new nested ul elements all have an button with the same class "saveTask". I then have a function that allows you to save a task by clicking on an button with the class "saveTask".

// Save New Task Item 
function saveTask() {
    $('.saveTask').click(function() {
        $this = $(this);
        var thisParent = $this.parent().parent()

        // Get the value
        var task = thisParent.find('input.taskName').val();

        // Ajax Call 
        var data = {
            sTitle: task,
            iTaskListID: 29
        };

        $.post('http://localhost:8501/toDoLists/index.cfm/Tasks/save', 
            data, function(data) {

            var newTask = '<a>' + task + '</a>'
            thisParent.find('li.sTitle').html(newTask);
        });
        return false;
    });
}

This essentially allows the user to enter some text into a form input, hit save, and then the task gets saved into the database using ajax, and displayed on the page using jQuery.

This works fine when there is only one element on the page with the class "saveTask", but if I have more than 1 form element with the class "saveTask" it stops functioning correctly, as the variable "var task" shows as "undefined" rather than the actual value of the form input.


回答1:


Don't rely on the .parent() method. Use .closest('form') instead. So the following line:

var thisParent = $this.parent().parent()

should look something like this instead:

var thisParent = $this.closest('form');

EDIT: Based on the updated information you provided, it looks like when you're trying to register the click event handler it's failing out for some reason. Try this javascript instead as it will make use of the live event so that all the newly added items on the page will automatically have the click event autowired to them.:

$(function(){
    $('span a').click(function(e){
        e.preventDefault();

         $('<li>\
             <ul>\
             <li class="sTitle"><input type="text" class="taskName"></li>\
             <li><input type="button" value="saveTask" class="saveTask button"></li>\
             </ul>\
             </l1>')
             .appendTo('#toDoList');

    });

    $('.saveTask').live('click', function() {
        $this = $(this);
        var thisParent = $this.closest('ul');

        // Get the value
        var task = thisParent.find('input.taskName').val();

        // Ajax Call 
        var data = {
            sTitle: task,
            iTaskListID: 29
        };

        $.post('http://localhost:8501/toDoLists/index.cfm/Tasks/save', 
            data, function(data) {

            var newTask = '<a>' + task + '</a>'
            thisParent.find('li.sTitle').html(newTask);
        });
        return false;
    });
});



回答2:


First turn the save task into a function:

(function($){
  $.fn.saveTask= function(options){


   return this.each(function(){

     $this = $(this);
     $this.click(function(){

       var thisParent = $this.parent().parent()
                 //get the value
       var task = thisParent.find('input.taskName').val();
        // Ajax Call 
        var data = {
        sTitle: task,
        iTaskListID: 29
      };
      $.post('http://localhost:8501/toDoLists/index.cfm/Tasks/save', data, function(data){

        var newTask = '<a>' + task + '</a>'

        thisParent.find('li.sTitle').html(newTask);
      });
    });
  });
  return false;
})(jQuery)

When the app starts change the saveTask selector to this:

function saveTask(){
  $('.saveTask').saveTask();
}

Then on your add function:

function addTask(){
  $newTask = $("<div>Some Task stuff</div>");
  $newTask.saveTask();
}

This code is written very quickly and untested but essentially create a jQuery extension that handles for data submission then when ever a task is created apply the save task extension to it.




回答3:


I think you're looking for the live event.

Also, your code is a little awkward, since the click event is only added when the saveTask() function is called. In fact, the saveTask() function, doesn't actually save anything, it just adds the click event to the elements with the .saveTask class.




回答4:


What is your HTML structure?

It looks like your code can't find the input.taskName element.

Try setting thisParent to something like $this.closest('form'). (Depending on your HTML)




回答5:


You could try wrapping your click function in an each()

ie

function saveTask(){
$('.saveTask').each (function () {

     $this = $(this);

     $this.click(function() {

         var thisParent = $this.parent().parent()
                     //get the value
         var task = thisParent.find('input.taskName').val();
            // Ajax Call 
            var data = {
            sTitle: task,
            iTaskListID: 29
        };
        $.post('http://localhost:8501/toDoLists/index.cfm/Tasks/save', data, function(data){

             var newTask = '<a>' + task + '</a>'

            thisParent.find('li.sTitle').html(newTask);


        });
        return false;
      });
  })
}

I find this helps sometimes when you have issues with multiple elements having the same class



来源:https://stackoverflow.com/questions/2000925/why-does-my-jquery-event-handler-fail-when-attached-to-multiple-elements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!