Điều gì quá tệ về DOM?


42

Tôi liên tục nghe mọi người (đặc biệt là Crockford) nói rằng DOM là một API khủng khiếp, nhưng không thực sự biện minh cho tuyên bố này. Ngoài sự không nhất quán giữa các trình duyệt, một số lý do tại sao DOM được coi là rất tệ?


31
Apart from cross-browser inconsistenciesNhư vậy vẫn chưa đủ?
yannis

3
cùng một câu hỏi (bao gồm cả tham chiếu đến Crockford) đã được hỏi và đóng vì không mang tính xây dựng tại SO: Điều gì sai với DOM?
gnat

3
Hầu hết mọi người nói rằng DOM là khủng khiếp hoặc là không biết gì hoặc nói rằng các trình duyệt cũ là khủng khiếp
Raynos

Mô hình lan truyền sự kiện là sai: nó không cho phép các nút cha ghi đè các trình xử lý sự kiện con để thêm hành vi tùy chỉnh. Trong OOP, nó được gọi là các hàm ảo, đa hình và ủy quyền (thành phần thông qua kế thừa). Các sự kiện được chụp từ trên xuống dưới trước, sau đó nổi lên. Trong Elm, họ đã triển khai mô hình có thể kết hợp rất đầy đủ, trong đó bong bóng sự kiện trước tiên sau đó được "bắt" (truyền từ cha mẹ sang con cái). Nó cho phép hủy các sự kiện ("đóng cửa sổ?") Và ghi đè / trang trí hành vi của thành phần trẻ em.
Brian Haak

Câu trả lời:


33

Crockford đã trình bày rộng rãi với tiêu đề "API không liên quan: Lý thuyết về nhà ở" nơi ông ít nhiều giải thích ý kiến ​​của mình về DOM. Nó dài (1h 18m), nhưng như hầu hết các bài thuyết trình của Crockford, nó khá thú vị và mang tính giáo dục.

Sự không nhất quán giữa các trình duyệt dường như là mối quan tâm chính của anh ấy và tôi đồng ý rằng đó là điều khó chịu nhất về DOM. Ông xác định:

  • Bẫy độc quyền (bẫy trình duyệt và máy chủ),
  • Phá vỡ quy tắc,
  • Chiến tranh doanh nghiệp,
  • Áp lực thời gian cực độ

vì các vấn đề chính đằng sau những mâu thuẫn khác nhau, việc thêm phần trình bày, phiên hoặc tương tác không bao giờ được dự đoán trong tầm nhìn ban đầu của web. Một số ví dụ về sự không nhất quán bao gồm:

  • document.all, một tính năng duy nhất của Microsoft,
  • thực tế đó nameidđược sử dụng để có thể thay thế cho nhau.
  • các chức năng khác nhau trong việc truy xuất các nút:
    • document.getElementById(id),
    • document.getElementsByName(name),
    • *node*.getElementsByTagName(tagName))

và tiếp tục với một vài ví dụ nữa, chủ yếu là nhắm mục tiêu đi qua DOM, rò rỉ bộ nhớ và sự kiện nhỏ giọt và bong bóng. Có một slide tóm tắt, có tiêu đề "Các vết nứt của DOM" tóm tắt:

  • Danh sách lỗi DOM bao gồm tất cả các lỗi trong trình duyệt.
  • Danh sách lỗi DOM bao gồm tất cả các lỗi trong tất cả các trình duyệt được hỗ trợ.
  • Không có DOM hoàn toàn thực hiện các tiêu chuẩn.
  • Phần lớn DOM không được mô tả trong bất kỳ tiêu chuẩn nào.

Nói tóm lại, đó là một API lộn xộn, lộn xộn. Nó có vẻ giống như nitpicking, nhưng bạn phải nhớ rằng khi bạn đang phát triển cho web, bạn hiếm khi chọn trình duyệt mà khách hàng của bạn sẽ sử dụng. Phải kiểm tra mọi thứ trong ít nhất hai phiên bản của mỗi trình duyệt chính sẽ sớm bị cũ. Một API được cho là nhất quán và DOM là nạn nhân của các cuộc chiến trình duyệt , nhưng nó đã trở nên tốt hơn. Nó vẫn không phải là nền tảng trung lập như W3C (và tôi nghĩ rằng tất cả chúng ta) sẽ thích nó, nhưng các nhà cung cấp trình duyệt có vẻ khá háo hức hợp tác hơn so với năm hay mười năm trước.


18
sự không nhất quán giữa các trình duyệt không liên quan gì đến DOM. Đó là những gì chúng ta gọi là "trình duyệt cũ". Đừng đổ lỗi cho DOM về sự tồn tại của các trình duyệt cũ. Điều đó giống như nói "linux hút bởi vì tôi biết di sản distro n và m và họ hút".
Raynos

document.allnằm trong tiêu chuẩn
Raynos

@Raynos Có và không. Các nhà cung cấp trình duyệt đã là lực lượng chính đằng sau sự phát triển của các tiêu chuẩn web quá lâu, làm rối tung mọi thứ, sự tương tự với linux không có nhiều. Điều tôi đang cố gắng nhấn mạnh là bản thân DOM không bị lỗi, đó là những triển khai bị lỗi và cách thức không hoàn chỉnh của tiêu chuẩn phát triển. Lấy document.allví dụ, đó là trong các tiêu chuẩn nhưng như một sự vi phạm cố ý .
yannis

1
Tôi không thể bận tâm về những người khó hiểu về các trình duyệt cũ và DOM. Tôi đã để lại một bình luận. Đối với các trình duyệt cũ, bỏ hỗ trợ cho chúng là chuyện nhỏ, chỉ cần làm điều đó. Có những quả bóng để làm điều đó. Hoặc bạn kiểm soát cuộc sống phát triển của mình hoặc IE8 kiểm soát nó. Tôi kiểm soát của tôi.
Raynos

3
Câu trả lời chính xác; Một phiền toái khác mà bạn chưa đề cập là API DOM cực kỳ dài dòng - chỉ cần so sánh mã jQuery điển hình với, chèn một phần tử với một vài thuộc tính tại một nút cụ thể so với phiên bản DOM đơn giản giống như vậy.
tdammers

15

Có gì sai với DOM? Ngoài cú pháp lấy cảm hứng từ Java (mà Crockford đã chạm vào), không có gì.

Những gì "sai" áp dụng một phần cho các nhà cung cấp trình duyệt; những gì "sai" áp dụng cho các nhà phát triển; những gì "sai" áp dụng cho sự thiếu hiểu biết.

Vậy, bắt đầu từ đâu?

Xuống hố thỏ

Nhà cung cấp trình duyệt

Trước hết, các nhà cung cấp trình duyệt đã chiến đấu cạnh tranh trong nhiều thập kỷ để trở thành "tốt nhất", "nhanh nhất", "dễ nhất", v.v. Trong thập kỷ đầu tiên (199x, 2000), Microsoft đã thống trị. Internet Explorer đã giới thiệu những ý tưởng sáng tạo như:

  • phơi bày công cụ phân tích cú pháp HTML của trình duyệt như innerHTMLouterHTML;
  • thao tác văn bản dễ dàng với innerTextouterText;
  • một mô hình sự kiện ( *tachEvent) là kế hoạch chi tiết cho Sự kiện cấp 2 của DOM ( *EventListener).

Mỗi người đã đóng góp (tốt hơn và tồi tệ hơn) đáng kể cho ngăn xếp phát triển web ngày nay. Opera thậm chí đã đi xa đến mức thực hiện cả ba trong phiên bản 7 (2003).

Tuy nhiên, Netscape có mô hình sự kiện DOM ( *EventListener). Năm 2000, nó đã trở thành đặc tả sự kiện cấp 2 của DOM. Safari 1 (2003) đã triển khai mô hình này; Opera 7 (2003) cũng thực hiện mô hình này. Khi tàn tích của Netscape trở thành Mozilla, Firefox 1 (2004) đã kế thừa mô hình.

Đối với phần đầu tiên của thập kỷ thứ hai (2000, năm2004), Microsoft trị vì tối cao. Internet Explorer 6 (2001) là một trình duyệt tốt nhất vào thời điểm đó. Một trong những đối thủ cạnh tranh của nó, Opera 6 (2001), vẫn chưa triển khai Lõi cấp 1 DOM ( createElementet al.) Microsoft đã triển khai nó trong Internet Explorer 4 (1997) trước khi thông số kỹ thuật thậm chí trở thành khuyến nghị (1998).

Tuy nhiên, phần thứ hai của thập kỷ thứ hai (2004 Wap2010) sẽ chứng minh thảm họa cho Microsoft. Năm 2003, Apple đã phát hành Safari 1.0; vào năm 2004, Mozilla đã hoàn thành Firefox 1.0. Microsoft dường như đang ngủ trên ngai vàng trên đỉnh trình duyệt. Internet Explorer 7 không được phát hành cho đến năm 2006: khoảng cách năm năm kể từ ngày phát hành của Internet Explorer 6. Không giống như Internet Explorer phiên bản 4 đến 6, phiên bản 7 đổi mới ít; Thay đổi DOM là phút. Gần hai năm rưỡi sau, Internet Explorer 8 đã được phát hành. Microsoft đã thức dậy từ giấc ngủ của mình và nhận thấy sự hợp nhất các nhà cung cấp trình duyệt khác đã hình thành xung quanh nhiều tiêu chuẩn web. Thật không may, quá nhiều thời gian đã trôi qua kể từ lần đổi mới thực sự cuối cùng của Microsoft. Một phong trào đã được tạo ra giữa các nhà cung cấp trình duyệt. Các tính năng DOM mới đã được thêm vào ở dạng đặc tả cho W3C; Ý tưởng của Microsoft đã bị bỏ lại trong quá khứ. Mô hình sự kiện của Microsoft (*tachEvent) đã được sử dụng cho mô hình Sự kiện Cấp 2 của DOM. Internet Explorer đã không triển khai mô hình trước đó cho đến phiên bản 9 (2011), trở thành mô hình Sự kiện Cấp 3 của DOM.

Các đối tượng của Microsoft (DOM) có thể được tóm tắt bởi các điểm sau:

  • sự hiện diện như một tính năng cốt lõi của Windows và các yêu cầu bảo mật cấp hệ điều hành;

  • phụ thuộc vào ActiveX cho mã phía máy khách;

  • sự đổi mới giảm dần một cách tò mò sau phiên bản 6 (2001).


(Các nhà phát triển web

Thứ hai, các nhà phát triển chịu một số lỗi nhất định. Khi web tiếp tục cất cánh, ngày càng có nhiều người "lao đao" trong phát triển web. Điều này đã dẫn đến một sự pha loãng trong tài năng và đạo đức làm việc. Vấn đề, tuy nhiên, chủ yếu nằm ở thái độ. "Hoàn thành công việc nhanh chóng" được ưu tiên hơn "Hoàn thành công việc đúng đắn". Kết quả là, vô số trang web không tương thích với các trình duyệt khác nhau. Một trong những nguyên nhân hàng đầu của sự không tương thích này là một thực tiễn gọi là "tác nhân đánh hơi". Mặc dù thực tế vẫn còn được sử dụng cho đến ngày nay, nó đã được chứng minh là vừa sai lầm vừa có hại. Opera thậm chí đã đi xa đến mức "đóng băng" phiên bản tác nhân người dùng ở mức "9,80" trong phiên bản 10 (2009) và hơn thế nữa. Điều này nhằm ngăn chặn các kịch bản sai lầm phá vỡ. Một thực hành tốt hơn nhiều gọi là "


Vô minh

Thứ ba, điểm đổ lỗi ưa thích của tôi là sự thiếu hiểu biết; thiếu hiểu biết trong thực tế là các nhà cung cấp trình duyệt đã không làm việc với nhau gần như đủ để tạo ra các thông số kỹ thuật thống nhất; thiếu hiểu biết về việc Microsoft xa lánh người dùng các trình duyệt khác; sự thiếu hiểu biết trong thực tế là các nhà phát triển quá lười biếng hoặc quá cận thị để bận tâm nghiên cứu các trình duyệt (đặc biệt là các trình duyệt không thịnh hành .) Có nhiều sự khác biệt trong API và triển khai. Hầu hết có thể tránh được bằng cách tiếp cận đơn giản nhưng vẫn phòng thủ (phụ thuộc vào DOM 0) cùng với số lượng lớn cả nghiên cứu và thử nghiệm. Sự thiếu hiểu biết đã dẫn đến khái niệm rằng Internet Explorer 6 là một điểm sáng trên Trái đất (nhớ lại vị trí của nó trên ngai vàng trình duyệt đã đề cập trước đó.)


Suy tư

Đáng buồn thay, DOM chỉ là một API bị hiểu lầm. Nhiều người mong muốn ném đá (thông qua FUD), nhưng ít người mong muốn tìm hiểu sự phức tạp của nó. Một kết quả của sự thiếu hiểu biết này là việc giới thiệu "bộ chọn" DOM. DOM at heart là một API để thao tác (các) cây tài liệu. Chuyển đổi cây nên được sử dụng cho các vấn đề phức tạp được đưa ra dưới dạng tài liệu được phân tích cú pháp. Với việc giới thiệu API DOM Selector, giờ đây, một nhà phát triển có thể tận dụng công cụ truyền tải CSS của trình duyệt. Điều này khá thuận tiện, nhưng nó che giấu hình dạng thực sự của cây tài liệu. Với "bộ chọn", truy xuất nút phần tử là cơ bản. Tuy nhiên, DOM có mười một loại nút khác được chỉ định. Nút văn bản là gì? Nút bình luận? Nút tài liệu? Đây cũng là các nút thường được mong muốn trong khi tương tác với DOM.


Phần kết luận

Tóm lại, hãy dành thời gian của bạn và đọc các thông số kỹ thuật DOM khác nhau. Kiểm tra mã trong càng nhiều trình duyệt càng tốt. Nếu Internet Explorer bị coi là hành xử kỳ quặc, hãy tham khảo MSDN. Thông thường, các hành vi được ghi lại.

(Những giai thoại lịch sử có thể và có thể không chính xác; bất kỳ sự thiếu chính xác nào đều được chào đón.)

Mầm non


Opera thậm chí đã đi xa đến mức "đóng băng" - Tôi ghét cách tiếp cận này vì nó khá thiển cận (một số nhà phát triển không thể viết mã, vì vậy hãy sử dụng API để giúp họ). Bạn thường cần lấy loại và phiên bản trình duyệt khi có một lỗi cụ thể trong trình duyệt đó mà khách hàng của bạn khăng khăng sửa. Sửa lỗi cho trình duyệt cụ thể dễ dàng hơn nhiều so với thực hiện một số "phát hiện lỗi" (tức là ngược lại với "phát hiện tính năng").
Pavel Horal

3

DOM là một API khủng khiếp

Đó là SAI . DOM KHÔNG phải là một API khủng khiếp.

  • Đầu tiên, hãy nhớ rằng DOM là bất khả tri ngôn ngữ. Tất cả các ngôn ngữ chính đã triển khai API. Điều này là do bạn không sử dụng nó trong trình duyệt, nhưng ở mọi nơi bạn cần để xử lý XML.

  • Thứ hai, lưu ý rằng DOM không định nghĩa các lớp nhưng giao diện. Điều này có một ý nghĩa rất quan trọng: các ngôn ngữ có thể thực hiện nó theo cách nó phù hợp với cấu trúc và triết lý của họ. Điều này giải phóng tất cả các ngôn ngữ khỏi phải nhất quán trong việc thực hiện với những người khác.

  • Thứ ba, DOM là một trong hai cách chính để phân tích cú pháp XML (khác là SAX) và tùy thuộc vào ngữ cảnh của bạn, DOM có thể rất hiệu quả.

Những gì bạn đang đề cập đến là trình duyệt DOM. Và, tôi đồng ý rằng DOM "cảm thấy" tệ trong trình duyệt. Một phần lý do là sự không tương thích của trình duyệt. Nhưng, tôi không đồng ý rằng họ là lý do duy nhất cho tiếng xấu của DOM trong trình duyệt.

  • Đầu tiên, nếu bạn nghĩ về nó, DOM là một trong những lĩnh vực mà những sự không tương thích này tương đối dễ khắc phục hơn. Trong so sánh, các sự kiện, ví dụ như rất nhiều thủ thuật và gây khó chịu để bình thường hóa.

  • Thứ hai, phát hiện tính năng cho các tính năng DOM đơn giản hơn so với các khu vực khác.

  • Thứ ba, DOM 3 tốt hơn nhiều - và ngày nay tất cả các trình duyệt đều hỗ trợ phần lớn.

Chắc chắn, sự không tương thích gây khó chịu, nhưng khi bạn tiếp cận họ, DOM sẽ bớt khó chịu hơn rất nhiều.

Tôi cũng không đồng ý với các lý do như bẫy độc quyền, chiến tranh doanh nghiệp, v.v. là lý do cho nó.

  • Tôi nghĩ rằng đó là sự mất kết nối giữa triết lý của JavaScript là một ngôn ngữ nhẹ và việc triển khai DOM được lấy cảm hứng từ Java - điều đó đã góp phần vào sự thất vọng.

  • Thứ hai, DOM đã được thiết kế cho XML và nó đã được điều chỉnh cho HTML. Do đó trong trình duyệt, chúng tôi có chính xác hai DOM - HTML DOM và XML DOM - và chúng không tương thích.

  • Thứ ba, DOM traversal trong trình duyệt không tốt. Chúng tôi không có XPath cho HTML DOM, vì vậy trước các công cụ chọn CSS, thực sự rất tẻ nhạt khi thực hiện các giao dịch.

Cuối cùng, tôi nghĩ ngày nay , với các trình duyệt hiện đại, (và với các trình duyệt cũ dần dần biến mất), không có lý do gì DOM cần phải được gọi là xấu. Nó chắc chắn sẽ trở nên tốt hơn trong trình duyệt - cả API và triển khai.


các sự kiện chỉ là tầm thường để bình thường hóa: \
Raynos

nghĩ về nó - nếu bạn phải hỗ trợ currentTargettài sản cho đối tượng sự kiện-- nó có tầm thường không?
treecoder

triển khai bong bóng sự kiện giống như một dòng mã 100: \
Raynos

currentTargetkhông chỉ là bong bóng sự kiện - và nó có thực sự khôn ngoan khi thực hiện bong bóng sự kiện của riêng bạn không?
treecoder

1
Và với việc dataManagerngồi bên ngoài, bạn nói rằng mã đó là Trivial? :)
treecoder
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.