Dwóch rzeczy nienawidzę tak bardzo, że mnie aż skręca, gdy na nie natrafię: złych książek oraz szerzenia przestarzałych lub po prostu nieprawdziwych informacji o technologiach webowych. A już do prawdziwego szału doprowadzają mnie złe książki szerzące przestarzałe lub po prostu nieprawdziwe informacje o technologiach webowych. Oczywiście gromy mego gniewu (jak to drzewiej bywało) spadną na wydawnictwo Helion, jako de facto jedyne fachowe webmasterskie wydawnictwo w Polsce, a dokładniej na ich najnowszą propozycję (z tego roku – tak, mamy 1 stycznia) – Javascript i jQuery. 131 praktycznych skryptów, autorstwa Witolda Wrotka, której co prawda nie posiadam, lecz nieopatrznie spojrzałem do przykładowego rozdziału, przyciągnięty tytułem.
Zacznijmy od tego, że nie jestem fanem papierowych książek dotyczących programowania – zwłaszcza tego związanego z Siecią. Czemu? Bo książki są nieaktualne w dniu premiery. Raczej widziałbym całkowicie inny model wydawniczy: książki powstają jako Open Source (albo na licencji CC) i ich „kod” ląduje na GitHubie, gdzie każdy zaznajomiony z tematem może dowalić swoim pull requestem, naprawiając wyłapane błędy. A jeśli całość naskrobiemy np. w Markdown i wrzucimy do gałęzi gh-pages
, mamy autopublikującą się pozycję, która może zostać uaktualniona w ciągu kilku chwil. Pomijam już dostępność przykładów kodu, które po prostu byłyby razem z książką. Open Source publishing! A dla tradycjonalistów możliwość wydrukowania sobie ładnie sformatowanej książki. Można? Można, ale przecież hajs się musi zgadzać. Kilku osobom ten pomysł już pokazałem i każda z nich pokiwała z powątpiewaniem głową i stwierdziła, że na tym się nie da zarobić… Cóż, wydaje mi się, że jeśli ktoś ma dostateczną wiedzę, żeby taką książkę napisać, nie musi zarabiać na swojej grafomanii, bo trzepie dużą kasę na czym innym. No ale koniec tego marudzenia, pomarudźmy o przykładowym rozdziale!
Oczywiście opierajac tę recenzję na przykładowym rozdziale, wychodzę z założenia, że skoro ten rozdział ma mnie zachęcić do kupna, to pokazuje to, co najlepsze w książce. Zasadnym jest zatem wyrobienie sobie zdania o całości (zasada koła hermeneutycznego: całość opisuje części, a części całość!), niemniej ostrze mej krytyki jest głównie wymierzone w to, co czytałem.
- Na początek spis treści… Źle się dzieje, gdy błędy są już w nim. Tu niestety tak mamy (ba, błąd jest nawet na okładce! Ale o nim za chwilę). Pomijam już tutaj dość dziwną kolejność rozdziałów (najpierw uczymy się obliczać – gdzie też, nie wiem czemu, opisano typ logiczny zmiennych – a dopiero później zapoznajemy się z… liczbami w JS) czy szalenie niefortunny termin „witalizacji strony” (jakby ktoś miał wątpliwości – chodzi o ożywienie strony animacjami) – jest tutaj błąd, który dyskwalifikuje tę książkę jeszcze przed dotarciem do treści. Otóż widzimy tutaj… rozwinięcie „skrótu” jQuery. Problemem jest to, że jQuery to nie skrót. Ale ok, jeszcze bym to jakoś przecierpiał, gdyby to rozwinięcie nie było całkowicie bezsensowne. Bo kto normalny nazwałby helper DOM-owy, naskrobany w JS, JavaQuery? Owszem, coś takiego istnieje, ale jest zbiorem API dla Javy, a Java ma się do JS jak – parafrazując inny klasyk Heliona – szynka do hamburgera. Mylenie tych dwóch języków jest po prostu niewybaczalne i wręcz obraźliwe dla twórców tej biblioteki.
-
No właśnie – biblioteki. Powróćmy do okładki, gdzie znajdziemy taki passus:
jQuery, czyli genialny framework pełen skryptowych gotowców
Okładka prawdę mówiąca
Otóż jQuery nie jest frameworkiem – to biblioteka (a jeszcze dokładniej można go nazwać helperem/wrapperem DOM-owym), której głównym zadaniem jest zapewnianie międzyprzeglądarkowej zgodności. Tyle i aż tyle. Poza tym – pojęcie frameworka z założenia wyklucza gotowce. Sam jQuery nazywa siebie biblioteką:
jQuery is a fast, small, and feature-rich JavaScript library.
jQuery we własnej osobie (chociaż mówi o sobie w 3. osobie)
Czemu? Bo framework to jednak co innego i de facto każdy posiada IoC (Invertion of Control – Odwrócenie Sterowania) oraz służy za szkielet aplikacji. jQuery natomiast po prostu… pomaga nam operować na DOM. Nic więcej.
-
Ok, przejdźmy do przykładowego rozdziału, poświęconego zdarzeniom. Już 1. zdanie wprawiło mnie w zakłopotanie:
Zdarzenia dzielą się na zdarzenia HTML i HTML DOM.
Otóż nie. Coś takiego, jak
zdarzenia HTML
nie może istnieć z prostego powodu: HTML nie definiuje żadnych zdarzeń. Owszem, specyfikacja HTML5 definiuje atrybuty HTML, które jako swoją wartość biorą tekst mający się wykonać jako JS (który de facto zostaje przez przeglądarkę przepuszczony przez konstruktorFunction
, co jest zawoalowaną postaciąeval
), ale są to atrybuty, nie – zdarzenia. HTML jest wyłącznie tekstem, który trzeba sparsować, a tekstowi średnio są potrzebne jakiekolwiek zdarzenia. Wszystkie zdarzenia są częścią standardu DOM, czyli „przestrzennego” modelu, który powstaje po przetrawieniu przez przeglądarkę HTML-a. Wówczas, zamiast tekstu, dostajemy ładną hierarchię obiektów – a na obiektach można operować o wiele swobodniej niż na tekście. Nie zgodzę się także z nazywaniem DOM HTML DOM-em – równie dobrze może to być SVG DOM, XML DOM, RSS DOM, SGML DOM itd. Każdy z tych języków może być przekonwertowany do postaci drzewka, zatem w teorii każdy może być oskryptowany w ten sposób (oczywiście w praktyce skryptuje się jedynie HTML i SVG, w rzadkich wypadkach XML). Bardzo płynny i dziwny jest także sam podział, np do zdarzeń HTML zostało zaliczone:zmiana zawartości pola do wpisywania danych
Natomiast kilkanaście linijek niżej czytamy:
HTML DOM (ang. Document Object Model — model obiektów dokumentu) to standard określający sposoby zmiany zawartości, właściwości i parametrów poszczególnych elementów strony HTML.
Mam wrażenie, że zostało tutaj pomylone samo zjawisko zdarzeń z systemem obsługi zdarzeń. Co więcej, nie zgodzę się z tłumaczeniem terminu Document Object Model jako
modelu obiektów dokumentu
. Jest to raczej obiektowy model dokumentu, bo opisuje cały dokument i jego części jako hierarchiczną strukturę, nie natomiast – stronę jako poszczególne obiekty. - Dziwi mnie także używanie terminu program do opisywania skryptów JS (a raczej – całych stron internetowych, które są przez nie obsługiwane). Dziwi mnie też używanie tego samego terminu w stosunku do funkcji obsługujących zdarzenia (w tym wypadku, jeśli przystalibyśmy na termin program, bardziej poprawny byłby termin podprogram). Skrypty i funkcje brzmią mniej pretensjonalnie.
-
Później mamy do czynienia z 1. przykładem w tym rozdziale (a 50. w książce), odnośnie zdarzeń związanych z myszą. Mamy nawet ładną tabelkę, w której
zebrano zdarzenia HTML DOM związane z myszą
. Nie zebrano wszystkich zatem. Brakuje np. zdarzeń związanych z obsługą kółka myszy. Inna rzecz – nazwy zdarzeń nie zawierająon
. Polecam spojrzeć do specyfikacji zdarzeń DOM i poszukać zdarzeń myszki. Zapis zdarzeń zon
na początku to pozostałość po tzw. DOM0, które od dawien dawna było niestandardowym sposobem wiązania zdarzeń i dopiero ustandaryzowano go w specyfikacji HTML5. DOM0 wywodzi się z całkowicie bzdurnych i przestarzałych atrybutów[on…]
. Dlatego nie mogę się zgodzić, że ta tabelka zawiera spis zdarzeń dotyczących myszki – to jest spis zachowanych dla bożka BC starych błędów W3C. Obecnie istnieją o wiele lepsze sposoby przypinania zdarzeń i tego typu antyki powinny w końcu odejść do lamusa – a już na pewno nie powinny być promowane w książce z 2015 roku.Pomijam już fakt, że w opisie tych zdarzeń i tak są błędy:
onmouseout
Zdarzenie występuje, gdy użytkownik przesuwa wskaźnik myszy na element lub z jednego z jego dzieci.Nie prościej napisać, że użytkownik po prostu zsuwa wskaźnik z elementu lub jednego z jego dzieci?
-
Następnie następuje kod przykładowej strony i choć jest króciutki, łamie wiele z dobrych praktyk. Zacznijmy od początku:
<!DOCTYPE HTML PUBLIC " -//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
Transitional
, czyli tryb prawie zgodności ze standardami. Byłoby prawie dobrze, gdybyśmy nie mieli roku 2015.There’s absolutely no reason whatsoever for using an HTML4 doctype. Just put the
<!DOCTYPE HTML>
doctype on your HTML documents and make sure they’re served as text/html and be done with it. Move on with your life.Mike[tm] Smith, HTML5 – Check it Before you Wreck it with Mike[tm] Smith
I taka jest prawda!
Dalej brakuje znacznika otwierającego
html
, za to końcowy już jest – ciut konsekwencji.<meta http-equiv="CONTENT-LANGUAGE" CONTENT="PL">
meta[http-equiv]
są ekwiwalentem dla nagłówków HTTP, więc to tylko atrapa. Ta jest tym bardziej kaleczna, że… została uznana za całkowicie zbędną i zamiast niej należy używać określania języka przezhtml[lang]
.<meta http-equiv="content-type" CONTENT="text/html; CHARSET=iso-8859-2">
UTF-8 powinien być używany de facto wszędzie i nowy walidator W3C zwraca na to uwagę.
<meta http-equiv="Content-Script-Type" content="text/javascript">
A ta linijka nie robi nic i nic nie znaczy – można ją z powodzeniem usunąć. W teorii był taki wymóg, ale żadna przeglądarka nigdy tego mechanizmu nie zaimplementowała – i słusznie, bo jest bezsensowny.
<script> document.write("<h1>050</h1>"); </script>
document.write
powinno być unikane za wszelką cenę, ponieważ blokuje speculative rendering (spekulatywne renderowanie strony) – przeglądarka na każdej tego typu deklaracji musi się zatrzymać, sparsować ją i wykonać, gdyż ta komenda modyfikuje drzewko DOM w miejscu swego wstawienia; w innym wypadku przeglądarka może „zgadywać” DOM, co skutkuje o wiele szybszym wyświetlaniem strony, wyklucza użycie Ajaksu –document.write
, wywołany na już załadowanej stronie, nadpisuje ją całą, nie działa w trybie XML (to akurat najmniejszy problem) i nie oferuje żadnej wartości dodanej w stosunku nawet do równie prymitywnegoelement.innerHTML
. A już tworzenie treści strony przy pomocy tej metody to czyste szaleństwo. Treść jest treścią i nie powinna mieć nic wspólnego z JS (prawda, Angular.js?).<h1 onclick="this.innerHTML='Dziękuję!'">Kliknij tekst!</h1>
O tym wspominałem już wcześniej, ale tutaj jeszcze trochę dopowiem. Oprócz już wymienionych powodów, ten zapis miesza warstwy aplikacji i wymusza obniżenie bezpieczeństwa strony, gdyż zaprzecza zasadom Content Security Policy (Polityki Bezpieczeństwa Treści). I nie, zezwolenie na skrypty i style inline nie jest ok – jest głupotą, porównywalną do używania telefonu jako młotka (da się, ale… no właśnie).
- Kolejny przykład (o numerze 51) cierpi na dokładnie te same problemy, więc nie będę nad nim elaborował.
-
Natomiast przykład 52. jest bardzo ciekawy i jego główna część wygląda tak:
<div onmouseover="mysz_nad(this)" onmouseout="mysz_na_zewn(this)" style="background-color:#EEEEEE;width:200px;height:20px;padding:20px;"> Przesuń kursor nad prostokąt!</div>
Co tu mamy? Rollover w stylu starego, dobrego DHTML-a z 2002 roku (serio, dam se rękę uciąć, że podobne przykłady widziałem w… podręczniku do TI właśnie z 2002 roku). Uderza tutaj już sama bzdurność zastosowania atrybutów
[on…]
, co bardzo udziwnia sam proces obsługi zdarzenia.function mysz_nad(obj) { obj.innerHTML = "Widzisz, jakie czary!" }
Bardzo rzadko widuję konwencję z podkreślnikiem w JS – raczej się stosuje camelCase. Jeszcze rzadziej widuję nazwy funkcji w języku polskim – angielski jest tutaj niepisanym standardem. A o przekazywaniu do handlera zdarzenia obiektu, na którym zdarzenie zaszło, zapomniałem 10 lat temu. Jeśli ta funkcja byłaby przypięta normalnie, ten obiekt byłby po prostu kontekstem wywołania (byłby dostępny jako
this
), a my, zamiast bezsensownego przekazywania go jako 1. parametr, zamiast tego dostalibyśmy obiekt samego zdarzenia. I choćby dlatego nie miesza się JS z HTML – z tego nigdy nie wychodzi nic dobrego, tylko dziwactwa tego typu. Jak to można rozwiązać bardziej elegancko? Choćby tak:<div style="background-color:#EEEEEE;width:200px;height:20px;padding:20px;"> Przesuń kursor nad prostokąt!</div> <script>document.getElementsByTagName('div')[0].addEventListener('mouseover', function(e) { this.innerHTML = 'Widzisz, jakie czary!'; }, false);</script>
Do tego przerzucić style do CSS, tam, gdzie ich miejsce i dorobić obsługę drugiego zdarzenia i jesteśmy w domu. Elegancko, schludnie, zgodnie ze sztuką. Tutaj trzeba jeszcze zwrócić uwagę, że nie poleca się używania zdarzeń
mouseover
imouseout
, gdyż de facto zawsze lepsze rezultaty da zastosowaniemouseenter
imouseleave
–mouseover
odpala się bowiem nawet przy przejściu z dziecka na rodzica, co jest po prostu frustrujące (jedynym powodem, dla których te zdarzenia były używane była… opieszałość Chrome, który do niedawna wciąż nie wspierałmouseenter
imouseleave
). A w wypadku rollovera JS i tak jest artylerią na muchę, bo wszystko, czego potrzebujemy to:hover
i pseudoelementy (bo właściwość CSScontent
wciąż nie działa na normalnych elementach, chociaż zgodnie ze specyfikacją powinna…). -
Kolejny, 53., przykład cierpi na inne problemy – jeden związany jest z wykorzystaniem złego zdarzenia, a drugi ze złamaniem konwencji stylistycznej JS, która jest de facto standardem. Zacznijmy od tego drugiego problemu, bo jest o wiele prostszy do zobaczenia i wyjaśnienia.
function Funkcja() { var x=document.getElementById("znak"); x.value=x.value.toUpperCase(); }
Chodzi o nazwę tej funkcji – nie powinna być dużą. Zgodnie ze standardowymi konwencjami nazewniczymi, duża litera zarezerwowana jest dla konstruktorów. Kropka.
Pomijam tutaj jak duża jest niespójność stylistyczna pomiędzy poszczególnymi sposobami – kod JS między przykładem 52. a 53. różni się tyloma szczegółami, że wygląda jakby pisały go dwie różne osoby. To jest niedopuszczalne. Po to istnieją tzw. styleguides, żeby zachować całkowitą spójność w obrębie całego systemu. A przestrzeganie konwencji jest ważne zwłaszcza wówczas, gdy uczymy innych.
Drugim problemem związanym z tym przykładem jest zastosowanie złego zdarzenia. Owszem, wykrywanie wpisywania danych do pola wykonywało się dawniej przy pomocy zdarzeń takich jak
keypress
czykeyup
, ale te czasy bezpowrotnie minęły. Obecnie od obsługi zdarzeń związanych ze zmianą zawartości pola, oprócz standardowegochange
, mamy takżeinput
. Czemu nowe zdarzenie? Bo reaguje na zmianę zawartości pola, a nie na naciśnięcia klawiszy – jak widać, zakresy użycia tych zdarzeń są różne (można stwierdzić, że niejakoinput
zawiera się w zdarzeniachkey…
). Co więcej, zdarzenieinput
jest de facto obsługiwane wszędzie. Zatem lepszy sposób na obsługę tego problemu byłby taki:document.getElementById('znak').addEventListener('input', function(e) { this.value = this.value.toUpperCase(); }, false);
-
Kolejny przykład (54.) związany jest z
obiektami (ramkami)
. Nie jest to właściwa nazwa, gdyż obiektami są wszystkie elementy DOM na stronie, w tym ramki. Co więcej, ten przykład operuje na dokumencie, nie na ramce. Poprawne nazewnictwo czasami jest bardzo istotne! Oczywiście mamy także tabelkę z opisem potrzebnych nam zdarzeń, niemniej są w niej rażące błędy.onerror
Obraz nie został załadowany prawidłowo (dla<object>
,<body>
iframeset
).A
img
? A dźwięki? A filmy? Aiframe
? Zdarzenia tutaj opisane dotyczą wszystkich zasobów. Przy okazji – od dawien dawna nie widziałemobject
na żywo (hint: standaryzacjaembed
to dobra rzecz). Pomijam fakt, żebody
to raczej nie obraz.onunload
Strona nie została załadowana (ma zastosowanie zarówno dla<body>
, jak i<frameset>
).I znów – co z
iframe
choćby?frameset
wszak nie używa się od lat. No i to zdarzenie oznacza moment, w którym strona jest „odładowywana”, czyli de facto wtedy, gdy użytkownik wyłącza kartę przeglądarki. Jeśli strona nie została załadowana, to, w zależności od powodu, odpala się zdarzenieerror
lubabort
.Wygląda na to, że te wszystkie tabelki to niedokładne tłumaczenie ze specyfikacji HTML4.
Co do samego przykładu – zamiast czekać z odpaleniem JS-a na zdarzenie
load
(które oczywiście powinno zostać poprawnie przypięte i to nie dobody
, ale do obiektuwindow
), wystarczy przenieść skrypt na koniecbody
. Dzięki tej technice de facto od lat nie korzystam ze zdarzeniaload
dla stron (wyjątkiem jest konieczność odpalenia skryptu dla stron z wczytanymi wszystkimi obrazkami – wówczas trzeba na to zdarzenie poczekać). No i tutaj wypadałoby od razu wspomnieć o zdarzeniuDOMContentLoaded
, które jest podstawą dla jQuery’owego$(document).ready
. -
Kolejny przykład dotyczy formularzy, więc standardowo dostajemy tabelkę ze zdarzeniami… w której znów jest błąd.
onfocus
Zdarzenie występuje, gdy element uzyskuje fokus (ma zastosowanie dla<label>
,<input>
,<select>
,<textarea>
oraz<button>
).Zacznijmy od tego, że zdarzenia
focus
iblur
są przeznaczone dla wszystkich elementów focusowalnych, więc np. również dla linków i dla wszystkich tych elementów, które mają atrybut[tabindex]
– więc nie są to zdarzenia formularzowe. Co więcej – nie sądzę, żebylabel
odpalał to zdarzenie, gdyż nie jest elementem focusowalnym.Co do podanego przykładu –
blur
nie jest odpowiednim zdarzeniem do odpalania funkcji na zawartości pola. Do tego służą zdarzeniachange
iinput
. -
A dalej to już w ogóle mega sajgon.
Zdarzenia HTML DOM związane z właściwościami
To wyrażenie nie ma najmniejszego sensu! Tym bardziej, że to, co jest hucznie nazywane
zdarzeniami HTML DOM
, jest tak naprawdę… właściwościami wcześniej już wspominanego przeze mnie obiektuevent
. Powtórzę raz jeszcze: nazywanie rzeczy poprawnymi nazwami jest ważne – zwłaszcza, jeśli kogoś uczymy!Oczywiście dostajemy tabelkę tych własności, w której wcale nie jest lepiej:
eventPhase
Zwraca informację, która faza przepływu zdarzeń jest obecnie oceniana.Eh, nienawidzę tworzenia na siłę polskich odpowiedników uznanych ogólnie nazw!!! Jeśli już tworzymy takie dziwactwa, podawajmy też odpowiedniki angielskie. Poza tym – to zdanie nie ma sensu. Jak można oceniać sposób propagacji zdarzenia? Ta własność zwraca typ propagacji zdarzenia (event propagation phase) – niczego nie ocenia!
Bąbelkowanie to odpowiadanie na zdarzenia w trakcie ich propagacji od obiektu docelowego do obiektów zewnętrznych.
To chyba najgorsze wytłumaczenie dla bąbelkowania, jakie słyszałem. Nie ma obiektów zewnętrznych – to nie są bańki włożone jedna w drugą. Mówimy o drzewie DOM, zatem to propagacja w górę drzewa. Ale zamiast niepotrzebnie się produkować, odeślę do kogoś, kto umie bardzo dobrze tłumaczyć.
<p onclick="stoper(event)">
Jak już pokazałem wyżej, przy normalnie dodanym event handlerze zdarzenie zostałoby dodane z automatu. Składnia dodania tego zdarzenia w JS mogłaby wyglądać następująco:
document.getElementsByTagName('p')[0].addEventListener('click', stoper, false);
Tak, wystarczy podać sam uchwyt do funkcji (nazwę, nieotoczoną apostrofami/cudzysłowami).
Co więcej, podawanie obiektu zdarzenia (zresztą
this
też to dotyczy) w atrybucie[on…]
wygląda dziwnie. Dostajemy bowiem znikąd dwie rzeczy – ki czort?! Jeśli natomiast przeniesiemy całość do JS, kod staje się o wiele przyjemniejszy. No i operujemy na prawdziwym kodzie, a nie evalowanym stringu (kolejny z mega problemów Angulara!). -
Dla przykładu 57. z kolei zrobiono dziwną rzecz – połączono właściwości zdarzeń
MouseEvent
iKeyboardEvent
. Nie rozumiem tego – to są zupełnie dwa różne interfejsy. No bo chyba wszyscy zdają sobie sprawę, że mysz ma wskaźnik i służy do wskazywania, a klawiatura ma klawisze i służy do pisania. Ba, brakuje dla klawiatury tak podstawowej rzeczy jak własnościkey
(lubkeyCode
), która przechowuje kod aktualnie wciśniętego klawisza – są za to własnościkeyIdentifier
ikeyLocation
, które na żywo w kodzie widziałem aż raz i było to demo dla specyfikacji DOM.W samym przykładzie natomiast zdarzenie
mousedown
nazywa się kliknięciem – co nie jest do końca prawdą (i było nawet wyjaśnione w 1. tabelce w tym rozdziale!). Pomijam fakt, że dema dla klawiatury nie ma w ogóle… -
Przykład 58. nie ma nic wspólnego ze zdarzeniami i w ogóle nie powinien się znajdować w tym rozdziale.
Obiekt
Anchor
reprezentuje element<a>
języka HTML.Zacznijmy od tego, że obiekt
Anchor
nie istnieje. Po drugie – to nie byłby obiekt, lecz konstruktor DOM-owy, czyli coś zupełnie innego. Tak naprawdę rozchodzi się tutaj o interfejsHTMLAnchorElement
(to „klasa”, po której dziedziczą wszystkie linki na stronie). To nie ma nic do czynienia ze zdarzeniami – to po prostu warstwa abstrakcji, pozwalająca dokładnie opisywać konkretny typ elementów na stronie. Być może interfejs ten jest prezentowany z powodu tego, że zawiera dodatkowe metody, dedykowane dla linków? Jeśli tak – to czemu nie prezentuje się jeszcze bardziej wypasionegoHTMLAudioElement
czyHTMLImageElement
?Tabelka dla „obiektu
Anchor
” również zawiera błędy.Nie jest obsługiwana w HTML5
Nie jest dozwolona przez specyfikację HTML5 – a to spora różnica. Przeglądarki te własności linków dalej rozumieją i radzą sobie bez problemu, z powodu bożka BC.
download
Ustawia lub zwraca wartość atrybutudownload
linku.Pomijam już fakt, że to tłumaczenie nic nie tłumaczy (ta tabelka wygląda jak przepisanie co ciekawszych atrybutów ze specyfikacji HTML5). Jest też po prostu błędne. Jest spora różnica między atrybutami elementu, a własnościami obiektu DOM. Owszem, atrybuty są przepisywane na własności, ale własności na atrybuty – niekoniecznie. Od operacji na atrybutach są metody
element.getAttribute
ielement.setAttribute
, natomiast odwołania typuelement.nazwa
działają bezpośrednio na własnościach obiektów DOM. I tą różnicę warto znać i rozumieć.name
Nie jest obsługiwana w HTML5. Zamiast niej należy używaćid
. Ustawia lub zwraca wartość atrybutuid
linku.Oczywiście wszystko, co napisałem powyżej, tyczy się także tego punktu. Niemniej jest tu jeszcze jeden błąd –
name
ustawia własnośćname
obiektu DOM. Automagicznie nagle w HTML5 nie zaczęło wpływać naelement.id
– bożek BC czuwa.W ogóle jestem zawiedziony tym przykładem – myślę, że fajniejsze byłoby pokazanie dynamicznego parsowania linków z formularza przy pomocy programo utworzonego linku, np. coś takiego.
Powiem tak: jestem przerażony. W przypadku tego przykładowego rozdziału praktycznie każde zdanie zawiera jakiś błąd merytoryczny. To nie napawa optymizmem w stosunku do reszty książki. I, niestety, powiększa moją awersję do polskich wydawnictw informatycznych. W chwili obecnej nie mamy dobrej literatury tego typu…