จะตั้งค่าแอตทริบิวต์ HTML5 ที่ต้องการใน Javascript ได้อย่างไร?


93

ฉันพยายามทำเครื่องหมายที่textช่องป้อนข้อมูลตามต้องการใน 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>

เมื่อผู้ใช้พยายามส่งจะได้รับข้อผิดพลาดในการตรวจสอบความถูกต้อง:

ป้อนคำอธิบายภาพที่นี่

แต่ตอนนี้ฉันต้องการตั้งค่าrequiredแอตทริบิวต์ที่"รันไทม์"ผ่าน Javascript:

<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แอตทริบิวต์เป็นเอกสารที่เป็นBoolean:

4.10.7.3.4 requiredแอตทริบิวต์

requiredแอตทริบิวต์เป็นแอตทริบิวต์แบบบูล เมื่อระบุองค์ประกอบจำเป็น

มีการเขียนด้วยมือมากมายเกี่ยวกับวิธีกำหนด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]

นั่นอาจนำไปสู่การแก้ปัญหา


4
ฉันไม่เข้าใจว่าทำไมพวกเขาไม่อนุญาตrequired="false"พวกเขาเคยเขียนเทมเพลตก่อนที่จะเขียนมาตรฐานหรือไม่? แอตทริบิวต์ที่มีเงื่อนไขมักจะเป็นความเจ็บปวดมันง่ายกว่าที่จะใส่บูลีนนั้นในค่าแอตทริบิวต์ ...
Christophe Roussy

เป็นไปได้หรือไม่ที่จะแสดงข้อความนั้นทับข้อมูลที่จำเป็น: "โปรดกรอกข้อมูลในฟิลด์นี้"
zygimantus

คำตอบ:


121

requiredเป็นคุณสมบัติสะท้อน (เช่นid, name, typeและเช่น) ดังนั้น:

element.required = true;

... องค์ประกอบ DOM ที่elementแท้จริงอยู่ที่ไหนinputเช่น:

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

(เพียงเพื่อความสมบูรณ์)

เรื่อง

จากนั้นค่าของแอตทริบิวต์ไม่ใช่สตริงว่างหรือชื่อบัญญัติของแอตทริบิวต์:

edName.attributes.required = [object Attr]

นั่นเป็นเพราะrequiredในรหัสนั้นเป็นวัตถุแอตทริบิวต์ไม่ใช่สตริง attributesเป็นNamedNodeMapที่มีค่าเป็นวัตถุAttr หากต้องการรับมูลค่าของหนึ่งในนั้นคุณต้องดูvalueคุณสมบัติของมัน แต่สำหรับแอตทริบิวต์บูลีนค่าจะไม่เกี่ยวข้อง แอตทริบิวต์มีอยู่ในแผนที่ (จริง) หรือไม่ปรากฏ (เท็จ)

ดังนั้นหากrequired ไม่สะท้อนให้คุณตั้งค่าโดยการเพิ่มแอตทริบิวต์:

element.setAttribute("required", "");

... ซึ่งเทียบเท่ากับelement.required = true. คุณต้องล้างมันโดยการลบทั้งหมด:

element.removeAttribute("required");

... ซึ่งเทียบเท่ากับelement.required = false.

แต่เราไม่จำเป็นต้องทำเช่นนั้นrequiredเพราะมันสะท้อนออกมา


คุณสามารถเพิ่มอะไรเกี่ยวกับ. prop ที่นี่ได้ไหม
mplungjan

@mplungjan - ฉันไม่แน่ใจว่าคุณหมายถึงอะไร ... ? jQuery?
TJ Crowder

ใช่เพราะสับสนว่า prod ไม่ทำงานใน DOM
mplungjan

110

เวอร์ชั่นสั้น

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

เวอร์ชันยาว

เมื่อ TJ 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.getAttributeและelement.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แอตทริบิวต์คืออะไร? คุณมีสองทางเลือกทั้งคุณสมบัติที่สะท้อนหรือผ่านการตั้งค่าแอตทริบิวต์อย่างถูกต้อง:

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

พูดอย่างเคร่งครัดค่าอื่น ๆ จะ "กำหนด" แอตทริบิวต์ แต่ความหมายของBooleanคุณลักษณะที่กำหนดว่ามันควรจะตั้งค่าเป็นสตริงที่ว่างเปล่า""เพื่อแสดงให้เห็นความจริง ต่อไปนี้วิธีการทำงานของทุกคนที่จะตั้ง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คุณสมบัติที่สะท้อนคุณยังสามารถใช้ค่า"falsey"ใด ๆเพื่อปิดและค่าที่แท้จริงเพื่อเปิดใช้งาน แต่เพียงยึดติดกับความจริงและเท็จเพื่อความชัดเจน

วิธีการตรวจสอบสำหรับrequired?

ตรวจสอบการมีอยู่ของแอตทริบิวต์ผ่าน.hasAttribute("required")วิธีการ:

if (edName.hasAttribute("required"))
{
}

คุณยังสามารถตรวจสอบผ่าน คุณสมบัติที่สะท้อนบูลีน.required :

if (edName.required)
{
}

1
อะไรคือความแตกต่างระหว่างตัวแปรelementและedName?
faintsignal

1
หนึ่งคือการที่ฉันลืมที่จะแปลงชื่อองค์ประกอบเฉพาะedName(เช่นชื่อกล่องใส่) elementลงในทั่วไป
Ian Boyd

"คุณต้องผ่านelement.getAttributeและelement.setAttribute:"เพื่อความชัดเจนคุณสามารถใช้attributes NamedNodeMapเพื่อเปลี่ยนค่าของแอตทริบิวต์หากคุณทราบว่ามีแอตทริบิวต์อยู่แล้วคุณไม่สามารถใช้เพื่อเพิ่มแอตทริบิวต์ที่ไม่มี (หรือเพื่อลบ หนึ่งนั่นคือ) ดังนั้นแนวทางดังกล่าวจึงไม่มีประโยชน์สำหรับแอตทริบิวต์บูลีนเช่นrequiredเพราะสิ่งที่สำคัญกับพวกเขาคือไม่ว่าจะอยู่ที่นั่นไม่ใช่คุณค่าของมัน แต่ใช่คุณสมบัติที่สะท้อนมักจะง่ายกว่า :-)
TJ Crowder

10

สิ่งที่สำคัญไม่ใช่แอตทริบิวต์ แต่เป็นคุณสมบัติและค่าของมันคือบูลีน

คุณสามารถตั้งค่าโดยใช้ไฟล์

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

10

และเวอร์ชัน jquery:

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

ฉันรู้ว่ามันไม่ใช่คำถาม แต่อาจมีคนคิดว่าสิ่งนี้มีประโยชน์ :)


2
ใช้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;

});

หากคุณต้องการป้อนข้อมูลพื้นที่ข้อความและเลือกองค์ประกอบที่จำเป็นทั้งหมด


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.