有没有更好的方法来包含jquery事件处理程序与xmlhttprequest()

时间:2014-12-07 09:27:19

标签: javascript php jquery html ajax

我已经为我的网站编写了必要的实时表单验证。它包含在我的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/。子目录中的每个页面都包含用户可以提交以更新其帐户的不同表单。例如,有一个update-email.php,update-password.php等。这些页面通过xmlhttprequest()加载到account-settings.php页面。我遇到的问题是找出一种包含jquery实时验证的有效方法,除非包含在xmlhttp.onreadystatechange函数中,否则它似乎无法工作。就像现在一样,我必须两次包含jquery验证;一个用于注册/联系表单,另一个用于帐户设置表单。请查看以下代码:

网站/用户/帐户的设置/帐户的settings.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


网站/ 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.在update-email.php,update-password.php页面中包含必要的jquery代码。我想:好吧,如果我将代码直接包含在将要使用它的页面上,无论页面是否通过xmlhttprequest传递,它都应该始终有效。但是我错了。它不起作用。

 2.从update-email.php,update-password.php页面中删除require("templates/header")。此模板包括我的css和js文件的所有链接。我想:当通过xmlhttprequest函数发送页面时,可能会发生模板冲突。它似乎只有一半逻辑,因为css仍然没有问题渲染但是,它值得一试。

 3.异步包含javascript文件,与Google map的方式相同。我想:由于xmlhttprequest是异步发生的,因此可能需要异步添加脚本。但是,这也不起作用

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

1 个答案:

答案 0 :(得分:0)

问题在于,通过在表单上分配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 documentation中的事件委托的详情。

上面特别勾勒出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>