Sự khác biệt giữa các thuộc tính và thuộc tính trong HTML là gì?


408

Sau những thay đổi được thực hiện trong jQuery 1.6.1, tôi đã cố gắng xác định sự khác biệt giữa các thuộc tính và thuộc tính trong HTML.

Nhìn vào danh sách trên các ghi chú phát hành jQuery 1.6.1 (gần cuối), có vẻ như người ta có thể phân loại các thuộc tính và thuộc tính HTML như sau:

  • Thuộc tính: Tất cả những gì có giá trị boolean hoặc được tính toán bằng UA, chẳng hạn như chọn Index.

  • Các thuộc tính: 'Các thuộc tính' có thể được thêm vào một phần tử HTML không phải là boolean cũng không chứa giá trị được tạo UA.

Suy nghĩ?


6
Bản sao có thể có của .prop () so với .attr ()
Naftali aka Neal

Câu trả lời:


826

Khi viết mã nguồn HTML, bạn có thể xác định các thuộc tính trên các thành phần HTML của mình. Sau đó, khi trình duyệt phân tích mã của bạn, một nút DOM tương ứng sẽ được tạo. Nút này là một đối tượng, và do đó nó có các thuộc tính .

Chẳng hạn, phần tử HTML này:

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

có 2 thuộc tính ( typevalue).

Khi trình duyệt phân tích mã này, một đối tượng HTMLInputE bổ sung sẽ được tạo và đối tượng này sẽ chứa hàng tá thuộc tính như: accept, accessKey, align, alt, các thuộc tính, tự động lấy nét, baseURI, đã kiểm tra, childEuityCount, childNodes, children, classList, className, khách hàng, v.v.

Đối với một đối tượng nút DOM đã cho, các thuộc tính là các thuộc tính của đối tượng đó và các thuộc tính là các thành phần của thuộc attributestính của đối tượng đó.

Khi một nút DOM được tạo cho một phần tử HTML nhất định, nhiều thuộc tính của nó liên quan đến các thuộc tính có cùng tên hoặc tương tự, nhưng đó không phải là mối quan hệ một đối một. Chẳng hạn, đối với phần tử HTML này:

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

nút DOM tương ứng sẽ có id, typevaluetài sản (số những người khác):

  • Các idbất động sản là một tài sản phản ánh cho idthuộc tính: Bắt tài sản lần đọc giá trị thuộc tính, và thiết lập tài sản ghi giá trị thuộc tính. idlà một thuộc tính phản ánh thuần túy , nó không sửa đổi hoặc giới hạn giá trị.

  • Các typebất động sản là một tài sản phản ánh cho typethuộc tính: Bắt tài sản lần đọc giá trị thuộc tính, và thiết lập tài sản ghi giá trị thuộc tính. typekhông phải là một thuộc tính được phản ánh thuần túy bởi vì nó bị giới hạn ở các giá trị đã biết (ví dụ: các loại đầu vào hợp lệ). Nếu bạn đã có <input type="foo">, sau đó theInput.getAttribute("type")cung cấp cho bạn "foo"nhưng theInput.typecung cấp cho bạn "text".

  • Ngược lại, thuộc valuetính không phản ánh valuethuộc tính. Thay vào đó, nó là giá trị hiện tại của đầu vào. Khi người dùng thay đổi thủ công giá trị của hộp đầu vào, thuộc valuetính sẽ phản ánh thay đổi này. Vì vậy, nếu người dùng "John"nhập vào hộp đầu vào, thì:

    theInput.value // returns "John"

    trong khi:

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

    Các valuebất động sản phản ánh hiện tại văn bản nội dung bên trong hộp đầu vào, trong khi các valuethuộc tính chứa ban đầu văn bản nội dung của các valuethuộc tính từ mã nguồn HTML.

    Vì vậy, nếu bạn muốn biết những gì hiện trong hộp văn bản, hãy đọc thuộc tính. Tuy nhiên, nếu bạn muốn biết giá trị ban đầu của hộp văn bản là gì, hãy đọc thuộc tính. Hoặc bạn có thể sử dụng thuộc defaultValuetính, đó là sự phản ánh thuần túy của valuethuộc tính:

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

Có một số tính năng mà trực tiếp phản ánh thuộc tính của họ ( rel, id), một số là phản ánh trực tiếp với những cái tên hơi khác nhau ( htmlForphản ánh forthuộc tính, classNamephản ánh classthuộc tính), nhiều phản ánh thuộc tính của họ, nhưng với những hạn chế / sửa đổi ( src, href, disabled, multiple), vv trên. Các thông số kỹ thuật bao gồm các loại phản ánh.


1
Này Sime, tôi đoán điều này khá mơ hồ, đặc biệt nếu bạn có một cái nhìn ở đây: w3.org/TR/html4/index/attribut.html , và không có câu trả lời rõ ràng. Về cơ bản, một người cần phải làm theo những gì được nêu trong bản tóm tắt trên blog jQuery và thậm chí sau đó, cái này sẽ ánh xạ tới cái khác và hoạt động trong cả hai trường hợp với một cú đánh hiệu suất nhẹ nếu bạn sử dụng prop không chính xác khi bạn cần sử dụng attr
schalkneethling

4
@oss Liên kết của bạn đề cập đến một danh sách các thuộc tính HTML. Danh sách đó không mơ hồ - đó là những thuộc tính.
Vidime Vidas

Có một số tài liệu về mối quan hệ? @ ImeVidas
SKing7

3
Tôi có thể tìm thấy một danh sách đầy đủ các thuộc tính cho các thuộc tính (như for-> htmlFor) và tương tự như một danh sách các thuộc tính lấy giá trị ban đầu của chúng từ một thuộc tính, nhưng không phản ánh nó ( input.value). Tôi hy vọng nó sẽ ở đâu đó trong nguồn của một thư viện như github.com/Matt-Esch/virtual-dom nhưng nó không thực sự được ghi lại.
sstur

1
@Pim Tôi chưa đọc nó, nhưng loạt bài viết gồm 4 phần này có vẻ như là một tài nguyên tuyệt vời: twitter.com/addyosmani/status/1082177515618295808
Vidime Vidas

53

Sau khi đọc câu trả lời của Sime Vidas , tôi đã tìm kiếm thêm và tìm thấy một lời giải thích rất thẳng thắn và dễ hiểu trong các tài liệu góc cạnh .

Thuộc tính HTML so với thuộc tính DOM


Các thuộc tính được xác định bởi HTML. Các thuộc tính được định nghĩa bởi DOM (Mô hình đối tượng tài liệu).

  • Một vài thuộc tính HTML có ánh xạ 1: 1 đến các thuộc tính. idlà một ví dụ

  • Một số thuộc tính HTML không có thuộc tính tương ứng. colspanlà một ví dụ

  • Một số thuộc tính DOM không có thuộc tính tương ứng. textContent là một ví dụ

  • Nhiều thuộc tính HTML xuất hiện để ánh xạ tới các thuộc tính ... nhưng không phải theo cách bạn có thể nghĩ!

Danh mục cuối cùng đó gây nhầm lẫn cho đến khi bạn nắm được quy tắc chung này:

Các thuộc tính khởi tạo các thuộc tính DOM và sau đó chúng được thực hiện. Giá trị tài sản có thể thay đổi; giá trị thuộc tính không thể.

Ví dụ: khi trình duyệt hiển thị <input type="text" value="Bob">, nó tạo một nút DOM tương ứng với thuộc valuetính được khởi tạo thành "Bob".

Khi người dùng nhập "Sally" vào hộp đầu vào, phần tử DOM value bất động sản trở thành "Sally". Nhưng value thuộc tính HTML vẫn không thay đổi khi bạn khám phá nếu bạn hỏi yếu tố đầu vào về thuộc tính đó: input.getAttribute('value')trả về "Bob".

Thuộc tính HTML valuechỉ định giá trị ban đầu ; thuộc tính DOM value là giá trị hiện tại .


Các disabledthuộc tính là một ví dụ khác thường. disabledThuộc tính của nút falsetheo mặc định để nút được bật. Khi bạn thêm disabledthuộc tính, sự hiện diện của nó sẽ khởi tạo thuộc tính của nút disabledđể truenút bị vô hiệu hóa.

Thêm và xóa disabledthuộc tính vô hiệu hóa và kích hoạt nút. Giá trị của thuộc tính là không liên quan, đó là lý do tại sao bạn không thể kích hoạt nút bằng cách viết<button disabled="false">Still Disabled</button>.

Thiết của nút disabled sở hữu vô hiệu hóa hoặc cho phép các nút. Giá trị của tài sản quan trọng.

Thuộc tính HTML và thuộc tính DOM không giống nhau, ngay cả khi chúng có cùng tên.


Ví dụ này không đúng: colspanthuộc tính có thuộc tính colSpan. ... Vậy, thuộc tính nào hiện tại không có thuộc tính liên quan?
Robert Siemer

46

Các câu trả lời đã giải thích cách các thuộc tính và thuộc tính được xử lý khác nhau, nhưng tôi thực sự muốn chỉ ra mức độ hoàn toàn điên rồ này. Ngay cả khi nó là một số mức độ spec.

Thật là điên rồ, khi có một số thuộc tính (ví dụ: id, class, foo, bar ) chỉ giữ lại một loại giá trị trong DOM, trong khi một số thuộc tính (ví dụ: được chọn, được chọn ) để giữ lại hai giá trị; đó là giá trị "khi nó được tải" và giá trị của "trạng thái động". (Không phải DOM được cho là đại diện cho trạng thái của tài liệu đến mức tối đa của nó sao?)

Điều thực sự cần thiết là hai trường đầu vào , ví dụ văn bảnhộp kiểm hoạt động theo cùng một cách . Nếu trường nhập văn bản không giữ lại giá trị "khi được tải" riêng biệt và giá trị "hiện tại, động", tại sao hộp kiểm? Nếu hộp kiểm có hai giá trị cho thuộc tính được kiểm tra , tại sao nó không có hai giá trị cho thuộc tính lớpid ? Nếu bạn muốn thay đổi giá trị của trường văn bản * đầu vào * và bạn mong đợi DOM (tức là "biểu diễn nối tiếp") thay đổi và phản ánh sự thay đổi này, tại sao bạn không mong đợi điều tương tự từ trường đầu vào của loại hộp kiểm trên thuộc tính được kiểm tra?

Sự khác biệt của "nó là một thuộc tính boolean" chỉ không có ý nghĩa gì với tôi, hoặc, ít nhất là không phải là một lý do đầy đủ cho việc này.


21
Đây không phải là một câu trả lời nhưng tôi đồng ý với bạn; nó hoàn toàn điên rồ
Samuel

Có khái niệm này hút và không nên được tiêu chuẩn hóa quá tệ. Đây là một trong những trường hợp (ví dụ như InternalHTML chẳng hạn) rất tốt trong IE cũ và nên được các tiêu chuẩn chấp nhận. Các thuộc tính và thuộc tính được đồng bộ hóa bất cứ nơi nào có thể, ngay cả các thuộc tính tùy chỉnh, tạo cú pháp dấu chấm js rất dễ đọc. HTML5 làm cho các thẻ HTML tùy chỉnh là công dân hạng nhất, thuộc tính tùy chỉnh cũng phải như vậy. Tính năng này đã bị xóa do IE cũ vẫn còn là một vấn đề thực sự - chúng ta mới chỉ thấy rất nhiều tập đoàn bị mắc kẹt với IE cho các hệ thống cũ giờ đã phát hiện ra chúng bị hỏng trong IE10.
mike nelson

48
Nó không điên. Bạn đã hiểu lầm. Các checkedthuộc tính được biểu diễn bởi các defaultCheckedtài sản (tương tự như vậy đối với một đầu vào văn bản valuethuộc tính được biểu diễn bởi các defaultValuetài sản). Thuộc tính thứ hai checked, được yêu cầu để thể hiện xem hộp kiểm có được kiểm tra hay không vì đây là một phần nội tại của chức năng của hộp kiểm: nó có tính tương tác và có thể được thay đổi (và đặt lại về mặc định, nếu người dùng có nút đặt lại biểu mẫu) , theo cách mà một thuộc tính khác như idkhông. Không có gì để làm với thực tế rằng đó là một thuộc tính boolean.
Tim xuống

3
@TimDown - Cảm ơn. Điều đó thực sự đã đưa tôi qua WTF? cái bướu.
pedz

12
@TimDown Tôi vẫn cảm thấy nó "điên rồ" bởi vì bất kỳ cách tiếp cận logic nào cũng sẽ làm cho tên thuộc tính và tên thuộc tính khớp với nhau, hoặc ít nhất là không có tên thuộc tính và tên thuộc tính không liên quan (ví dụ: thuộc tính được kiểm tra đề cập đến defaultChecked tài sản trong khi tài sản được kiểm tra là không liên quan). Trong thực tế, cách tiếp cận logic mà mọi người giả định là trường hợp khi bắt đầu sẽ không tách rời các thuộc tính và thuộc tính. Các thuộc tính không nên bất biến mà phải luôn phản ánh các giá trị thuộc tính. Không nên có sự phân biệt giữa hai.
dallin

10

Chúng được chỉ định bởi w3c thuộc tính là gì và thuộc tính là gì http://www.w3.org/TR/SVGTiny12/attributionTable.html

nhưng hiện tại attr và prop không quá khác nhau và gần như giống nhau

nhưng họ thích chống đỡ một số thứ

Tóm tắt về cách sử dụng ưa thích

Phương thức .prop () nên được sử dụng cho các thuộc tính / thuộc tính boolean và cho các thuộc tính không tồn tại trong html (như window.location). Tất cả các thuộc tính khác (những thuộc tính bạn có thể thấy trong html) có thể và nên tiếp tục được thao tác với phương thức .attr ().

thực ra bạn không phải thay đổi thứ gì đó nếu bạn sử dụng attr hoặc prop hoặc cả hai, cả hai đều hoạt động nhưng tôi thấy trong ứng dụng của mình hoạt động mà atrr không hoạt động nên tôi đã sử dụng trong ứng dụng 1.6 prop =)


Này Daniel, tôi đã đọc nó. Dường như có định nghĩa cắt rõ ràng để tách hai phần, vì một số điều mà Sime đề cập dưới đây cũng có thể được thêm vào phần tử HTML, ví dụ như alt. Sẽ tiếp tục đọc một số thông số kỹ thuật HTML và xem liệu thực sự có cách nào để phân biệt rõ ràng hai thực tế này không.
schalkneethling

3
Tài liệu đó liên quan đến SVG chứ không phải HTML.
Luzado

5

Các thuộc tính và thuộc tính HTML khác nhau:

Trước tiên chúng ta hãy xem định nghĩa của những từ này trước khi đánh giá sự khác biệt trong HTML:

Định nghĩa tiếng anh:

  • Các thuộc tính đang đề cập đến thông tin bổ sung của một đối tượng.
  • Các thuộc tính đang mô tả các đặc điểm của một đối tượng.

Trong ngữ cảnh HTML:

Khi trình duyệt phân tích cú pháp HTML, nó sẽ tạo ra cấu trúc dữ liệu cây mà về cơ bản là biểu diễn bộ nhớ của HTML. Cấu trúc dữ liệu cây chứa các nút là các thành phần và văn bản HTML. Các thuộc tính và thuộc tính liên quan đến điều này là cách sau:

  • Các thuộc tính là thông tin bổ sung mà chúng ta có thể đưa vào HTML để khởi tạo một số thuộc tính DOM nhất định.
  • Các thuộc tính được hình thành khi trình duyệt phân tích cú pháp HTML và tạo DOM. Mỗi thành phần trong DOM có tập thuộc tính riêng được trình duyệt đặt. Một số thuộc tính này có thể có giá trị ban đầu được đặt bởi các thuộc tính HTML. Bất cứ khi nào thuộc tính DOM thay đổi có ảnh hưởng đến trang được hiển thị, trang sẽ được hiển thị lại ngay lập tức

Một điều cũng quan trọng là phải nhận ra rằng ánh xạ của các thuộc tính này không phải là 1 đến 1. Nói cách khác, không phải mọi thuộc tính mà chúng ta đưa ra trên một phần tử HTML sẽ có thuộc tính DOM có tên tương tự.

Hơn nữa có các yếu tố DOM khác nhau thuộc tính khác nhau. Ví dụ: một <input>phần tử có thuộc tính giá trị không có trên một thuộc <div>tính.

Thí dụ:

Hãy lấy tài liệu HTML sau:

 <!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>

Sau đó, chúng tôi kiểm tra <div>, trong bảng điều khiển JS:

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

Chúng tôi thấy các thuộc tính DOM sau (chrome devtools, không phải tất cả các thuộc tính được hiển thị):

thuộc tính và thuộc tính html

  • Chúng ta có thể thấy rằng id thuộc tính trong HTML bây giờ cũng là một thuộc tính id trong DOM. Id đã được khởi tạo bởi HTML (mặc dù chúng tôi có thể thay đổi nó bằng javascript).
  • Chúng ta có thể thấy rằng thuộc tính lớp trong HTML không có thuộc tính lớp tương ứng ( classlà từ khóa dành riêng trong JS). Nhưng thực tế 2 tài sản, classListclassName.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.