Ścisłe sprzężenie między JavaScript, HTML i CSS: bardziej nowoczesne podejście?

29

Bardzo często JavaScript jest powiązany z niektórymi selektorami, aby znaleźć elementy, przechowywać dane i nasłuchiwać zdarzeń. Często zdarza się, że te same selektory są używane do stylizacji.

jQuery (i jego silnik selektora Sizzle) obsługują i promują to, odwołując się do elementów o składni typu CSS. Jako taka, technika ta jest szczególnie trudna do „oduczenia” (lub refaktoryzacji) podczas tworzenia projektów.

Zrozumiałem, że jest to wynik historii rozwoju HTML i Javascript oraz że przeglądarki zostały zbudowane tak, aby efektywnie wykorzystywać / analizować / i renderować tego rodzaju sprzężenie. Ale w miarę jak strony internetowe stają się coraz bardziej złożone, ta rzeczywistość może powodować trudności w organizowaniu i utrzymywaniu tych oddzielnych warstw.

Moje pytanie brzmi: czy można tego unikać w nowoczesnych witrynach internetowych?

Jeśli jestem nowy w tworzeniu front-endu i chcę uczyć się rzeczy „we właściwy sposób”, czy warto nauczyć się rozdzielać i unikać takich zależności od samego początku? Czy to oznacza unikanie jQuery na rzecz biblioteki, która promuje bardziej oddzieloną strukturę?

Stuart Kershaw
źródło
1
Jak by to działało? Jak na przykład wyłączasz kontrolkę na stronie bez faktycznego dotykania tej kontrolki lub posiadania wiedzy na jej temat? (to mój mały sposób na powiedzenie, że musisz sprecyzować, co masz na myśli przez oddzielenie, najlepiej z kilkoma przykładami, nawet jeśli są wymyślone).
Robert Harvey
2
Najważniejszą rzeczą, gdy mówimy o oddzieleniu html, css i js, jest użycie selektorów klas zamiast jakichkolwiek innych, jest to podstawowa koncepcja metodologii takich jak oocss i BEM.
angvillar
Naucz się React lub komponentów internetowych, a nie będziesz już musiał przejmować się selektorami w JS.
Andy

Odpowiedzi:

35

Nie da się tego uniknąć. Są sprzężone, ponieważ współdziałają ze sobą. Jeśli skrypt javascript zamierza wykonywać jakiekolwiek manipulacje DOM, musi mieć sposób na odniesienie się do DOM.

Istnieją różne konwencje.

Interfejs API DOM poziomu 2 udostępnia metody getElementById, getElementByTagName i getElementsByName. Do dziś są to konie każdego rodzaju przemierzania DOM. Wszystkie inne bardziej wyszukane selektory jQuery ostatecznie przekształcają się w ich kombinacje i / lub przechodzą prosto przez każdy węzeł DOM (był to sposób na wykonanie getByClassName).

Nie ma innego skrótu. Javascript musi wiedzieć, co robić i gdzie. Zazwyczaj, jeśli element ma identyfikator lub klasę, która jest istotna tylko w skryptach, wiele osób poprzedzi go js-flagą lub inną oczywistą flagą.

Kolejną nowszą konwencją jest wybór atrybutów danych.

<ul data-myapp-sortable="true">

jQuery('[data-myapp-sortable]').makeSortable();

Atrybut danych jest zwykle używany do celów skryptowych, a wybór użycia ma sens. Wadą jest to, że jest to wolniejsze niż użycie getElementById ().

Innym podejściem jest to, które stosuje angularJS, który tworzy model widoku. W tej konwencji wszelkie funkcje skryptowe są określone przez specjalnie oznaczone atrybuty, takie jak ng-disabled ng-hrefi wiele innych. Nie dodajesz selektorów w swoim javascript. Dokument HTML staje się głównym autorytetem w zakresie tego, co jest skryptowane i jak, a javascript działa na nim abstrakcyjnie. To dobre podejście, ale oczywiście z wyższą krzywą uczenia się niż poprzednie metody. I znowu należy wziąć pod uwagę wydajność.

Ale nigdy nie myśl, że możesz pisać interaktywny HTML i javascript, i w jakiś sposób obie te części nie wiedzą o drugiej. To więcej o tym, jak ograniczyć odniesienia do zależności.

mastaBlasta
źródło
2
Genialna odpowiedź, +1. Gdyby tylko wspomnieć o atrybutach danych jako mechanizmie unikania ścisłego powiązania
Fergus In London
3
atrybuty danych nie są panaceum. Są teraz bardzo popularne i ludzie wkładają do nich wszystko oprócz zlewu kuchennego. Wiele frameworków (np. JQuery UI) używa ich intensywnie. Musisz być bardzo surowy w zakresie nazw i innych konwencji, aby uniknąć problemów. Pomagają oddzielić HTML od JS, ale niekoniecznie ułatwiają debugowanie.
mastaBlasta
Nigdy nie rozumiałem, dlaczego należy na nowo wymyślać klasy, identyfikatory i atrybuty danych jako haczyki i flagi stanu. Wszystko, co Angular osiągnął w tym względzie, to zmniejszenie wydajności i zastąpienie powszechnie znanej / rozumianej konwencji nową konwencją, wymagającą zrozumienia, jak to zrobić „po Angularu”, wymyślania własnych atrybutów i tagów. Nie ma tam dużej krzywej uczenia się. Jest po prostu wolniejszy, wbrew całkowicie rozsądnej i powszechnie znanej konwencji i całkowicie niepotrzebnemu IMO.
Erik Reppen,
9

Jeśli chcesz zrezygnować z interaktywności, którą masz, możesz całkowicie uniknąć Javascript. Frameworki takie jak ASP.NET MVC są bardzo dobre w wyświetlaniu stron zawierających tylko HTML, CSS i przycisk SUBMIT.

DOBRZE. Może to trochę ekstremalne.

Odsprzęganie w aplikacji internetowej występuje już na wielu poziomach. Aplikacje REST umożliwiają definiowanie aplikacji w kategoriach „zasobów sieciowych” powiązanych z adresem URL. Wyświetl modele umożliwiają prezentację danych w interfejsie użytkownika, który jest oddzielony od modelu domeny, ale ma kształt, którego potrzebujesz, aby go poprawnie wyświetlić. Warstwy serwisowe pozwalają na zamianę jednego interfejsu użytkownika na inny i tak dalej.

Historycznie zawsze istniał kompromis między interaktywnością a sprzężeniem. Im bardziej interaktywna jest twoja strona internetowa, tym bardziej będzie ściśle związana z aplikacją. Ale logika interaktywności na stronie internetowej ogranicza się do samej strony internetowej; każde połączenie z serwerem nastąpi przez POST lub AJAX. Nie jestem więc pewien, czy powinieneś zbytnio przejmować się sprzężeniem na poziomie Javascript, poza zwracaniem uwagi na sposób przesyłania pakietów danych między przeglądarką a serwerem.

Najbardziej „nowoczesnym” podejściem (tj. Smakiem tygodnia) są prawdopodobnie aplikacje SPA .

Robert Harvey
źródło
Nie brzmi dla mnie ekstremalnie. Wiele witryn, które intensywnie korzystają z JavaScript, do tego stopnia, że ​​bez niego są bezużyteczne, w rzeczywistości nie potrzebują go. Czy ich twórcy mieliby więcej wskazówek ...
Michael Hampton
5

Martin Fowler opisuje jedno podejście do tego jako segregowany DOM , w którym oddzielasz DOM JavaScript od JavaScript logiki strony.

Application Logic <----> DOM Manipulation <----> DOM / HTML
Rory Hunter
źródło
1
+1 Całkowicie zgadzam się z segregacją logiki DOM <--> DOM JavaScript. Naprawdę nie lubię atrybutów danych, ponieważ nie dotyczą one modelu DOM, ale narzędzia zewnętrznego. Uważam, że czystszym podejściem jest posiadanie pewnego rodzaju mapowania. Tak, może to oznaczać, że masz plik z odniesieniami do dwóch aspektów (np. Funkcji JS i elementów DOM), a nie np. DOM zawierający pewne odwołania, które JS wybiera (które można opisać jako „pojedynczy aspekt ”). Jeśli jednak zostanie to przemyślane, może być bardzo łatwe w utrzymaniu, wielokrotnego użytku i oferuje lepsze oddzielenie problemów niż atrybutów danych.
awj
2

Nie, nie należy unikać używania selektorów klas, elementów i identyfikatorów po stronie klienta. Składnia jest używana, ponieważ selektory CSS są bardzo dojrzałym i dobrze ugruntowanym językiem domeny, a wspólny projekt znacznie ułatwia dzielenie wspólnego logicznego modelu strony między programem a projektem, co jest bardzo, bardzo dobrą rzeczą.

Chociaż możliwe jest nieprawidłowe użycie tej składni i utworzenie okropnej i niemożliwej do utrzymania aplikacji, jest to możliwe niezależnie od języka i zestawu narzędzi.

DougM
źródło
2
W rzeczywistości odradzam używanie selektorów klas, elementów i identyfikatorów do wielu rzeczy, a zamiast tego skupiam się na używaniu niestandardowych [data-*]selektorów atrybutów, których można używać na bardzo potężne sposoby.
zzzzBov
2
W mojej opinii kiepska rada, szczególnie jeśli chodzi o pisanie modułowych JS wielokrotnego użytku, które nie powinny zakładać selektorów. Atrybuty danych są lepszym pomysłem dla tych scenariuszy.
Fergus In London
3
@zzzzBov - Wiem, że to mikrooptymalizacja, ale wyszukiwanie ID i klas jest znacznie szybsze niż wyszukiwanie atrybutów danych. Ale tak, podoba mi się pomysł używania różnych zestawów atrybutów do rozwiązywania różnych problemów.
Jimmy Breck-McKye
0

Ktoś musi zbudować interfejs menedżera ścieżek jQuery dla warstwy pośredniej i pamięci podręcznej do domeny.

pathMgr.register(name,selector [,isDynamic=false]);
pathMgr.get(name [,refresh]);

Następnie,

String.prototype.reg([isDynamic=false]);
String.prototype.get(name [,refresh]);

Więc,

// at init....
var pathMgr=new PathMgr();
'sidebar-links #sidebar a'.reg();// new registery of selector '#sidebar a' under name 'sidebar-links'
// more, more


// in code
'sidebar-links'.get().css(etc...);
//or
'sidebar-links'.addStyleRule({});
znak
źródło