如何在Javascript中设置HTML5 required属性?

132
我正在尝试使用Javascript将文本输入框标记为必填项。
<input id="edName" type="text" id="name">

如果该字段最初被标记为 required
<form>
    <input id="edName" type="text" id="name" required><br>
    <input type="submit" value="Search">
</form>

当用户尝试提交时,会收到验证错误提示:

enter image description here

但是现在我想通过Javascript在“运行时”设置required属性:

<form>
    <input id="edName" type="text" id="name"><br>
    <input type="submit" value="Search">
</form>

使用相应的脚本:

//recommended W3C HTML5 syntax for boolean attributes
document.getElementById("edName").attributes["required"] = "";         

除了当我提交时,没有验证检查,也没有阻止。

设置HTML5验证布尔属性的正确方法是什么?

jsFiddle

你问属性的值是什么?

HTML5验证required属性文档中说明了它是一个布尔值

4.10.7.3.4 required属性

required属性是一个boolean attribute。当指定时,该元素是必需的。

有很多关于如何定义boolean属性的争论。HTML5规范指出:

元素上存在布尔属性表示其为真值,不存在则表示其为假值。

如果属性存在,则其值必须为空字符串或与属性规范名称的ASCII大小写不敏感匹配相同,且没有前导或尾随空格。

这意味着您可以通过两种不同的方式指定一个 required 布尔 属性:

edName.attributes.required = ""; //the empty string
edName.attributes.required = "required"; //the attribute's canonical name

但是属性真正的价值是什么?

当您查看此问题的jsFiddle示例时,您会注意到如果在标记中定义了required属性:

<input id="edName" type="text" id="name" required>

如果属性的值不是空字符串,也不是属性的规范名称:

edName.attributes.required = [object Attr]

那可能会导致一个解决方案。


5
我不明白为什么他们不允许使用required="false",在编写标准之前,他们有没有编写过模板?条件属性通常很麻烦,将布尔值放入属性值中要容易得多... - Christophe Roussy
能否手动显示所需输入的文本:“请填写此字段。”? - zygimantus
1
@ChristopheRoussy 同意。编写标准(HTML、CSS 甚至 JS)的人都是扭曲的思维。这些语言非常混乱,但由于被广泛使用而难以轻易替换,不幸的是... - Virus721
6个回答

165

required是一个反映属性(例如idnametype等),因此:

element.required = true;

...其中element是实际的input DOM元素,例如:

document.getElementById("edName").required = true;

(仅为完整性而提供。)

回复:

Then the attribute's value is not the empty string, nor the canonical name of the attribute:

edName.attributes.required = [object Attr]
那是因为required在该代码中是一个属性对象,而不是一个字符串;attributes是一个NamedNodeMap,其值为Attr对象。要获取其中一个的值,您需要查看其value属性。但对于布尔属性,值并不重要;属性要么存在于映射中(true),要么不存在(false)。
因此,如果未反映required,则可以通过添加属性来设置它:
element.setAttribute("required", "");

...这相当于element.required = true。要清除它,您需要完全删除它:

element.removeAttribute("required");

这相当于element.required = false

但是对于required,我们不需要这样做,因为它已经被反映出来了。


159

简短版本

element.setAttribute("required", "");    //turns required on
element.required = true;                 //turns required on through reflected attribute
jQuery(element).attr('required', '');    //turns required on
$("#elementId").attr('required', '');    //turns required on

element.removeAttribute("required");     //turns required off
element.required = false;                //turns required off through reflected attribute
jQuery(element).removeAttr('required');  //turns required off
$("#elementId").removeAttr('required');  //turns required off

if (edName.hasAttribute("required")) { }  //check if required
if (edName.required) { }                 //check if required using reflected attribute

长版本

当T.J. Crowder成功指出反射属性后,我意识到以下语法是错误的

element.attributes["name"] = value; //bad! Overwrites the HtmlAttribute object
element.attributes.name = value;    //bad! Overwrites the HtmlAttribute object
value = element.attributes.name;    //bad! Returns the HtmlAttribute object, not its value
value = element.attributes["name"]; //bad! Returns the HtmlAttribute object, not its value

你必须使用element.getAttributeelement.setAttribute来进行操作。
element.getAttribute("foo");         //correct
element.setAttribute("foo", "test"); //correct

这是因为该属性实际上包含一个特殊的HtmlAttribute对象:
element.attributes["foo"];           //returns HtmlAttribute object, not the value of the attribute
element.attributes.foo;              //returns HtmlAttribute object, not the value of the attribute

通过将属性值设置为"true",您错误地将其设置为一个String对象,而不是所需的HtmlAttribute对象。
element.attributes["foo"] = "true";  //error because "true" is not a HtmlAttribute object
element.setAttribute("foo", "true"); //error because "true" is not an HtmlAttribute object

概念上,正确的想法(用一种编程语言表达)是:
HtmlAttribute attribute = new HtmlAttribute();
attribute.value = "";
element.attributes["required"] = attribute;

这就是为什么:
  • getAttribute(name)
  • setAttribute(name, value)
存在的原因。它们在内部对HtmlAttribute对象赋值起到了作用。
此外,一些属性是反射的。这意味着你可以更方便地从Javascript中访问它们:
//Set the required attribute
//element.setAttribute("required", ""); 
element.required = true;

//Check the attribute
//if (element.getAttribute("required")) {...}
if (element.required) {...}

//Remove the required attribute
//element.removeAttribute("required");
element.required = false;

你不想做的是错误地使用.attributes集合:
element.attributes.required = true;     //WRONG!
if (element.attributes.required) {...}  //WRONG!
element.attributes.required = false;    //WRONG!

测试案例

这导致了对required属性的测试,比较通过属性返回的值和反射属性的使用情况。

document.getElementById("name").required;
document.getElementById("name").getAttribute("required");

带有结果:

HTML                         .required        .getAttribute("required")
==========================   ===============  =========================
<input>                      false (Boolean)  null (Object)
<input required>             true  (Boolean)  "" (String)
<input required="">          true  (Boolean)  "" (String)
<input required="required">  true  (Boolean)  "required" (String)
<input required="true">      true  (Boolean)  "true" (String)
<input required="false">     true  (Boolean)  "false" (String)
<input required="0">         true  (Boolean)  "0" (String)

尝试直接访问.attributes集合是错误的。它返回表示DOM属性的对象。
edName.attributes["required"] => [object Attr]
edName.attributes.required    => [object Attr]

这解释了为什么您永远不应直接访问 .attributes 集合。您正在操作的不是属性的 ,而是表示属性本身的对象。

如何设置 required?

设置属性 required 的正确方式是什么?您有两种选择,要么使用反射的 属性,要么通过正确设置属性:

element.setAttribute("required", "");         //Correct
element.required = true;                      //Correct

严格来说,任何其他值都会“设置”属性。但是布尔属性的定义规定它只能被设置为空字符串""来表示true。以下方法都可以用来设置required布尔属性,
但请不要使用它们:
element.setAttribute("required", "required"); //valid, but not preferred
element.setAttribute("required", "foo");      //works, but silly
element.setAttribute("required", "true");     //Works, but don't do it, because:
element.setAttribute("required", "false");    //also sets required boolean to true
element.setAttribute("required", false);      //also sets required boolean to true
element.setAttribute("required", 0);          //also sets required boolean to true

我们已经学到了直接设置属性是错误的。
edName.attributes["required"] = true;       //wrong
edName.attributes["required"] = "";         //wrong
edName.attributes["required"] = "required"; //wrong
edName.attributes.required = true;          //wrong
edName.attributes.required = "";            //wrong
edName.attributes.required = "required";    //wrong

如何清除必填项?
尝试移除“required”属性的技巧在于很容易意外地将其打开:
edName.removeAttribute("required");     //Correct
edName.required = false;                //Correct

以无效的方式:

edName.setAttribute("required", null);    //WRONG! Actually turns required on!
edName.setAttribute("required", "");      //WRONG! Actually turns required on!
edName.setAttribute("required", "false"); //WRONG! Actually turns required on!
edName.setAttribute("required", false);   //WRONG! Actually turns required on!
edName.setAttribute("required", 0);       //WRONG! Actually turns required on!

使用反射的.required属性时,您还可以使用任何“假值”来关闭它,并使用真值来打开它。但为了清晰起见,请只使用true和false。
如何检查required?
通过.hasAttribute("required")方法检查属性是否存在:
if (edName.hasAttribute("required"))
{
}

你还可以通过布尔反射的.required属性进行检查。
if (edName.required)
{
}

2
变量 elementedName 之间有什么区别? - faintsignal
1
一个问题是我忘记将特定的元素名称edName(即名称输入框)转换为通用的element - Ian Boyd
"你必须使用element.getAttributeelement.setAttribute:为了明确起见,如果你知道属性已经存在,你可以使用attributes NamedNodeMap来更改属性的值,但是你不能用它来添加不存在的属性(或删除已有的属性)。所以这种方法对于像required这样的布尔属性并不有用,因为重要的是它们是否存在,而不是它们的值是什么。但是,反射属性通常更容易。:-)" - T.J. Crowder

14

重要的不是属性而是属性值,其值为布尔类型。

您可以使用以下方式进行设置:

 document.getElementById("edName").required = true;

10

而且还有 JQuery 版本:

$('input').attr('required', true)
$('input').attr('required', false)

我知道这超出了问题的范围,但或许有人会发现这有用 :)


3
使用 prop() 替代 attr() :) - Poul Kruijt
1
@PierreDuc,现在是2019年了,我们不再使用:)了。 - a20
@a20 上次我检查过,我仍在使用它。所以,我想你是错的。 - Poul Kruijt
我在开玩笑跟我哥哥.. 抱歉! - a20

3
let formelems = document.querySelectorAll('input,textarea,select');
formelems.forEach((formelem) => {
  formelem.required = true;

});

如果您希望将所有输入框、文本框和下拉框设置为必填项。

0

试试这个...

document.getElementById("edName").required = true;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接