Co jest tak złego w DOM?

42

Ciągle słyszę ludzi (w szczególności Crockford), którzy mówią, że DOM to straszne API, ale tak naprawdę nie uzasadniają tego stwierdzenia. Oprócz niespójności między przeglądarkami, jakie są niektóre powody, dla których DOM jest tak źle oceniany?

wheresrhys
źródło
31
Apart from cross-browser inconsistenciesCzy to nie wystarczy?
yannis
3
to samo pytanie (w tym odniesienie do Crockford) zostało zadane i zamknięte, ponieważ nie jest konstruktywne w SO: Co jest nie tak z DOM?
komar
3
Większość ludzi, którzy twierdzą, że DOM jest straszny, jest albo nieświadoma, albo mówi, że starsze przeglądarki są straszne
Raynos
Model propagacji zdarzeń jest niepoprawny: nie pozwala węzłom nadrzędnemu przesłonić procedury obsługi zdarzeń potomnych w celu dodania niestandardowego zachowania. W OOP nazywało się to funkcjami wirtualnymi, polimorfizmem i delegowaniem (dziedziczenie przez kompozycję). Zdarzenia są najpierw przechwytywane od góry do dołu, a następnie propagowane. W Elm wdrożyli bardzo adekwatny model, w którym zdarzenia najpierw bańkują, a następnie „przechwytują” (propagują od rodziców do dzieci). Pozwala anulować zdarzenia („zamknąć okno?”) I zastąpić / udekorować zachowanie elementu potomnego.
Brian Haak

Odpowiedzi:

33

Crockford przedstawił obszerną prezentację zatytułowaną „Niewygodne API: teoria domu”, w której mniej więcej wyjaśnia swoje opinie na temat modelu DOM. Jest długa (1h 18m), ale jak większość prezentacji Crockforda jest całkiem przyjemna i pouczająca.

Niespójności między przeglądarkami wydają się być jego głównym zmartwieniem i zgadzam się, że jest to najbardziej denerwująca rzecz w DOM. Identyfikuje:

  • Pułapki zastrzeżone (pułapki na przeglądarkę i serwer),
  • Łamanie zasad,
  • Wojna korporacyjna,
  • Ekstremalna presja czasu

jako kluczowe kwestie związane z różnymi niespójnościami, dodanie oryginalnej prezentacji, sesji lub interaktywności nigdy nie było przewidywane w oryginalnej wizji sieci. Niektóre przykłady niespójności obejmują:

  • document.all, funkcja tylko Microsoft,
  • fakt, że namei iddawniej zamiennie.
  • różne funkcje pobierania węzłów:
    • document.getElementById(id),
    • document.getElementsByName(name),
    • *node*.getElementsByTagName(tagName))

i kontynuuje kilka innych przykładów, głównie ukierunkowanych na przemierzanie DOM, wycieki pamięci oraz spływanie i bulgotanie zdarzeń. Istnieje slajd podsumowujący zatytułowany „Pęknięcia DOM”, który podsumowuje:

  • Lista błędów DOM zawiera wszystkie błędy w przeglądarce.
  • Lista błędów DOM zawiera wszystkie błędy we wszystkich obsługiwanych przeglądarkach.
  • Żaden DOM nie wdraża w pełni standardów.
  • Duża część DOM nie jest opisana w żadnym standardzie.

Krótko mówiąc, jest to niechlujny, niechlujny API. Może się to wydawać dziwne, ale musisz pamiętać, że gdy tworzysz strony internetowe, rzadko wybierasz przeglądarkę, z której będą korzystać Twoi klienci. Konieczność przetestowania wszystkiego w co najmniej dwóch wersjach każdej z głównych przeglądarek szybko się zestarzeje. Interfejs API ma być spójny, a DOM był ofiarą wojen w przeglądarkach , ale jest coraz lepiej. Wciąż nie jest tak neutralny dla platformy, jak W3C (i myślę, że wszyscy) chcieliby, aby tak było, ale producenci przeglądarek wydają się bardziej chętni do współpracy niż pięć czy dziesięć lat temu.

Yannis
źródło
18
niespójność między przeglądarkami nie ma nic wspólnego z DOM. To właśnie nazywamy „starszymi przeglądarkami”. Nie obwiniaj DOM za istnienie starszych przeglądarek. To tak, jakby powiedzieć: „linux jest do bani, bo znam dystrybucję starszego im, a oni do bani”.
Raynos
document.alljest w normach
Raynos
@Raynos Tak i nie. Dostawcy przeglądarek od dawna są główną siłą napędową ewolucji standardów internetowych, co psuje wszystko, analogia z linuksem nie ma większego znaczenia. Próbuję podkreślić, że sam DOM nie jest wadliwy, to wadliwe implementacje i niespójny sposób ewolucji standardu. Weźmy document.allna przykład, że jest to zgodne ze standardami, ale jako umyślne naruszenie .
yannis
1
Nie mogę się martwić, że ludzie mylą starsze przeglądarki i DOM. Zostawiłem komentarz. Jeśli chodzi o starsze przeglądarki, rezygnacja z ich obsługi jest banalna, po prostu zrób to. Przygotuj piłki. Albo kontrolujesz swoje życie programistyczne, albo IE8 je kontroluje. Kontroluję moje.
Raynos
3
Świetna odpowiedź; Inną uciążliwością, o której nie wspomniałeś, jest to, że DOM API jest bardzo gadatliwy - wystarczy porównać typowy kod jQuery, aby, powiedzmy, wstawić element z kilkoma atrybutami w określonym węźle w porównaniu z wersją zwykłego DOM, która robi to samo.
tdammers
15

Co jest nie tak z DOM? Poza składnią inspirowaną Javą (której dotknął Crockford), nic.

To, co „złe” dotyczy częściowo dostawców przeglądarek; co jest „złe” dotyczy programistów; to, co „złe” dotyczy ignorancji.

Więc od czego zacząć?

W dół króliczej nory…

Dostawcy przeglądarek

Po pierwsze, producenci przeglądarek walczyli przez dziesięciolecia o to, by być „najlepszym”, „najszybszym”, „najłatwiejszym” itd. W pierwszej dekadzie (199 x 2000) Microsoft rządził rynkiem. Internet Explorer wprowadził innowacyjne pomysły, takie jak:

  • ujawnienie silnika analizującego HTML przeglądarki jako innerHTMLi outerHTML;
  • łatwa manipulacja tekstem za pomocą innerTexti outerText;
  • model zdarzenia ( *tachEvent), który był planem dla zdarzeń poziomu 2 DOM ( *EventListener).

Każdy z nich znacząco przyczynił się (na dobre i na złe) do dzisiejszego stosu programistycznego. Opera posunęła się nawet do wdrożenia wszystkich trzech wersji 7 (2003).

Netscape miał jednak własny model zdarzeń DOM ( *EventListener). W 2000 r. Stała się specyfikacją zdarzeń poziomu 2 DOM. Safari 1 (2003) zaimplementował ten model; Opera 7 (2003) również zaimplementowała ten model. Gdy ruiny Netscape stały się Mozillą, Firefox 1 (2004) odziedziczył ten model.

W pierwszej części drugiej dekady (2000–2004) królował Microsoft. Internet Explorer 6 (2001) był wtedy najlepszą przeglądarką. Jeden z jego konkurentów, Opera 6 (2001), jeszcze nie wdrożył DOM Level 1 Core ( createElementi in.) Microsoft wdrożył go w Internet Explorerze 4 (1997), zanim specyfikacja stała się nawet rekomendacją (1998).

Jednak druga część drugiej dekady (2004–2010) okazałaby się katastrofalna dla Microsoft. W 2003 r. Apple wydało Safari 1.0; w 2004 roku Mozilla zakończyła przeglądarkę Firefox 1.0. Microsoft najwyraźniej spał na swoim tronie na szczycie góry przeglądarki. Internet Explorer 7 został wydany dopiero w 2006 roku: pięcioletnia przerwa od daty premiery Internet Explorera 6. W przeciwieństwie do wersji Internet Explorer od 4 do 6, wersja 7 wprowadziła niewiele innowacji; Zmiany DOM były niewielkie. Prawie dwa i pół roku później wypuszczono program Internet Explorer 8. Microsoft obudził się ze snu i zauważył, że inni producenci przeglądarek utworzyli wokół wielu standardów internetowych. Niestety minęło zbyt wiele czasu od ostatniej prawdziwej innowacji Microsoftu. Utworzono ruch wśród producentów przeglądarek. Nowe funkcje DOM miały zostać dodane w formie specyfikacji do W3C; Pomysły Microsoftu pozostały w przeszłości. Model zdarzeń Microsoft (*tachEvent) został odrzucony dla modelu DOM Level 2 Events. Internet Explorer nie wdrożył poprzedniego modelu do wersji 9 (2011), która stała się modelem zdarzeń poziomu 3 DOM.

Szaleństwa Microsoft (DOM) można podsumować za pomocą następujących punktów:

  • obecność jako podstawowa funkcja systemu Windows i wynikające z niej wymagania bezpieczeństwa na poziomie systemu operacyjnego;

  • poleganie na ActiveX dla kodu po stronie klienta;

  • innowacja, która ciekawie spadła po wersji 6 (2001).


(Autorzy strony

Po drugie, programiści ponoszą pewną winę. Ponieważ sieć nadal się rozwija, coraz więcej osób „bawi się” w tworzenie stron internetowych. Doprowadziło to do osłabienia talentu i etyki pracy. Problem leży jednak głównie w postawie. „Zrób to szybko” ma pierwszeństwo przed „Zrób to dobrze”. W rezultacie niezliczone strony internetowe są niezgodne z różnymi przeglądarkami. Jedną z głównych przyczyn tej niezgodności jest praktyka zwana „wąchaniem agenta użytkownika”. Chociaż praktyka ta jest nadal stosowana, udowodniono, że jest ona zarówno błędna, jak i szkodliwa. Opera posunęła się nawet do „zamrożenia” wersji agenta użytkownika w wersji „9.80” w wersji 10 (2009) i późniejszych. Miało to na celu zapobieganie łamaniu się błędnych skryptów. O wiele lepsza praktyka zwana „


Ignorancja

Po trzecie, moim preferowanym punktem winy jest ignorancja; nieznajomość faktu, że producenci przeglądarek nie współpracowali wystarczająco blisko, aby stworzyć ujednolicone specyfikacje; nieznajomość faktu, że Microsoft stronił od użytkowników innych przeglądarek; ignorancja w tym, że programiści są albo zbyt leniwi, albo zbyt krótkowzroczni, aby zawracać sobie głowę przeglądaniem przeglądarek (szczególnie tych, które nie są modne ). Istnieje wiele różnic w interfejsach API i implementacjach. Większości można uniknąć, stosując podejście uproszczone, ale jednocześnie defensywne (poleganie na DOM 0), wraz z dużą ilością badań i testów. Niewiedza doprowadziła do przekonania, że ​​Internet Explorer 6 jest plagą na Ziemi (przypomnijmy jej miejsce na wspomnianym wcześniej tronie przeglądarki).


Odbicie

Niestety DOM to po prostu źle zrozumiany interfejs API. Wielu chce rzucać kamieniami (za pośrednictwem FUD), ale niewielu chce uczyć się jego zawiłości. Jednym z rezultatów tej niewiedzy jest wprowadzenie „selektorów” DOM. DOM w sercu to API do manipulowania drzewem dokumentów. W przypadku złożonych problemów należy stosować przechodzenie do drzewa, biorąc pod uwagę formę przeanalizowanego dokumentu. Dzięki wprowadzeniu interfejsu DOM Selectors API programista może teraz korzystać z silnika przejścia CSS przeglądarki. Jest to dość wygodne, ale kryje w sobie prawdziwą formę drzewa dokumentów. W przypadku „selektorów” pobieranie węzłów elementu jest elementarne. Jednak w DOM określono jedenaście innych typów węzłów. Co z węzłami tekstowymi? Węzły komentowania? Węzły dokumentów? Są to również węzły, które są często pożądane podczas interakcji z DOM.


Wniosek

Krótko mówiąc, nie spiesz się i przeczytaj różne specyfikacje DOM. Przetestuj kod w jak największej liczbie przeglądarek. Jeśli uważasz, że Internet Explorer działa dziwnie, skontaktuj się z MSDN. Najczęściej zachowanie jest udokumentowane.

(Anegdoty historyczne mogą i mogą być niedokładne; wszelkie nieścisłości są mile widziane.)

—Mat

zero
źródło
Opera posunęła się nawet do „zamrożenia” - nie podoba mi się takie podejście, ponieważ jest dość krótkowzroczne (niektórzy programiści nie mogą kodować, więc pomińmy API, aby im pomóc). Zazwyczaj musisz uzyskać typ i wersję przeglądarki, gdy w tej przeglądarce występuje określony błąd, który klient nalega na naprawę. Naprawa konkretnej przeglądarki jest znacznie łatwiejsza niż implementacja „wykrywania błędów” (tj. Odwrotność „wykrywania funkcji”).
Pavel Horal
3

DOM to straszne API

To jest ŹLE . DOM NIE jest strasznym API.

  • Po pierwsze, pamiętaj, że DOM jest niezależny od języka. Wszystkie główne języki wdrożyły interfejs API. Wynika to z faktu, że po prostu nie używasz go w przeglądarce, ale wszędzie tam, gdzie musisz poradzić sobie z XML.

  • Po drugie, zauważ, że DOM nie definiuje klas, ale interfejsy. Ma to bardzo ważne implikacje: języki mogą je implementować w sposób, który odpowiada ich konstrukcjom i filozofii. Dzięki temu wszystkie języki nie muszą być spójne w implementacji z innymi.

  • Po trzecie, DOM jest jednym z dwóch głównych sposobów analizowania XML (innym jest SAX), aw zależności od kontekstu DOM może być bardzo wydajny.

To, o czym mówisz, to DOM przeglądarki. Zgadzam się, że DOM „źle się czuje” w przeglądarce. Jednym z powodów są niezgodności przeglądarki. Ale nie zgadzam się, że są one jedynym powodem złej reputacji DOM w przeglądarce.

  • Po pierwsze, jeśli się nad tym zastanowić, DOM jest jednym z tych obszarów, w których te niezgodności są stosunkowo łatwiejsze do pokonania. Dla porównania, zdarzenia, na przykład, są znacznie trudniejsze i irytujące w celu normalizacji.

  • Po drugie, wykrywanie funkcji dla funkcji DOM jest prostsze niż w innych obszarach.

  • Po trzecie, DOM 3 jest znacznie lepszy - a dziś wszystkie przeglądarki obsługują większość z nich.

Oczywiście, niezgodności są denerwujące, ale kiedy do nich dojdziesz, DOM jest o wiele mniej irytujący.

Nie zgadzam się również z powodami, takimi jak pułapki własnościowe, wojna korporacyjna itp.

  • Myślę, że to rozdźwięk między filozofią JavaScript jako lekkiego języka a implementacją DOM inspirowaną Javą - to przyczyniło się do dużej frustracji.

  • Po drugie, DOM został zaprojektowany dla XML i został dostosowany do HTML. Dlatego w przeglądarce mamy dokładnie dwie DOM - HTML DOM i XML DOM - i są one niezgodne.

  • Po trzecie, przeglądanie DOM w przeglądarce nie jest dobre. Nie mamy XPath dla HTML DOM, więc przed silnikami selekcyjnymi CSS wykonywanie przejść było naprawdę uciążliwe.

Wreszcie, myślę, że dzisiaj przy nowoczesnych przeglądarkach (i przy starszych przeglądarkach powoli zanikających) nie ma powodu, by DOM musiał być nazywany złym. Z pewnością poprawi się w przeglądarce - zarówno interfejs API, jak i implementacja.

treecoder
źródło
wydarzenia są równie trywialne do znormalizowania: \
Raynos
pomyśl o tym - gdybyś musiał obsługiwać currentTargetwłaściwość dla obiektu zdarzenia - czy byłoby to trywialne?
treekoder
implementacja propagacji zdarzeń jest jak 100 linii kodu: \
Raynos
currentTargetto nie tylko propagowanie zdarzeń - i czy naprawdę byłoby mądrze wdrożyć własne propagowanie zdarzeń?
treekoder
1
A dataManagersiedząc na zewnątrz, mówisz, że kod jest Trywialny? :)
treekoder