有没有更好的方法将 jquery 事件处理程序包含在 xmlhttprequest() 中


Is there a better way to include jquery event handlers with xmlhttprequest()

我已经编写了我的网站所需的实时表单验证。它包含在我的javascript/jquery.js文件中,并执行以下操作:

//Let user know if they've left an invalid email in the field
 $signupEmail.on("blur", function() {
    var form = new SignupForm($signupEmail.val());
        if ( !form.isEmailEmpty() && !form.isEmailValid() ) {
            form.showEmailError("Invalid email");
        } else {
            form.isEmailRegistered();
            if (!form.emailError && form.isEmailValid()) {
                form.hideEmailError();
                form.showValidEmail();
            }
        }   
});

和:

 //Let user know when they've entered a valid email
$signupEmail.on("keyup", function() {
    var form = new SignupForm($signupEmail.val());
    var userEmail = form.userEmail();
     $.post("/sitename/scripts/checkEmailAvailability.php", {"userEmail": userEmail}, function (data) {
        if (form.isEmailValid() && !data) {
            form.showValidEmail();
        } else {
            form.hideEmailError();
        }
    });   
});

这代码和其余代码与我的注册和联系表单完美配合。

我还有一个名为users/的目录,其中包含一个名为account-settings/的子目录。子目录中的每个页面都包含不同的表单,用户可以提交以更新其帐户。例如,有一个更新电子邮件.php,更新密码.php等。这些页面通过xmlhttprequest()加载到帐户设置.php页面上。我遇到的问题是找出一种包含jquery实时验证的有效方法,除非包含在xmlhttp.onreadystatechange函数中,否则它似乎不起作用。就像现在一样,我必须包含两次 jquery 验证;一个用于注册/联系表单,另一个用于帐户设置表单。请查看以下代码:

站点/用户/帐户

设置/帐户设置.php

//php includes
//session configurations
 <div id="user-settings">
        <ul>
            <li><a href="#update-email">Update Email</a></li>
            <li><a href="#update-password">Update Password</a></li>
            <li><a href="#update-photo">Update Photo</a></li>
            <li><a href="#manage-friends">Manage Friends</a></li>
        </ul>
    </div>
    <div id="user-settings-forms">
    </div>
//php include footer


site/javascript/jquery.js

//Show User Profile's Settings Forms
$("#user-settings li").on('click', function() {
    var data = $(this).find('a').attr('href');
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
            document.getElementById("user-settings-forms").innerHTML = xmlhttp.responseText;
            // I'm currently duplicating all of the real-time validation here
            // If I move the code anywhere else, it doesn't work
            // This makes for a lot of redundancy
            // I also don't know how this affects the xmlhttprequest
        }
    }
    if (data === '#update-email') {
        xmlhttp.open('POST', 'update-email.php');
    } else if (data === '#update-password') {
        xmlhttp.open('POST', 'update-password.php');
    } else if (data === '#update-photo') {
        xmlhttp.open('POST', 'update-photo.php');
    } else if (data === '#manage-friends') {
        xmlhttp.open('POST', 'manage-friends.php');
    }
    xmlhttp.send();
});

到目前为止我尝试过的事情:
1. 在更新电子邮件.php、更新密码.php页面上包含必要的 jquery 代码。我想:好吧,如果我直接在使用它的页面上包含代码,那么无论页面是否通过 xmlhttprequest 传递,它都应该始终有效。但是,我错了。它不起作用。

2. 从更新电子邮件.php、更新密码.php页面中删除require("templates/header")。除其他事项外,此模板还包括指向我的 css 和 js 文件的所有链接。我想:当页面通过 xmlhttprequest 函数发送时,可能会发生模板冲突。这似乎只有一半合乎逻辑,因为 css 仍然毫无问题地渲染,但值得一试。

3.异步包含javascript文件,就像我使用谷歌地图一样。我想:由于 xmlhttprequest 是异步发生的,因此可能需要异步添加脚本。但是,这也不起作用。

那么,有没有更有效的方法可以包含属于通过 xmlhttprequest 对象传递的页面的 jquery 事件处理程序?如果这是唯一的方法,它如何影响 xmlhttprequest?放慢速度?一点变化都没有?添加过多的代码会以任何方式导致脚本出现问题吗?谢谢。我非常感谢你能提供的任何帮助。

问题是,通过分配给窗体上的innerHTML,您将销毁已附加处理程序的元素,并将它们替换为未附加处理程序的新元素。

这是事件委托的一个很好的用例:你把事件挂在表单上,而不是元素上,但告诉jQuery只在冒泡阶段通过给定元素时通知你事件。因此,假设您的$signupEmail字段有name="user-email"或类似的东西(您尚未显示它,所以我只是选择一些东西作为示例(。要处理其blur,请执行以下操作:

$("#user-settings-forms").on("blur", "input[name=user-email]", function() {
    /// Your validation logic here, this will refer to the user-email field
});

jQuery使像blurfocus这样的事件即使在它们本身不是的浏览器上也会冒泡。

有关事件委派的更多信息,请参阅.on文档。

上面专门连接了user-settings-forms元素,但您可以在两个表单上使用公共类以避免使其像这样具体,因此您可以在两个页面上包含验证脚本而无需修改。

下面是使用 .user-form-validate 类的示例:

$(".user-form-validate").on("blur keyup", "input[name=user-email]", function(e) {
  var $this = $(this),
      $validation = $this.closest("label").next(".validation-error");
  if (!$.trim($this.val())) {
    if (e.type === "blur" || e.type === "focusout") {
     $validation.text("Please fill in an email address").fadeIn();
    }
  } else {
    $validation.fadeOut();
  }
});
.validation-error {
  color: #a00;
}
<form class="user-form-validate">
  <label>Email address:
    <input type="text" name="user-email">
  </label>
  <p class="validation-error" style="display: none"></p>
  <div>
    <input type="button" value="Fake Send Button">
  </div>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>