Czy osadzanie JavaScript w treści HTML jest złą praktyką?

84

Zespół, nad którym pracuję, nabrał zwyczaju używania <script>tagów w przypadkowych miejscach treści naszych stron HTML. Na przykład:

<html>
    <head></head>
    <body>
        <div id="some-div">
            <script type="text/javascript">//some javascript here</script>
        </div>
    </body>
</html>

Nie widziałem tego wcześniej. Wydaje się, że działa w kilku przeglądarkach, które testowałem. Ale z tego co wiem, umieszczanie tagów skryptów w takich miejscach jest niewłaściwe.

Czy się mylę? Jak źle jest, że umieszczamy tagi skryptu w znacznikach DIV? Czy są jakieś problemy ze zgodnością przeglądarek, o których powinienem wiedzieć?

Andrzej
źródło
1
Czy robi to document.writestam, czy też nie ma konkretnego powodu, aby to było tam, gdzie jest?
Martin Smith
8
Skrypt może występować w dowolnym miejscu ciała. Nie ma w tym nic złego. Ma to swoje implikacje (synchronizacja, łatwość utrzymania, mieszanie kodu i układu, osobiste preferencje), ale poza tym jest w porządku.
Tomalak
@earlz - zobacz moją odpowiedź, dlaczego jest źle. próbuję tylko ocalić życie tutaj. i mam rację.
Jason

Odpowiedzi:

88

To jest całkowicie poprawne.

Nie chciałbyś umieszczać tam wielkich, dużych bloków kodu pomieszanych w znacznikach (lepiej użyć zewnętrznych skryptów), ale może to być przydatne do:

  • dodać dodatkowe informacje wiążące w celu stopniowego ulepszania (gdy dane te są trudne do dopasowania do nazwy klasy lub innego podejścia do ukrywania rozszerzonych informacji w atrybutach); lub

  • gdzie konieczne jest jak najszybsze uruchomienie rozszerzenia opartego na skryptach (zamiast czekać na załadowanie okna / gotowość dokumentu). Przykładem może być autofokus, który może irytować, jeśli zostanie wystrzelony zbyt późno.

Możesz myśleć o <style>elementach, które są niedozwolone <body>(chociaż większość przeglądarek mimo wszystko na to pozwala).

bobince
źródło
12
+1 dla autofokusa; czasami mam wolne połączenie i nie jest fajnie być już gdzieś indziej (w najgorszym przypadku: wpisując hasło), gdy wracam do pierwszego pola.
Marcel Korpel
1
Jednak osadzanie JS może być przydatne, gdy jest tylko jedna strona i zmniejsza liczbę wyszukiwań na serwerze. Ta sama historia z osadzonym CSS. Ale zwykle lepiej jest oddzielić kod javascript i css w oddzielnych plikach, aby skrócić czas ładowania strony (przy użyciu prawidłowego nagłówka pamięci podręcznej), gdy używasz szablonu z tymi samymi wymaganiami javascript i css.
Codebeat
17

Właściwie to dość powszechne. Na przykład kod śledzenia Google Analytics używa tylko tej składni:

<script type="text/javascript">
  var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
  document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>

Jeśli to wystarczy dla Google ...

Keltex
źródło
37
-1 - tylko dlatego, że Google to robi, nie oznacza, że ​​jest to dobra praktyka. Często! = Dobrze.
Jason
3
Google Analytics i tak jest zbyt zawiłe, a ich użycie JavaScript do śledzenia jest w rzeczywistości dobrym przykładem przepracowania.
Esko
Ponadto zalecają umieszczenie skryptu na dole strony, a nie na środku, czyli tam, gdzie skrypty powinny być umieszczane, jeśli trzeba je umieścić. NIE w nagłówku, gdzie ludzie zwykle je umieszczają
Jason
2
Poza tematem na bok: zawsze irytuje mnie niepotrzebne i dziwaczne użycie Google unescape, biorąc pod uwagę, że escape/ unescapeIs Evil (i to \x3Cbyłby znacznie prostszy sposób na zrobienie tego).
bobince
3
@Keltex: Kod nie jest nieprawidłowy, jednak twierdzenie, że jest to dobra praktyka tylko dlatego, że niektórzy go używają, nie jest poprawnym argumentem.
Matti Virkkunen
4

Jest prawidłowy i, w zależności od frameworka po stronie serwera i natury kodu, czasami bardzo trudny do uniknięcia.

Spiczasty
źródło
4

Jak wspomniało kilka osób, jest ważny, działa i jest szeroko stosowany.

Najlepsze praktyki w zakresie zalecanym przez semantykę (lub przynajmniej używane do zalecania) to umieszczanie tagów skryptu wewnątrz nagłówka.

Bardziej nowoczesne najlepsze praktyki, które uwzględniają wydajność, zalecają umieszczanie tagów skryptów (zewnętrznych i wbudowanych) w prawym dolnym rogu przed tagiem body, aby umożliwić całkowite renderowanie znaczników przed wykonaniem kodu JavaScript.

Aby kod był łatwiejszy do zrozumienia i utrzymania, zalecany jest „dyskretny JavaScript”, w którym kod znajduje się w pliku zewnętrznym i wiąże zdarzenia z DOM (dyskretny JavaScript Google).

Jednym z przypadków, w których warto mieć wbudowany JavaScript, jest zainicjowanie zmiennych z wartościami, które istnieją tylko po stronie serwera, które zostaną później wykorzystane przez zewnętrzny kod JavaScript.

Gal
źródło
3

Wolę umieszczać odniesienia do zewnętrznych skryptów w głowie oraz skryptów, które uruchamiają i inicjalizują widżety i inne elementy w treści.

Problem, na który bardzo łatwo się natknąć, polega na tym, że element skryptu w treści nie ma dostępu do elementów, które występują po nim. Powiązany nieprzyjemny problem ze zgodnością przeglądarki polega również na tym, że IE nie zezwala elementom skryptów na modyfikowanie elementu, w którym się znajdują. Więc jeśli masz to:

<div id="foo">
  <script type="text/javascript">
    document.getElementById("foo")... // do something to it
  </script>
</div>

IE nie polubi Twojej strony. Stare wersje IE dawały bardzo tajemnicze komunikaty o błędach, a nawet pustą całą stronę, ale IE8 wydaje się wyświetlać opisowy komunikat o błędzie.

Dopóki upewnisz się, że twoje skrypty mają dostęp tylko do DOM, do którego dostęp jest bezpieczny, nie sądzę, że jest złe umieszczanie elementów skryptu w treści. W rzeczywistości, IMHO, umieszczanie skryptów inicjujących widżety po powiązanych elementach może być bardziej czytelne niż umieszczanie wszystkiego w jednym miejscu (i uważam, że może to również spowodować, że będą działać wcześniej, co sprawi, że rzeczy będą mniej przeskakiwać podczas ładowania strony).

Matti Virkkunen
źródło
3

To jest ważne!

Możesz użyć:

<script type="text/javascript">
    //<![CDATA[

    // Some JavaScript code that perfectly validates in the W3C validator

    //]]>
</script>

Nie sądzę, aby można było powiedzieć, czy jest to ogólnie zła praktyka. Musisz powiedzieć w tej sprawie. Ale na pewno dobrze jest mieć cały kod JavaScript w tym samym miejscu. To trochę bałaganiarskie, jeśli masz małe fragmenty kodu JavaScript w całym pliku HTML.

meo
źródło
2
jest to ogólnie zła praktyka.
Jason
ok, po prostu przeczytaj post, dobrze wiedzieć. I tak nigdy tego nie robię, ale nigdy nie myślałem, że może to spowodować zawieszenie przeglądarki ... ... jak to się dzieje?
meo
1
Każdy JavaScript może zawiesić twoją przeglądarkę (czasami w Firefoksie nadal pojawiają się okna z ostrzeżeniami z opcją „Przerwij skrypt” i „Kontynuuj skrypt”).
Marcel Korpel
to prawda, każdy JS może zawiesić twoją przeglądarkę. jeśli jednak zamierzasz ją zawiesić (nigdy nie jest to zalecane), lepiej to zrobić, gdy strona zostanie w pełni wyrenderowana z zawartością, a użytkownik może rozpocząć czytanie / interakcję ze stroną. powodem, dla którego JS zawiesza twoją przeglądarkę jest to, że działa synchronicznie, co oznacza, że ​​przeglądarka musi poczekać, aż JS zostanie całkowicie wykonany, zanim będzie kontynuował renderowanie, ponieważ nie wie, co zrobi JS. Podczas oczekiwania nie renderuje się, przez co wygląda, jakby się zawieszał.
Jason
Nie używaj tego CDATA - to nonsens. Tylko parsery sprawdzające poprawność XML rozumieją sekcje CDATA, więc jeśli Twoje strony są wyświetlane jako HTML, nie ma to żadnego znaczenia funkcjonalnego. Jeśli jednak Twoje strony są wyświetlane w formacie XML, wyrenderuje znak „//” przed tagiem otwierającym.
brothercake
2

Nie widziałem tego wcześniej. Wydaje się, że działa w kilku przeglądarkach, które testowałem. Ale z tego co wiem, umieszczanie tagów skryptów w takich miejscach jest niewłaściwe.

Jest to poprawne, ale nie jest dobrą (ani zalecaną) praktyką.

Czy się mylę? Jak źle jest, że umieszczamy tagi skryptu w znacznikach DIV? Czy są jakieś problemy ze zgodnością przeglądarek, o których powinienem wiedzieć?

Nie ma problemu z umieszczeniem <script>pod innymi elementami (ale powinno być wewnątrz <head>lub <body>). Nie ma również problemu z kompatybilnością przeglądarki, jednak osadzanie skryptów JS na stronach internetowych ma poważne wady (jak / dlaczego są uważane za złe) :

  1. Dodaje grubość strony
  2. Trudność (lub prawdopodobnie niemożliwa) do minifikacji
  3. Nie można przenieść ani używać na innych stronach
  4. Nie można przechowywać w pamięci podręcznej (należy pobierać za każdym razem, gdy strona jest ładowana)
  5. Brak separacji obaw (trudniejszy do utrzymania)

źródło
2

Jednak jest to również dobre, ponieważ wiesz, że kod JavaScript potrzebny do sekcji HTML będzie tam dla niej. Zamiast potwierdzać i tworzyć jakieś dołączenia na początku pliku.

Więc zamiast „jeśli zamierzasz używać tego HTML, upewnij się, że importujesz xyz.js”, możesz po prostu dołączyć HTML i skończyć z nim.

Więc niekoniecznie jest to straszne zło. Może nie spektakularnie niesamowity, ale też nie straszny. To zależy od intencji.

Will Hartung
źródło
2

Zobacz interfejs użytkownika Yahoo, aby zapoznać się z najlepszymi praktykami: http://developer.yahoo.com/performance/rules.html (JavaScript na dole strony)

Jonathan Lebrun
źródło
duże +1! Tak wiele odpowiedzi, ale żadna z nich nie wspomina, że ​​skrypty w HEAD mogą blokować inne elementy (takie jak obrazy! Co może zepsuć układ przy wolnym połączeniu)
David J
1

To z pewnością legalne; Widziałem to na kilku stronach , na przykład w Exforsys .

Teraz jest to strona z samouczkami pokazująca podstawy HTML i JavaScript, więc w tym kontekście jest to całkowicie zrozumiałe. Jednak nie chciałbym widzieć tego w kodzie produkcyjnym dla czegoś więcej niż zwykłego lub dwóch instrukcji. Nie widząc, czym zastąpiłeś // Some JavaScript code here, nie chciałbym komentować.

Nie powinno być jednak żadnych problemów z przeglądarką.

ChrisF
źródło
1

Można dodać <script> body, ale Internet Explorer naprawdę tego nie lubi. Więc aby być bezpieczniejszym, upewnij się, że masz swoje skrypty wewnątrz tagu <head>.

To naprawdę spowodowało spustoszenie (szczególnie w Internet Explorerze) w projekcie, nad którym pracujemy.

niełuskany
źródło
1

Zakładam, że Twój zespół robi to albo dlatego, że chce dynamicznie wstawić skrypt, albo że pisze skrypt, który będzie uruchamiany po załadowaniu strony.

Nie powiedziałbym, że jest coś złego w robieniu tego, gdy jest to ABSOLUTNIE KONIECZNE (o ile jest w bloku CDATA), ale poza tym zalecałbym Twojemu zespołowi korzystanie z biblioteki skryptów, takiej jak Prototype lub jQuery, i zachowywanie skrypty zewnętrzne w stosunku do strony. Zwykle jest to czystsze, a biblioteki czasami wymuszają odrobinę czystości w kodzie, co, jak założyłem, obecnie się nie dzieje.

Nie uruchamiałbym również żadnych czasochłonnych funkcji w tagach skryptu wbudowanego, ponieważ zdarzają się one podczas ładowania strony, a jak stwierdził Jason powyżej, mogą spowolnić ładowanie strony. Wszystkie biblioteki skryptów mają zgrabne funkcje, które pozwalają wykonywać czynności przy ładowaniu strony i dają możliwość uruchomienia ich w momencie załadowania strony, na przykład po załadowaniu DOM.

Jesse
źródło
1

To jedna z wielu, wielu najlepszych praktyk, która dotyczy zarówno poprawy wydajności, jak i poprawy podejścia do programowania.

Ostatecznie w tworzeniu stron internetowych najważniejsze jest uzyskanie produktu!

heydenberk
źródło
0

Często powtarzanym zaleceniem, aby skrypty były przechowywane w nagłówku, jest zapewnienie, że skrypt zostanie załadowany przed jego wywołaniem. Jest to problem tylko w przypadku niektórych programów obsługi zdarzeń. W przypadku innych typów skryptów nie ma to znaczenia, a dla niektórych (np. Document.write) nie ma sensu.

Tor Haugen
źródło
0

Jeśli masz edytor, który obsługuje jednocześnie składnię HTML i JavaScript. A jeśli chcesz najpierw przeczytać kilka wierszy kodu HTML, a następnie cpde JavaScript ... jasne. Idź po to.

Wesoły
źródło
Brzmi jak Visual Studio i widoki maszynki do golenia, które mogą obsługiwać oba. W niektórych przypadkach może to być całkiem wygodne (cały kod, który musisz edytować w jednym miejscu). Oczywiście zbyt dużo javascript w widoku może utrudniać czytanie i rozumienie kodu, a ponadto pojawia się problem z rozdęciem wyjściowego kodu HTML.
jahu
0

Kilka rzeczy:

  1. Jest całkowicie poprawny pod względem kodu.
  2. Jest to całkowicie niezalecane.

Takie postępowanie znacznie spowalnia ładowanie strony, ponieważ kod JavaScript musi zostać wykonany, zanim reszta strony będzie mogła zostać wyrenderowana. Jeśli wykonujesz dużo pracy w tym kodzie JavaScript, Twoja przeglądarka może się zawiesić. Należy starać się (jeśli to możliwe) ładować kod JavaScript dynamicznie i na końcu strony (najlepiej przed </body>tagiem).

Kup i przeczytaj wysokowydajny JavaScript . Zmieni to sposób, w jaki piszesz kod JavaScript.

Jason
źródło
3
Nie moje głosy przeciw, ale kiedy myślę, że Yahoo, myślę YAHOO.util.Event.addListener, że nie jest wydajny / zwięzły javascript. Nie czytałbym książki i nie traktowałbym jej jak ewangelii, czasami trzeba mieć javascript w samej stronie, np. Zmienna renderowana dynamicznie, czego nie da się zrobić na zewnątrz .js.
Nick Craver
2
czy przeczytałeś książkę? gdyby tak było, wiedziałbyś, że uczy technik optymalizacji. rzeczy takie jak YAHOO.xx.xx.xxsą buforowane lokalnie. czasami tak, renderowanie zmiennej na stronie jest w porządku, ale zwykle można to zrobić zewnętrznie, jeśli po prostu ustawisz ukrytą wartość wejściową z serwera. ale powiedziałem, że to nie jest zalecane, nie jest złe . także Nicholas Zakas, autor, zna się na rzeczy, niezależnie od tego, kto jest jego pracodawcą.
Jason
2
„Ładowanie dynamiczne” i „ładowanie na końcu strony” to dwie różne rzeczy i jest wysoce nieprawdopodobne, że korzystanie z nich obu zwiększy wydajność. "Czy przeczytałeś książkę?" i „mam rację” również nie są najlepszym sposobem na rozpoczęcie konstruktywnej rozmowy. Również na pierwotne pytanie można odpowiedzieć „ponieważ w końcu dławi się IE”, ponieważ niektóre operacje są obsługiwane tylko wtedy, gdy skrypt jest bezpośrednim dzieckiem ciała.
Nacho Coloma,