localhost环境下jQuery动态生成字段的required属性失效问题
动态生成输入框的
required校验在HTTP环境下失效的问题解决 问题背景
我遇到一个奇怪的问题:
- 直接本地打开页面(
file://协议)时,所有必填字段的required校验都正常工作; - 但通过
localhost(HTTP协议)访问同一页面时,jQuery动态生成的输入框无法触发必填校验,而原生的<select>组件的required属性在两种场景下都正常。
相关代码如下:
HTML代码
<html> <head> <title>Submit your data</title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <link href="style.css" rel="stylesheet"> <script src="jquery+ajax.js"></script> </head> <body> <div id="mainform"> <h1>Insert your data</h1> <form method="post" action="add_product.php"> <input type="hidden" name="submitted" value="true" required/> <fieldset id="product_list"> <legend>New Product</legend> <label>SKU:<input name="sku" required/></label> <label>Name:<input name="name" required/></label> <label>Price:<input name="price" required/></label> <label>Product Type</label> <select id="Product_Type" required> <option value="" selected>Select product type</option> <option value="Dvd" >DVD</option> <option value="Book">Book</option> <option value="Furniture">Furniture</option> </select> </fieldset> </div> <br /> <input type="submit" id="submit" value="Add"/> <div id='result'></div> <button id="back" class="back" onclick="location.href='index.html';">Go Back</button> </body> <!-- onClick="window.location.reload()" --> </html>
jQuery代码
var $input_DVD = $('<input id="dvd" placeholder="Size in Mb" required/>'); var $input_Book = $('<input id="book" placeholder="Weight in Kg" required/>'); var $input_FurnitureHeight = $('<input id="furnh" placeholder="Height in Cm" required/>'); var $input_FurnitureWidth = $('<input id="furnw" placeholder="Width in Cm" required/>'); var $input_FurnitureLength = $('<input id="furnl" placeholder="Length in Cm" required/>'); $(document).ready(function() { $('select#Product_Type').on('change', function() { $('#container').remove(); var val = $(this).val() $container = $('<fieldset id="container" class="inner" ></fieldset>'); if (val == "Dvd")$input_DVD.appendTo($container); if (val == "Book") $input_Book.appendTo($container); if (val == "Furniture"){ $input_FurnitureHeight.appendTo($container); $input_FurnitureWidth.appendTo($container); $input_FurnitureLength.appendTo($container); } $container.insertAfter($(this)).val(); }) });
问题根源
问题出在你提前创建了输入框DOM对象并反复复用:
- 页面加载时,你就创建了所有动态输入框的DOM元素;
- 每次切换产品类型时,你只是把这些已经存在的元素从旧容器移到新容器;
- 在HTTP协议环境下,浏览器的表单校验逻辑是在元素首次插入DOM时绑定的,当元素被移除再重新插入时,校验绑定会丢失(而
file://协议的浏览器行为特殊,没有触发这个问题); - 原生
<select>是一开始就在DOM里的,所以校验逻辑一直有效。
解决方案
每次切换产品类型时,重新创建对应的输入框元素,而不是复用之前的DOM对象。这样新生成的元素每次插入DOM时,浏览器都会重新绑定校验规则。
修改后的jQuery代码:
$(document).ready(function() { $('select#Product_Type').on('change', function() { $('#container').remove(); var val = $(this).val(); // 用const声明变量,避免全局污染 const $container = $('<fieldset id="container" class="inner" ></fieldset>'); if (val === "Dvd") { // 每次重新创建输入框 $('<input id="dvd" name="dvd_size" placeholder="Size in Mb" required/>').appendTo($container); } if (val === "Book") { $('<input id="book" name="book_weight" placeholder="Weight in Kg" required/>').appendTo($container); } if (val === "Furniture"){ $('<input id="furnh" name="furniture_height" placeholder="Height in Cm" required/>').appendTo($container); $('<input id="furnw" name="furniture_width" placeholder="Width in Cm" required/>').appendTo($container); $('<input id="furnl" name="furniture_length" placeholder="Length in Cm" required/>').appendTo($container); } $container.insertAfter($(this)); // 原代码的.val()是多余的,移除 }) });
额外优化点
- 给动态输入框添加
name属性:这样表单提交时,这些字段的值能被正确传递到后端; - 用
const/let声明变量:避免未声明的变量变成全局变量,造成潜在问题; - 移除多余的
.val()调用:原代码中$container.insertAfter($(this)).val();里的.val()没有意义,因为fieldset没有值属性。
这样修改后,不管是本地直接打开还是通过localhost访问,动态输入框的required校验都会正常触发了。
内容的提问来源于stack exchange,提问作者EdwardK
相关产品推荐
相关产品推荐

