Stretto accoppiamento tra Javascript, HTML e CSS: un approccio più moderno?


29

È molto comune vedere Javascript associato a determinati selettori per trovare elementi, archiviare dati e ascoltare eventi. È anche comune vedere questi stessi selettori usati per lo styling.

jQuery (e il suo motore di selezione Sizzle) supportano e promuovono facendo riferimento a elementi con sintassi di tipo CSS. Come tale, questa tecnica è particolarmente difficile da "disimparare" (o refactoring) quando si costruiscono progetti.

Ho capito che questo è il risultato della storia dello sviluppo di HTML e Javascript e che i browser sono stati creati per consumare / analizzare / rendere in modo efficiente questo tipo di accoppiamento. Ma man mano che i siti Web diventano sempre più complessi, questa realtà può presentare difficoltà nell'organizzazione e nel mantenimento di questi livelli separati.

La mia domanda è: può e dovrebbe essere evitato nei siti Web moderni?

Se sono nuovo nello sviluppo del front-end e desidero imparare le cose "nel modo giusto", vale la pena imparare a separare ed evitare tali dipendenze dall'inizio? Questo significa evitare jQuery a favore di una libreria che promuove una struttura più disaccoppiata?


1
Come funzionerebbe una cosa del genere? Come, ad esempio, disabilitare un controllo su una pagina senza toccarlo in qualche modo o conoscerlo? (questo è il mio piccolo modo di dire che devi essere più specifico su cosa intendi per disaccoppiamento, idealmente con alcuni esempi, anche se sono inventati).
Robert Harvey,

2
La cosa più importante quando parli di disaccoppiare html, css e js è usare i selettori di classe invece di qualsiasi altro, questo è il concetto centrale di metodologie come oocss e BEM.
angvillar,

Scopri React o i componenti web e non dovrai più preoccuparti dei selettori in JS.
Andy,

Risposte:


35

Non c'è modo di evitarlo. Sono accoppiati perché interagiscono tra loro. Se il tuo javascript intende eseguire qualsiasi tipo di manipolazione DOM, allora ha bisogno di un modo per fare riferimento al DOM.

Ci sono varie convenzioni per questo.

L'API DOM di livello 2 fornisce i metodi getElementById, getElementByTagName e getElementsByName. Ad oggi questi sono i cavalli di battaglia di qualsiasi tipo di attraversamento del DOM. Tutti gli altri selettori jQuery più elaborati si risolvono in una combinazione di questi eventualmente, e / o attraversando direttamente ogni nodo DOM (questo era il modo di fare getByClassName).

Non c'è altra scorciatoia. Javascript deve sapere cosa fare e dove. In genere, se un elemento ha un id o una classe che è rilevante solo nello scripting, molte persone lo anteporranno con js-o con qualche altra bandiera evidente.

Un'altra convenzione più recente è la selezione dell'attributo di dati.

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

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

L'attributo data viene generalmente utilizzato per scopi di scripting e la selezione dell'uso ha un senso. Lo svantaggio è che questo è più lento rispetto all'utilizzo di getElementById ().

Un altro approccio è quello utilizzato da angularJS, che crea un modello di visualizzazione. In questa convenzione qualsiasi tipo di funzionalità di scripting è specificato da attributi appositamente designati ng-disabled ng-hrefe molti altri. Non aggiungi selettori nel tuo JavaScript. Il documento HTML diventa l'autorità principale su ciò che è scritto e come, e il javascript ci lavora in modo astratto. È un buon approccio, ma ovviamente con una curva di apprendimento più elevata rispetto ai metodi precedenti. E ancora, le prestazioni devono essere considerate.

Ma non pensare mai che puoi scrivere HTML interattivo e javascript e in qualche modo entrambe le parti non conoscono l'altra. Si tratta di come limitare i riferimenti alle dipendenze.


2
Risposta brillante, +1. Se non altro per menzionare gli attributi dei dati come meccanismo per evitare l'accoppiamento stretto
Fergus In London,

3
gli attributi dei dati non sono una panacea. Sono molto popolari in questi giorni e la gente ci mette tutto tranne il lavello della cucina. Molti framework (ad es. L'interfaccia utente di jQuery) li usano ampiamente. Devi essere molto severo con lo spazio dei nomi e altre convenzioni per evitare problemi. Aiutano a disaccoppiare HTML da JS, ma non rendono necessariamente più semplice il debug.
mastaBlasta,

Non ho mai capito perché fosse necessario reinventare l'utilizzo di classi, ID e attributi di dati come hook e flag di stato. Tutto ciò che Angular ha realizzato in tal senso è una riduzione delle prestazioni e ha sostituito la convenzione ampiamente conosciuta / capita con una nuova che richiede di capire come farlo "in modo angolare", inventando i propri attributi e tag. Non c'è un'enorme curva di apprendimento lì. È solo più lento, in contrasto con una convenzione perfettamente ragionevole e comunemente nota e IMO completamente inutile.
Erik Reppen,

9

Se sei disposto a rinunciare all'interattività che ottieni, puoi evitare completamente Javascript. Frame come ASP.NET MVC sono molto bravi a pubblicare pagine che contengono solo HTML, CSS e un pulsante INVIA.

OK. Forse è un po 'estremo.

Il disaccoppiamento in un'applicazione Web si verifica già a molti livelli. Le applicazioni REST ti consentono di definire la tua applicazione in termini di "risorse web" associate a un URL. Visualizza modelli consente di presentare all'interfaccia utente i dati che sono disaccoppiati dal modello di dominio, ma ha la forma necessaria per visualizzarli correttamente. I livelli di servizio consentono di scambiare un'interfaccia utente con un'altra e così via.

Storicamente, c'è sempre stato un compromesso tra interattività e accoppiamento. Quanto più interattiva è la tua pagina web, tanto più strettamente legata all'applicazione sarà. Ma la logica di interattività nella pagina Web è limitata alla pagina Web stessa; qualsiasi accoppiamento con il server avverrà tramite POST o AJAX. Quindi non sono sicuro che dovresti preoccuparti eccessivamente dell'accoppiamento a livello Javascript, oltre a prestare attenzione al modo in cui i pacchetti di dati vengono passati tra il browser e il server.

L'approccio più "moderno" (ovvero il sapore della settimana) è probabilmente l' applicazione SPA .


Non sembra estremo per me. Molti siti che fanno ampio uso di JavaScript, al punto da essere inutilizzabili senza di essa, in realtà non ne hanno bisogno. I loro sviluppatori avrebbero avuto più di un indizio ...
Michael Hampton,

5

Martin Fowler descrive un approccio a questo come il DOM segregato , in cui separa il tuo JavaScript JavaScript dalla tua logica di pagina JavaScript.

Application Logic <----> DOM Manipulation <----> DOM / HTML

1
+1 Sono totalmente d'accordo con la separazione della logica DOM <--> JavaScript. Non mi piacciono davvero gli attributi dei dati in quanto questi non sono pertinenti al DOM ma per uno strumento esterno. Sento che un approccio più pulito è avere un qualche tipo di mappatura. Sì, ciò può significare che hai quindi un file con riferimenti a due aspetti (ad esempio, funzioni JS ed elementi DOM) anziché, ad esempio, il DOM contenente alcuni riferimenti che JS raccoglie (che potrebbe essere descritto come "aspetto singolo '). Tuttavia, se fatto in modo ponderato, questo può essere molto mantenibile, riutilizzabile e offre una migliore separazione delle preoccupazioni rispetto agli attributi dei dati.
awj

2

No, l'uso di selettori di classe, elemento e ID sul lato client non dovrebbe essere evitato. La sintassi viene utilizzata perché i selettori CSS sono un linguaggio di dominio molto maturo e ben consolidato e avere un design comune rende molto più facile condividere un modello logico comune di una pagina tra programma e design, il che è una cosa molto, molto buona.

Sebbene sia possibile utilizzare in modo improprio questa sintassi e creare un'applicazione terribile e non mantenibile, ciò è possibile indipendentemente dalla lingua o dal set di strumenti.


2
In realtà sconsiglio di utilizzare selettori di classi, elementi e ID per molte cose, e invece mi concentro sull'uso di [data-*]selettori di attributi personalizzati , che possono essere utilizzati in modi molto potenti.
zzzzBov,

2
Cattivi consigli nella mia mente, specialmente quando si tratta di scrivere JS modulari / riutilizzabili che non dovrebbero fare ipotesi sui selettori. Gli attributi dei dati sono un'idea migliore per questi scenari.
Fergus A Londra,

3
@zzzzBov - So che è una microottimizzazione, ma le ricerche di ID e di classe sono molto più veloci delle ricerche di attributi di dati. Sì, mi piace l'idea di utilizzare diversi set di attributi per gestire preoccupazioni diverse.
Jimmy Breck-McKye il

0

Qualcuno deve creare un'interfaccia del gestore percorsi jQuery per un livello indiretto e cache al dom.

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

Poi,

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

Così,

// 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({});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.