将jquery升级到1.6.1后的附加功能执行

时间:2011-08-01 10:10:35

标签: javascript jquery

我最初使用jQuery 1.4.2为我开发的在线支持系统编写了一个基于ajax的小设置页面,它运行良好。但是,在升级到1.6.1之后,正在调用以前只调用过一次的函数的其他执行。

我有三个菜单选项,每个选项都有一个onclick事件,用于将特定页面加载到#settingsph div中。然后根据相关页面调用其他代码。 (如果没有定义,则apache服务器自动假定使用.php文件ext)

function open_page(name) {
    $("#settingsph").load("/includes/support/stg/"+name, function(){
        if(name == "managecontacts"){
            $("#contactselect").load("/includes/support/stg/contactsel");
        }else if(name == "changepw"){
            $(change_pw(), "changepw_box");
        }else if(name == "editcompany"){
            $(company_update(), "#company_update");
        }
    });
}

加载后,会向用户显示一个选择框,以选择要编辑的联系人。在Onchange中,调用以下函数。

function open_contact(id) {
    $("#contact_info").load("/includes/support/stg/editcontact?id="+id);
    if(id != "NewContact") {
        $(contact_update(), "#contact_update"); 
    }else{
        $(contact_add(), "#contact_add"); 
    }
}

让我们假设用户已经决定编辑他们的联系信息(所有3个更新页面使用大致相同的功能,但更改的变量反映了从中获取信息的页面)。

function contact_update() {
  $('input.text-input').css({backgroundColor:"#ffffe0"});
  $('input#ldate').live('focus', function(){
    $(this).datepick({dateFormat: 'dd/mm/yy'});                                   
  });
  $("input.text-input").live('focus', function(){
    $(this).css({backgroundColor:"#FFFFFF"});
  });
  $("input.text-input").live('blur', function(){                                      
    $(this).css({backgroundColor:"#ffffe0"});
  });
  $('.error','#contact_info').hide();

  $(".buttonupd").live('click', function() {
        // validate and process form
        // first hide any error messages
    $('.error').hide();

    var forename = $("input#forename").val();
    if (forename == "") {
      $("label#forename_error").show();
      $("input#forename").focus();
      $('input#forename').css({border:"solid #aa0000"});
    }else{
      $('input#forename').css({border:""});     
    }
    var surname = $("input#surname").val();
    if (surname == "") {
      $("label#surname_error").show();
      $("input#surname").focus();
      $('input#surname').css({border:"solid #aa0000"});
    }else{
      $('input#surname').css({border:""});  
    }
    var phone = $("input#phone").val();
    if (phone == "") {
      $("label#phone_error").show();
      $("input#phone").focus();
      $('input#phone').css({border:"solid #aa0000"});
    }else{
      $('input#phone').css({border:""});    
    }
    var email = $("input#email").val();
    if (email == "") {
      $("label#email_error").show();
      $("input#email").focus();
      $('input#email').css({border:"solid #aa0000"});
    }else{
      $('input#email').css({border:""});    
    }
    if((forename == "") || (surname == "") || (phone == "") || (email == "")){
        return false;   
    }   
    var contactid = $("input#contactid").val();
    var jobtitle = $("input#jobtitle").val();
    var site = $("select#site option:selected").val();
    var mobile = $("input#mob").val();
    var ldate = $("input#ldate").val();
    var loginallowed = $("input[name='loginallowed']:checked").val();
    var editaddress = $("input[name='editaddress']:checked").val();
    var editcontacts = $("input[name='editcontacts']:checked").val();
    var editcompany = $("input[name='editcompany']:checked").val();
    var lognewissue = $("input[name='lognewissue']:checked").val();
    var viewallissues = $("input[name='viewallissues']:checked").val();
    var viewchangelog = $("input[name='viewchangelog']:checked").val();
    var viewdownloads = $("input[name='viewdownloads']:checked").val();
    var newissuenotify = $("input[name='newissuenotify']:checked").val();
    var closeissuenotify = $("input[name='closeissuenotify']:checked").val();
    var changelognotify = $("input[name='changelognotify']:checked").val();
    var viewsitehardware = $("input[name='viewsitehardware']:checked").val();
    var viewcompanyhardware = $("input[name='viewcompanyhardware']:checked").val();

    var dataString = 'contactid=' + contactid + '&forename=' + forename + '&surname=' + surname + '&jobtitle=' + jobtitle + '&site=' + site + '&email=' + email + '&phone=' + phone + '&mob=' + mobile + '&ldate=' + ldate + '&loginallowed=' + loginallowed + '&editaddress=' + editaddress + '&editcontacts=' + editcontacts + '&editcompany=' + editcompany + '&lognewissue=' + lognewissue + '&viewallissues=' + viewallissues + '&viewsitehardware=' + viewsitehardware + '&viewcompanyhardware=' + viewcompanyhardware + '&viewchangelog=' + viewchangelog + '&viewdownloads=' + viewdownloads + '&newissuenotify=' + newissuenotify + '&closeissuenotify=' + closeissuenotify + '&changelognotify=' + changelognotify;
        //alert (dataString);return false;

    $.ajax({
      type: "POST",
      url: "/includes/support/stg/contactupd",
      data: dataString,
      success: function() {
        $('#contact_update').html("<div id='contact_upd_msg'></div>");
        $('#contact_upd_msg').html("<h2>Contact Successfully Updated</h2>")
        .append("<p>Thank you.</p>")
        .hide()
        .fadeIn(1500, function() {
          $('#contactselect').html("")
          $("#contactselect").load("/includes/support/stg/contactsel");
        });
      }
     });
    return false;
  });
}

第一次执行该函数时,它只被调用一次并且看起来很好。但是,如果第二次调用上述函数可能更新另一个联系人,则会发送两个请求,两次更新信息并使用两次联系人列表刷新选择框。如果第三次调用上述函数,则会发送三个请求,依此类推,直到页面完全刷新为止。我恢复到1.4.2并且这些函数只执行一次,无论在没有页面刷新的情况下调用它们多少次。

当我第一次编写系统并且在加载了settings.php页面时,在DOM中不存在.buttonupd时,.live()方法被引入我here on SO。这是我的问题?

1 个答案:

答案 0 :(得分:2)

正如评论中提到的,您不应该在可以多次调用的函数中附加事件。每次在该函数中调用live时,都会附加一个新的事件处理程序。这就是为什么如果该方法被调用3次,触发事件将导致处理程序运行3次。

这是一个精简的例子:

http://jsfiddle.net/N78MX/

请注意,每次单击时,添加的单词数量都会增加一个。这是因为每次点击都会调用live并附加另一个处理程序。

您可以通过简单地移动功能之外的所有live来解决此问题。由于您使用的是live,因此可以在创建相关元素之前调用它。因此,精简的例子就变成了这个:

http://jsfiddle.net/N78MX/1

无论您点击多少次,它都能正常工作。 (显然,如果这是一个真实的页面,我会将这两个live调用结合起来,但这只是为了说明。)