jQuery输入框规则在XMLHttpRequest动态加载后失效的问题及解决
问题
我用jQuery为输入框设置了格式规则,静态加载(不通过XMLHttpRequest)时规则正常生效,但通过XMLHttpRequest动态加载这些输入框后,所有规则都失效了。想知道原因,以及如何让规则在动态加载后依然生效。
相关代码如下:
z1.php 代码
<?php include('z1ajax.php'); ?> <html lang="en"> <head> <title>SIGN UP</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <link rel="shortcut icon" type="image/x-icon" href="/to/img/bqicon.png"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <style> body{ background-color:black; } </style> <script> window.onload=function(){ var signup = document.getElementById("signup"); var xhr = new XMLHttpRequest(); xhr.open("POST", "/to/z1ajax.php", true); xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhr.onreadystatechange=function(){ if(xhr.readyState==4 && xhr.status==200){ signup.innerHTML = xhr.responseText; } } var v="onload=yes"; xhr.send(v); } $(document).ready(function(){ $('#email').on('keyup',function(){ var $this = $(this); var value = $this.val(); $this.val(value.replace(/\s+/g,'')); //NO SPACE $(this).val($(this).val().toLowerCase()); //LOWERCASE }); $('#username').bind('keyup keypress blur', function(){ $(this).val(function(i, val) { return val.replace(/[^a-z]/,''); //LOWERCASE, NO SPACE, LETTER ONLY }); }); $('#namapang').bind('keyup keypress blur', function(){ $(this).val(function(i, val) { return val.replace(/[^a-z]/,''); //LOWERCASE, NO SPACE, LETTER ONLY }); }); $('#pwd').on('keyup',function(){ var $this = $(this); var value = $this.val(); $this.val(value.replace(/\s+/g,'')); //NO SPACE }); $('#city').bind('keyup keypress blur', function(){ $(this).val(function(i, val) { return val.replace(/[^a-zA-Z ]/,''); //LETTER ONLY WITH SPACE }); }); }); </script> </head> <body> <div id='signup'></div> </body> </html>
z1ajax.php 代码
<?php $onload=isset($_REQUEST['onload'])?$_REQUEST['onload']:null; if($onload=='yes'){ ?> <br> <div class='container'> <div class='row'> <div class='col-md-4'></div> <div class='col-md-4'> <center> <font size='4'><strong><font color='white'>SIGN UP</font></strong></font><br> </center> <br> <div class='input-group'> <span class='input-group-addon'><span class='glyphicon glyphicon-envelope'></span></span> <input type='email' id='email' class='form-control' placeholder='Email aktif'> </div> <br> <div class='input-group'> <span class='input-group-addon'><span class='glyphicon glyphicon-pushpin'></span></span> <input type='text' id='username' class='form-control' placeholder='username'> </div> <br> <div class='input-group'> <span class='input-group-addon'><span class='glyphicon glyphicon-credit-card'></span></span> <input type='text' id='namapang' class='form-control' placeholder='nama panggilan'> </div> <br> <div class='input-group'> <span class='input-group-addon'><span class='glyphicon glyphicon-credit-card'></span></span> <input type='password' id='pwd' class='form-control' placeholder='password untuk login'> <span class='input-group-addon'><span id='eye' class='glyphicon glyphicon-eye-close' onclick="seppwd('pwd')"></span></span> </div> <br> <div class='input-group'> <span class='input-group-addon'><span class='glyphicon glyphicon-home'></span></span> <input type='text' id='city' class='form-control' placeholder='kota'> </div> <br> </div> <div class='col-md-4'></div> </div> </div> <?php } ?>
问题原因
你的事件绑定逻辑在$(document).ready()中执行,此时页面初始化完成,但动态加载的输入框还不存在于DOM中。jQuery的直接事件绑定(比如$('#email').on(...)或者bind())只能绑定到当前已存在的DOM元素上,后续通过AJAX添加的元素不会自动继承这些事件绑定,所以规则失效。
另外,bind()是jQuery的旧方法,从jQuery 1.7开始就推荐使用on()替代,bind()本质上是on()的语法糖,功能一致但不够灵活。
修复方案
使用事件委托(Event Delegation):把事件绑定到一个一开始就存在于DOM中的父元素(比如你的#signup容器)上,然后通过选择器过滤触发事件的目标元素。事件委托利用事件冒泡机制,父元素能捕获到子元素的事件,即使子元素是后续动态添加的。
修改后的$(document).ready()代码如下:
$(document).ready(function(){ // 事件委托:绑定到#signup父元素,监听子元素#email的keyup事件 $('#signup').on('keyup', '#email', function(){ var $this = $(this); var value = $this.val(); $this.val(value.replace(/\s+/g,'')); // 移除空格 $(this).val($(this).val().toLowerCase()); // 转小写 }); $('#signup').on('keyup keypress blur', '#username', function(){ $(this).val(function(i, val) { return val.replace(/[^a-z]/,''); // 仅保留小写字母 }); }); $('#signup').on('keyup keypress blur', '#namapang', function(){ $(this).val(function(i, val) { return val.replace(/[^a-z]/,''); // 仅保留小写字母 }); }); $('#signup').on('keyup', '#pwd', function(){ var $this = $(this); var value = $this.val(); $this.val(value.replace(/\s+/g,'')); // 移除空格 }); $('#signup').on('keyup keypress blur', '#city', function(){ $(this).val(function(i, val) { return val.replace(/[^a-zA-Z ]/,''); // 仅保留大小写字母和空格 }); }); });
额外优化建议
- 既然已经用了jQuery,AJAX请求可以改用jQuery的
$.post()方法,代码更简洁:
window.onload=function(){ $.post("/to/z1ajax.php", {onload: "yes"}, function(response){ $('#signup').html(response); }); }
- 统一使用
on()方法替代bind(),保持代码一致性和兼容性。
内容的提问来源于stack exchange,提问作者Juna serbaserbi
相关产品推荐
相关产品推荐

