getAttribute () so với thuộc tính đối tượng Element?


92

Biểu thức thích Element.getAttribute("id")Element.idtrả về cùng một thứ.

Cái nào nên được sử dụng khi chúng ta cần các thuộc tính của một đối tượng HTMLElement?

Có bất kỳ vấn đề trình duyệt chéo nào với các phương pháp này như getAttribute()setAttribute()không?

Hoặc bất kỳ tác động nào đến hiệu suất giữa việc truy cập trực tiếp thuộc tính đối tượng và sử dụng các phương thức thuộc tính này?


Câu trả lời:


126

getAttributetruy xuất thuộc tính của phần tử DOM, trong khi el.idtruy xuất thuộc tính của phần tử DOM này. Chúng không giống nhau.

Hầu hết thời gian, thuộc tính DOM được đồng bộ hóa với các thuộc tính.

Tuy nhiên, sự đồng bộ hóa không đảm bảo cùng một giá trị . Một ví dụ cổ điển là giữa el.hrefel.getAttribute('href')cho một phần tử neo.

Ví dụ:

<a href="/" id="hey"></a>
<script>
var a = document.getElementById('hey')
a.getAttribute('href') // "/"
a.href // Full URL except for IE that keeps '/'
</script>

Hành vi này xảy ra vì theo W3C , thuộc tính href phải là một liên kết được hình thành tốt. Hầu hết các trình duyệt đều tôn trọng tiêu chuẩn này (đoán xem ai không?).

Có một trường hợp cho input's checkedtài sản. Thuộc tính DOM trả về truehoặc falsetrong khi thuộc tính trả về chuỗi "checked"hoặc một chuỗi rỗng.

Và sau đó, có một số thuộc tính chỉ được đồng bộ hóa một chiều . Ví dụ tốt nhất là thuộc valuetính của một inputphần tử. Thay đổi giá trị của nó thông qua thuộc tính DOM sẽ không thay đổi thuộc tính (chỉnh sửa: kiểm tra nhận xét đầu tiên để biết chính xác hơn).

Vì những lý do này, tôi khuyên bạn nên tiếp tục sử dụng thuộc tính DOM , chứ không phải thuộc tính, vì hành vi của chúng khác nhau giữa các trình duyệt.

Trong thực tế, chỉ có hai trường hợp bạn cần sử dụng các thuộc tính:

  1. Thuộc tính HTML tùy chỉnh, vì nó không được đồng bộ hóa với thuộc tính DOM.
  2. Để truy cập thuộc tính HTML tích hợp sẵn, thuộc tính này không được đồng bộ hóa từ thuộc tính và bạn chắc chắn mình cần thuộc tính (ví dụ: bản gốc valuecủa một inputphần tử).

Nếu bạn muốn giải thích chi tiết hơn, tôi thực sự khuyên bạn nên đọc trang này . Bạn chỉ mất vài phút thôi, nhưng bạn sẽ rất vui vì thông tin (mà tôi tổng hợp ở đây).


9
+1 cho lời khuyên tốt nói chung. Tuy nhiên, điều đồng bộ hóa hơi bị tắt: thuộc valuetính của một đầu vào nhận được giá trị ban đầu của nó từ thuộc tính nhưng nếu không thì không bị ràng buộc với nó. Các valuethuộc tính được đầy đủ đồng bộ thay vì với defaultValuebất động sản. Tương tự như vậy checkeddefaultChecked. Ngoại trừ IE cũ (<= 7 và các chế độ tương thích sau này), đã bị hỏng getAttribute()setAttribute().
Tim Down

Đã thêm nhận xét của bạn là "giải thích thêm" :-)
Florian Margaine

2
Tôi nghĩ bạn đã nhầm ví dụ đầu tiên. a.hreftrả về URL đầy đủ, a.getAttribute("href")trả về thuộc tính chính xác như defiend trong nguồn HTML.
Salman A

Nếu bạn đang cố gắng tìm hiểu xem một giá trị có phải là giá trị không mặc định hay không, bạn nên sử dụng các thuộc tính. Nhiều trình duyệt hiện đại sẽ trả về giá trị mặc định (ví dụ input.formAction) hoặc chuỗi trống (ví dụ a.download), điều này làm cho mọi thứ trở nên mơ hồ. Ngoại lệ duy nhất là các giá trị không được đồng bộ hóa 2 chiều, chẳng hạn như value.
Kevin Li

Nếu id hoàn toàn không được đặt trong dom, getAttribute sẽ trả về null và element.id sẽ trả về một chuỗi trống. Đây có phải là một tiêu chuẩn?
Maciej Krawczyk

11

getAttribute('attribute') thường trả về giá trị thuộc tính dưới dạng một chuỗi, chính xác như được xác định trong nguồn HTML của trang.

Tuy nhiên, element.attributecó thể trả về giá trị được chuẩn hóa hoặc được tính toán của thuộc tính. Ví dụ:

  • <a href="https://stackoverflow.com/foo"></a>
    • a.href sẽ chứa URL đầy đủ
  • <input type="checkbox" checked>
    • input.checked sẽ là true (boolean)
  • <input type="checkbox" checked="bleh">
    • input.checked sẽ là true (boolean)
  • <img src='http://dummyimage.com/64x64/000/fff'>
    • img.width sẽ là 0 (số) trước khi hình ảnh được tải
    • img.width sẽ là 64 (số) khi hình ảnh (hoặc vài byte đầu tiên của nó) được tải
  • <img src='http://dummyimage.com/64x64/000/fff' width="50%">
    • img. width sẽ là 50% được tính toán
  • <img src='http://dummyimage.com/32x32/000/fff' style='width: 50px'>
    • img. width sẽ là 50 (số)
  • <div style='background: lime;'></div>
    • div.style sẽ là một đối tượng

3

Theo thử nghiệm jsPerf getAttribute này chậm hơn idtài sản.

PS

Thật kỳ lạ là cả hai câu lệnh đều hoạt động rất tệ trên IE8 (so với các trình duyệt khác).


3

Luôn sử dụng các thuộc tính trừ khi bạn có lý do cụ thể để không sử dụng.

  • getAttribute()setAttribute()bị hỏng trong IE cũ hơn (và chế độ tương thích trong các phiên bản mới hơn)
  • thuộc tính thuận tiện hơn (đặc biệt là những thuộc tính tương ứng với thuộc tính boolean)

một số ngoại lệ :

  • truy cập các thuộc tính của <form>các phần tử
  • truy cập các thuộc tính tùy chỉnh (mặc dù tôi không khuyến khích sử dụng các thuộc tính tùy chỉnh)

Tôi đã viết về chủ đề này một vài lần trên SO:


Trước IE 8, các thuộc tính và thuộc tính được xử lý giống nhau . Như bạn đã đề cập trước đó, tài sản là con đường để đi.

@MattMcDonald: Vâng, đó là sự đổ vỡ mà tôi đang ám chỉ. Tôi không mở rộng trên đó trong câu trả lời này bởi vì tôi cảm thấy tôi đã làm như vậy đủ trong câu trả lời khác tôi liên kết với :)
Tim Xuống

3

.idtiết kiệm chi phí cuộc gọi hàm. (rất nhỏ, nhưng bạn đã hỏi.)


Xin chào gdoron, chỉ vì tò mò: Tôi đã cố gắng tìm lời giải thích 'chính thức' về điều này (ngoài thử nghiệm thực nghiệm, đủ rõ ràng;))) nhưng không thành công. Bạn có bất kỳ liên kết về nó?
mamoo

0

Hãy thử ví dụ dưới đây để hiểu điều này hoàn toàn. Đối với DIV bên dưới

<div class="myclass"></div>

Các Element.getAttribute('class')sẽ trở lại myclassnhưng bạn phải sử dụng Element.classNamemà lấy nó từ tài sản DOM.


0

Một lĩnh vực mà điều này tạo ra sự khác biệt lớn là tạo kiểu css dựa trên các thuộc tính.

Hãy xem xét những điều sau:

const divs = document.querySelectorAll('div');

divs[1].custom = true;
divs[2].setAttribute('custom', true);
div {
  border: 1px solid;
  margin-bottom: 8px;
}

div[custom] {
  background: #36a;
  color: #fff;
}
<div>A normal div</div>
<div>A div with a custom property set directly.</div>
<div>A div with a custom attribute set with `setAttribute`</div>

Div với thuộc tính tùy chỉnh được đặt trực tiếp không phản ánh giá trị cho thuộc tính và không được chọn bởi bộ chọn thuộc tính của chúng tôi ( div[custom]) trong css.

setAttributeTuy nhiên, div có thuộc tính tùy chỉnh được đặt bằng cách sử dụng công cụ chọn thuộc tính css và được tạo kiểu cho phù hợp.

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.