为什么我的jQuery事件处理程序在连接到多个元素时会失败?

时间:2010-01-04 17:31:49

标签: javascript jquery ajax event-handling

每次点击一个链接时,我都会使用jquery在页面上的“ul”中添加多个新的“addTask”表单元素。

  $('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();
});

这些新的嵌套ul元素都有一个具有相同类“saveTask”的按钮。然后,我有一个函数,允许您通过单击“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;
    });
}

这实际上允许用户在表单输入中输入一些文本,点击保存,然后使用ajax将任务保存到数据库中,并使用jQuery显示在页面上。

当页面上只有一个元素“saveTask”时,这个工作正常,但是如果我有一个带有“saveTask”类的多个表单元素,它就会停止正常运行,因为变量“var task”显示as“undefined”而不是表单输入的实际值。

5 个答案:

答案 0 :(得分:3)

不要依赖.parent()方法。请改用.closest('form')。所以以下一行:

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

应该看起来像这样:

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

修改 根据您提供的更新信息,看起来当您尝试注册Click事件处理程序时,由于某种原因它会失败。请尝试使用此javascript,因为它会使用live事件,以便页面上所有新添加的项目都会自动将点击事件自动发送给他们。:

$(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;
    });
});

答案 1 :(得分:1)

首先将保存任务转换为函数:

(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)

当应用程序启动时,将saveTask选择器更改为:

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

然后在你的添加功能:

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

此代码编写速度非常快且未经测试,但实际上创建了一个jQuery扩展,用于处理数据提交,然后在创建任务时应用保存任务扩展。

答案 2 :(得分:0)

我认为你正在寻找live event

此外,您的代码有点尴尬,因为只有在调用saveTask()函数时才会添加click事件。实际上,saveTask()函数实际上并没有保存任何东西,只是将click事件添加到带有.saveTask类的元素中。

答案 3 :(得分:0)

您的HTML结构是什么?

您的代码看起来无法找到input.taskName元素。

尝试将thisParent设置为$this.closest('form')之类的内容。 (取决于您的HTML)

答案 4 :(得分:-1)

您可以尝试将click函数包装在each()

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;
      });
  })
}

我发现当你遇到具有相同类别的多个元素的问题时,这会有所帮助