ความแตกต่างระหว่างคุณสมบัติและคุณสมบัติใน HTML คืออะไร?


407

หลังจากการเปลี่ยนแปลงใน jQuery 1.6.1 ฉันได้พยายามกำหนดความแตกต่างระหว่างคุณสมบัติและคุณลักษณะใน HTML

เมื่อดูรายการบันทึกย่อประจำรุ่น jQuery 1.6.1 (ใกล้ด้านล่าง) ดูเหมือนว่ามีคุณสมบัติและคุณสมบัติ HTML ดังนี้

  • คุณสมบัติ: ทั้งหมดซึ่งมีค่าบูลีนหรือที่มีการคำนวณ UA เช่น selectedIndex

  • แอตทริบิวต์: 'แอตทริบิวต์' ที่สามารถเพิ่มลงในองค์ประกอบ HTML ซึ่งไม่ใช่บูลีนหรือมีค่าที่สร้าง UA

คิด?


6
เป็นไปได้ที่ซ้ำกันของ. prop () และ. atr ()
Naftali aka Neal

คำตอบ:


825

เมื่อเขียนซอร์สโค้ด HTML คุณสามารถกำหนดคุณสมบัติในองค์ประกอบ HTML ของคุณ จากนั้นเมื่อเบราว์เซอร์แยกรหัสของคุณโหนด DOM ที่เกี่ยวข้องจะถูกสร้างขึ้น โหนดนี้เป็นวัตถุและดังนั้นจึงมีคุณสมบัติ

ตัวอย่างเช่นองค์ประกอบ HTML นี้:

<input type="text" value="Name:">

มี 2 ​​คุณลักษณะ ( typeและvalue)

เมื่อเบราว์เซอร์แยกวิเคราะห์รหัสนี้วัตถุHTMLInputElementจะถูกสร้างขึ้นและวัตถุนี้จะมีคุณสมบัติหลายอย่างเช่น: accept, accessKey, align, alt, คุณลักษณะ, ออโต้โฟกัส, baseURI, การตรวจสอบ, childElementCount, childNode, classList, className, ลูกค้าความสูง ฯลฯ

สำหรับวัตถุโหนด DOM ที่ระบุคุณสมบัติคือคุณสมบัติของวัตถุนั้นและแอตทริบิวต์เป็นองค์ประกอบของattributesคุณสมบัติของวัตถุนั้น

เมื่อโหนด DOM ถูกสร้างขึ้นสำหรับองค์ประกอบ HTML ที่กำหนดคุณสมบัติส่วนใหญ่จะเกี่ยวข้องกับแอตทริบิวต์ที่มีชื่อเหมือนหรือคล้ายกัน แต่ไม่ใช่ความสัมพันธ์แบบหนึ่งต่อหนึ่ง ตัวอย่างเช่นสำหรับองค์ประกอบ HTML นี้:

<input id="the-input" type="text" value="Name:">

โหนด DOM ที่เกี่ยวข้องจะมีid, typeและvalueคุณสมบัติ (อื่น):

  • idคุณสมบัติเป็นคุณสมบัติสะท้อนสำหรับidแอตทริบิวต์: การเดินทางสถานที่ให้อ่านค่าแอตทริบิวต์และการตั้งค่าคุณสมบัติเขียนค่าแอตทริบิวต์ idเป็นคุณสมบัติที่สะท้อนกลับอย่างแท้จริงมันไม่ได้ปรับเปลี่ยนหรือ จำกัด ค่า

  • typeคุณสมบัติเป็นคุณสมบัติสะท้อนสำหรับtypeแอตทริบิวต์: การเดินทางสถานที่ให้อ่านค่าแอตทริบิวต์และการตั้งค่าคุณสมบัติเขียนค่าแอตทริบิวต์ typeไม่ใช่คุณสมบัติที่สะท้อนได้อย่างแท้จริงเนื่องจาก จำกัด เฉพาะค่าที่รู้จัก (เช่นประเภทที่ถูกต้องของอินพุต) หากคุณมี<input type="foo">แล้วtheInput.getAttribute("type")จะช่วยให้คุณ"foo"แต่จะช่วยให้คุณtheInput.type"text"

  • ในทางตรงกันข้ามvalueคุณสมบัติไม่ได้สะท้อนvalueคุณลักษณะ แต่มันคือค่าปัจจุบันของอินพุต เมื่อผู้ใช้เปลี่ยนค่าของกล่องป้อนข้อมูลด้วยตนเองvalueคุณสมบัติจะแสดงถึงการเปลี่ยนแปลงนี้ ดังนั้นหากผู้ใช้ป้อนข้อมูล"John"ลงในช่องป้อนข้อมูลแล้ว:

    theInput.value // returns "John"

    ขณะที่:

    theInput.getAttribute('value') // returns "Name:"

    valueคุณสมบัติสะท้อนให้เห็นถึงปัจจุบันข้อความเนื้อหาภายในกล่องใส่ในขณะที่valueแอตทริบิวต์มีเริ่มต้นข้อความเนื้อหาของvalueแอตทริบิวต์จากรหัสที่มา HTML

    ดังนั้นหากคุณต้องการทราบว่ามีอะไรอยู่ในกล่องข้อความให้อ่านคุณสมบัติ อย่างไรก็ตามหากคุณต้องการทราบว่าค่าเริ่มต้นของกล่องข้อความคืออะไรให้อ่านคุณสมบัติ หรือคุณสามารถใช้defaultValueคุณสมบัติซึ่งเป็นภาพสะท้อนที่แท้จริงของvalueคุณลักษณะ:

    theInput.value                 // returns "John"
    theInput.getAttribute('value') // returns "Name:"
    theInput.defaultValue          // returns "Name:"

มีหลายคุณสมบัติที่สะท้อนโดยตรงแอตทริบิวต์ของพวกเขา (มีrel, id) บางสะท้อนโดยตรงกับชื่อเล็กน้อยที่แตกต่างกัน ( htmlForสะท้อนให้เห็นถึงforคุณลักษณะclassNameสะท้อนให้เห็นถึงclassแอตทริบิวต์) หลายอย่างที่สะท้อนให้เห็นถึงแอตทริบิวต์ของพวกเขา แต่มีข้อ จำกัด / การปรับเปลี่ยน ( src, href, disabled, multiple) และอื่น ๆ บน. ข้อมูลจำเพาะครอบคลุมการสะท้อนชนิดต่าง ๆ


1
สวัสดี Sime ฉันเดาว่านี่ค่อนข้างคลุมเครือโดยเฉพาะถ้าคุณดูที่นี่: w3.org/TR/html4/index/attributes.htmlและไม่มีคำตอบที่ชัดเจน โดยทั่วไปจำเป็นต้องติดตามสิ่งที่ระบุไว้ในสรุปในบล็อก jQuery และจากนั้นบล็อกจะแมปไปที่อื่นและทำงานในทั้งสองกรณีพร้อมกับประสิทธิภาพการทำงานเล็กน้อยหากคุณใช้ prop ไม่ถูกต้องเมื่อคุณต้องการใช้ attr
schalkneethling

4
@oss ลิงก์ของคุณอ้างถึงรายการแอตทริบิวต์ HTML รายการนั้นไม่ชัดเจน - เป็นคุณลักษณะ
Šime Vidas

มีเอกสารเกี่ยวกับความสัมพันธ์บ้างไหม? @ ŠimeVidas
SKing7

3
ฉันสามารถหารายการแอตทริบิวต์ทั้งหมดไปยังคุณสมบัติ (เช่นfor-> htmlFor) และรายการคุณสมบัติที่คล้ายกันที่ใช้ค่าเริ่มต้นจากแอตทริบิวต์ แต่ยังไม่สะท้อนให้เห็น ( input.value) ฉันคาดหวังว่านี่จะเป็นที่ ๆ หนึ่งในแหล่งที่มาของห้องสมุดเช่นgithub.com/Matt-Esch/virtual-domแต่มันไม่ได้จัดทำเป็นเอกสารจริงๆ
sstur

1
@ พิมฉันไม่ได้อ่านด้วยตัวเอง แต่บทความชุด 4 ตอนนี้ดูเหมือนว่าเป็นแหล่งข้อมูลที่ดีมาก: twitter.com/addyosmani/status/1082177515618295808
Šime Vidas

53

หลังจากที่ได้อ่านSime Vidasคำตอบของฉันค้นหามากขึ้นและพบมากตรงไปตรงมาและง่ายต่อการเข้าใจคำอธิบายในเอกสารเชิงมุม

คุณสมบัติ HTML เทียบกับคุณสมบัติ DOM


คุณสมบัติที่กำหนดโดย HTML คุณสมบัติถูกกำหนดโดย DOM (โมเดลวัตถุเอกสาร)

  • แอตทริบิวต์ HTML บางอย่างมีการแมป 1: 1 กับคุณสมบัติ idเป็นตัวอย่างหนึ่ง

  • คุณลักษณะ HTML บางอย่างไม่มีคุณสมบัติที่สอดคล้องกัน colspanเป็นตัวอย่างหนึ่ง

  • คุณสมบัติ DOM บางอย่างไม่มีแอตทริบิวต์ที่เกี่ยวข้อง textContent เป็นตัวอย่างหนึ่ง

  • แอตทริบิวต์ HTML จำนวนมากปรากฏขึ้นเพื่อจับคู่กับคุณสมบัติ ... แต่ไม่ใช่ในแบบที่คุณคิด!

หมวดหมู่สุดท้ายนั้นสับสนจนคุณเข้าใจกฎทั่วไปนี้:

คุณสมบัติเริ่มต้นคุณสมบัติ DOM แล้วพวกเขาจะทำ ค่าคุณสมบัติสามารถเปลี่ยนแปลงได้; ค่าแอตทริบิวต์ไม่สามารถ

ตัวอย่างเช่นเมื่อเบราว์เซอร์แสดงผล<input type="text" value="Bob">มันจะสร้างโหนด DOM ที่สอดคล้องกับvalueคุณสมบัติที่เริ่มต้นเป็น "Bob"

เมื่อผู้ใช้ป้อน "Sally" ลงในกล่องอินพุตvalue คุณสมบัติองค์ประกอบ DOM จะกลายเป็น "Sally" แต่value แอตทริบิวต์ HTML จะไม่เปลี่ยนแปลงเมื่อคุณค้นพบว่าคุณถามองค์ประกอบอินพุตเกี่ยวกับแอตทริบิวต์นั้นหรือไม่: input.getAttribute('value')ส่งคืน "Bob"

คุณลักษณะ HTML valueระบุค่าเริ่มต้น value คุณสมบัติDOM คือค่าปัจจุบัน


disabledแอตทริบิวต์เป็นอีกหนึ่งตัวอย่างที่แปลกประหลาด disabledคุณสมบัติของปุ่ม นั้นเป็นfalseค่าเริ่มต้นดังนั้นปุ่มจึงเปิดใช้งาน เมื่อคุณเพิ่มแอdisabledททริบิวการมีอยู่ของมันจะเริ่มต้นdisabledคุณสมบัติของปุ่มtrueเพื่อปิดใช้งานปุ่ม

การเพิ่มและลบแอdisabledททริบิวต์ปิดใช้งานและเปิดใช้งานปุ่ม ค่าของแอตทริบิวต์นั้นไม่เกี่ยวข้องซึ่งเป็นสาเหตุที่คุณไม่สามารถเปิดใช้งานปุ่มด้วยการเขียน<button disabled="false">Still Disabled</button>.

การตั้งค่าdisabled คุณสมบัติของปุ่มปิดใช้งานหรือเปิดใช้งานปุ่ม มูลค่าของทรัพย์สินมีความสำคัญ

คุณลักษณะ HTML และคุณสมบัติ DOM ไม่เหมือนกันแม้ว่าจะมีชื่อเหมือนกันก็ตาม


ตัวอย่างนี้ไม่ถูกต้อง: colspanแอตทริบิวต์มีcolSpanคุณสมบัติ ... ดังนั้นคุณลักษณะใดที่ไม่มีคุณสมบัติที่เกี่ยวข้องในตอนนี้
Robert Siemer

46

คำตอบได้อธิบายวิธีการจัดการคุณสมบัติและคุณสมบัติที่แตกต่างกันไปแล้ว แต่ฉันอยากจะชี้ให้เห็นว่าสิ่งนี้บ้าอย่างสิ้นเชิง ถึงแม้ว่าจะเป็นสเป็คที่พอเหมาะก็ตาม

มันบ้าไปแล้วที่จะมีคุณสมบัติบางอย่าง (เช่นid, class, foo, bar ) เพื่อรักษาค่าประเภทเดียวใน DOM ในขณะที่คุณลักษณะบางอย่าง (เช่นเลือกถูกเลือก ) เพื่อรักษาสองค่า นั่นคือค่า "เมื่อโหลด" และค่าของ "สถานะไดนามิก" (DOM ไม่ควรที่จะแสดงสถานะของเอกสารในขอบเขตที่สมบูรณ์หรือไม่)

มันเป็นสิ่งจำเป็นอย่างยิ่งที่สองช่องใส่เช่นข้อความและช่องทำเครื่องหมาย ในลักษณะเดียวกันมาก หากช่องป้อนข้อความไม่เก็บค่า "แยกเมื่อโหลด" และค่า "ปัจจุบันไดนามิก" ทำไมช่องทำเครื่องหมาย หากช่องจะมีสองค่าสำหรับการตรวจสอบแอตทริบิวต์ทำไมมันไม่ได้มีสองสำหรับชั้นและรหัสแอตทริบิวต์? หากคุณคาดว่าจะเปลี่ยนค่าของฟิลด์ข้อความ * อินพุต * และคุณคาดหวังว่า DOM (เช่น "การแทนค่าแบบอนุกรม") เพื่อเปลี่ยนและสะท้อนการเปลี่ยนแปลงนี้ทำไมบนโลกนี้คุณจะไม่คาดหวังเหมือนกันจากฟิลด์อินพุตของ ประเภทช่องทำเครื่องหมาย เกี่ยวกับคุณสมบัติการตรวจสอบ?

ความแตกต่างของ "มันเป็นคุณสมบัติแบบบูลีน" เพียง แต่ไม่สมเหตุสมผลกับฉันหรืออย่างน้อยก็ไม่มีเหตุผลเพียงพอสำหรับเรื่องนี้


21
นี่ไม่ใช่คำตอบ แต่ฉันเห็นด้วยกับคุณ มันบ้ามาก
ซามูเอล

ใช่แนวคิดนี้แย่และไม่ควรเป็นมาตรฐานมากนัก นี่เป็นหนึ่งในกรณี (เช่น innerHTML เป็นต้น) ที่ดีใน IE แบบเก่าและควรได้รับการรับรองโดยมาตรฐาน คุณสมบัติและแอททริบิวถูกซิงโครไนซ์ทุกที่ที่เป็นไปได้แม้แต่แอททริบิวที่กำหนดเองทำให้การอ่าน js dot เป็นไวยากรณ์ที่ดีมาก HTML5 สร้างแท็ก HTML ที่กำหนดเองให้เป็นพลเมืองชั้นหนึ่งแอตทริบิวต์ที่กำหนดเองควรเป็นเช่นกัน คุณลักษณะนี้ถูกลบเนื่องจาก IE รุ่นเก่ายังคงเป็นปัญหาจริง - เราเพิ่งเห็น บริษัท เอกชนจำนวนมากที่ติดอยู่กับ IE แบบดั้งเดิมสำหรับระบบเก่าตอนนี้พบว่ามันถูกทำลายใน IE10
ไมค์เนลสัน

48
มันไม่ได้บ้า คุณเข้าใจผิด checkedแอตทริบิวต์เป็นตัวแทนจากdefaultCheckedสถานที่ให้บริการ (เช่นเดียวกันสำหรับป้อนข้อความที่valueแอตทริบิวต์เป็นตัวแทนจากdefaultValueทรัพย์สิน) คุณสมบัติที่สองcheckedจะต้องแสดงว่ามีการทำเครื่องหมายในช่องทำเครื่องหมายเพราะนี่เป็นส่วนที่แท้จริงของการทำงานของช่องทำเครื่องหมาย: มันเป็นแบบโต้ตอบและสามารถเปลี่ยนแปลงได้ (และรีเซ็ตเป็นค่าเริ่มต้นหากปุ่มรีเซ็ตฟอร์มอยู่) โดยผู้ใช้ ในทางที่คุณลักษณะอื่นเช่นidไม่ใช่ มันไม่เกี่ยวอะไรกับความจริงที่ว่ามันเป็นคุณสมบัติบูลีน
Tim Down

3
@ TimDown - ขอบคุณ ที่จริงฉันได้ผ่าน WTF? โคก.
pedz

12
@TimDown ฉันยังรู้สึกว่า "บ้า" เพราะวิธีการแบบลอจิคัลใด ๆ จะทำให้ชื่อคุณสมบัติและชื่อแอตทริบิวต์ตรงกันหรืออย่างน้อยไม่มีชื่อแอตทริบิวต์และชื่อคุณสมบัติที่ตรงกันที่ไม่เกี่ยวข้อง (เช่นแอตทริบิวต์ที่ตรวจสอบอ้างถึง defaultChecked คุณสมบัติในขณะที่คุณสมบัติที่ตรวจสอบไม่เกี่ยวข้อง) ในความเป็นจริงวิธีการเชิงตรรกะที่ทุกคนคิดว่าเป็นกรณีที่เริ่มต้นจะไม่แยกคุณลักษณะและคุณสมบัติทั้งหมด แอตทริบิวต์ไม่ควรเปลี่ยนรูป แต่ควรสะท้อนค่าคุณสมบัติเสมอ ไม่ควรมีความแตกต่างระหว่างทั้งสอง
dallin

10

อย่างดีเหล่านี้จะถูกระบุโดย w3c สิ่งที่เป็นคุณลักษณะและสิ่งที่เป็นคุณสมบัติ http://www.w3.org/TR/SVGTiny12/attributeTable.html

แต่ปัจจุบัน attr และ prop ไม่แตกต่างกันและมีเกือบเหมือนกัน

แต่พวกเขาชอบเสาสำหรับบางสิ่ง

สรุปการใช้งานที่ต้องการ

ควรใช้เมธอด .prop () สำหรับคุณสมบัติ / คุณสมบัติบูลีนและสำหรับคุณสมบัติที่ไม่มีอยู่ใน html (เช่น window.location) แอตทริบิวต์อื่น ๆ ทั้งหมด (สิ่งที่คุณเห็นใน html) สามารถและควรได้รับการจัดการต่อไปด้วยวิธีการ. attr ()

ดีจริง ๆ คุณไม่ต้องเปลี่ยนอะไรถ้าคุณใช้ attr หรือ prop หรือทั้งสองอย่างทำงาน แต่ฉันเห็นในแอปพลิเคชันของตัวเองที่ prop ทำงานที่ atrr ไม่ได้ดังนั้นฉันจึงเอาแอปพลิเคชัน 1.6 prop =)


เฮ้แดเนียลฉันอ่านแล้ว ดูเหมือนว่ามีคำจำกัดความที่ชัดเจนในการแยกทั้งสองอย่างเนื่องจาก Sime ที่กล่าวถึงด้านล่างสามารถเพิ่มลงในองค์ประกอบ HTML ได้เช่น alt จะอ่านข้อมูลจำเพาะ HTML ต่อไปและดูว่ามีวิธีการแยกความแตกต่างทั้งสองอย่างชัดเจน
schalkneethling

3
เอกสารนั้นเกี่ยวข้องกับ SVG ไม่ใช่ HTML
Luzado

5

คุณสมบัติและแอตทริบิวต์ HTML ที่แตกต่าง:

ก่อนอื่นเรามาดูคำจำกัดความของคำเหล่านี้ก่อนประเมินความแตกต่างใน HTML:

คำจำกัดความภาษาอังกฤษ:

  • คุณสมบัติหมายถึงข้อมูลเพิ่มเติมของวัตถุ
  • คุณสมบัติอธิบายคุณสมบัติของวัตถุ

ในบริบท HTML:

เมื่อเบราว์เซอร์วิเคราะห์ HTML มันจะสร้างโครงสร้างข้อมูลทรีซึ่งโดยทั่วไปแล้วจะเป็นการแสดงหน่วยความจำของ HTML มันโครงสร้างข้อมูลต้นไม้มีโหนดซึ่งเป็นองค์ประกอบ HTML และข้อความ คุณสมบัติและคุณสมบัติที่เกี่ยวข้องกับเรื่องนี้มีลักษณะดังต่อไปนี้:

  • คุณสมบัติเป็นข้อมูลเพิ่มเติมที่เราสามารถใส่ใน HTML เพื่อ เริ่มต้นคุณสมบัติ DOM บางอย่าง
  • คุณสมบัติจะเกิดขึ้นเมื่อเบราว์เซอร์แยกวิเคราะห์ HTML และสร้าง DOM แต่ละองค์ประกอบใน DOM มีชุดคุณสมบัติของตัวเองซึ่งถูกตั้งค่าทั้งหมดโดยเบราว์เซอร์ คุณสมบัติเหล่านี้บางอย่างสามารถมีค่าเริ่มต้นที่กำหนดโดยแอตทริบิวต์ HTML เมื่อใดก็ตามที่มีการเปลี่ยนแปลงคุณสมบัติ DOM ซึ่งมีผลต่อหน้าที่แสดงผลหน้านั้นจะเป็นแสดงผลอีกครั้งทันที

สิ่งสำคัญคือต้องตระหนักว่าการแมปของคุณสมบัติเหล่านี้ไม่ใช่ 1 ถึง 1 กล่าวอีกนัยหนึ่งไม่ใช่ทุกแอตทริบิวต์ที่เราให้กับองค์ประกอบ HTML จะมีคุณสมบัติ DOM ที่คล้ายกัน

นอกจากนี้ยังมีองค์ประกอบ DOM ที่แตกต่างกันคุณสมบัติที่แตกต่าง ตัวอย่างเช่น<input>องค์ประกอบมีคุณสมบัติค่าที่ไม่ได้อยู่ใน<div>สถานที่ให้บริการ

ตัวอย่าง:

มาดูเอกสาร HTML ต่อไปนี้:

 <!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">  <!-- charset is a attribute -->
  <meta name="viewport" content="width=device-width"> <!-- name and content are attributes -->
  <title>JS Bin</title>
</head>
<body>
<div id="foo" class="bar foobar">hi</div> <!-- id and class are attributes -->
</body>
</html>

จากนั้นเราตรวจสอบ<div>ในคอนโซล JS:

 console.dir(document.getElementById('foo'));

เราเห็นคุณสมบัติ DOM ต่อไปนี้ (chrome devtools ไม่ใช่คุณสมบัติทั้งหมดที่แสดง):

คุณสมบัติ html และคุณสมบัติ

  • เราจะเห็นได้ว่า id ของแอตทริบิวต์ใน HTML ตอนนี้ยังเป็นคุณสมบัติ id ใน DOM ด้วย รหัสได้รับการเริ่มต้นโดย HTML (แม้ว่าเราสามารถเปลี่ยนได้ด้วย javascript)
  • เราจะเห็นว่าแอตทริบิวต์ class ใน HTML ไม่มีคุณสมบัติคลาสที่สอดคล้องกัน ( classเป็นคีย์เวิร์ดที่สงวนไว้ใน JS) แต่ที่จริงแล้ว 2 คุณสมบัติและclassListclassName
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.