Acoplamento apertado entre Javascript, HTML e CSS: uma abordagem mais moderna?


29

É muito comum ver o Javascript vinculado a determinados seletores para encontrar elementos, armazenar dados e ouvir eventos. Também é comum ver esses mesmos seletores usados ​​para estilizar.

O jQuery (e seu mecanismo de seleção Sizzle) suportam e promovem isso referenciando elementos com sintaxe do tipo CSS. Como tal, essa técnica é particularmente difícil de desaprender (ou refatorar) ao criar projetos.

Eu entendi que isso é resultado do histórico de desenvolvimento de HTML e Javascript e que os navegadores foram criados para consumir / analisar / renderizar eficientemente esse tipo de acoplamento. Porém, à medida que os sites se tornam cada vez mais complexos, essa realidade pode introduzir dificuldades na organização e manutenção dessas camadas separadas.

Minha pergunta é: isso pode e deve ser evitado em sites modernos?

Se eu sou novo no desenvolvimento de front-end e gostaria de aprender as coisas 'da maneira certa', vale a pena aprender a dissociar e evitar essas dependências desde o início? Isso significa evitar o jQuery em favor de uma biblioteca que promova uma estrutura mais dissociada?


1
Como isso funcionaria? Como você, por exemplo, desabilita um controle em uma página sem realmente tocá-lo de alguma forma ou ter conhecimento dele? (esta é minha pequena maneira de dizer que você precisa ser mais específico sobre o que quer dizer com dissociação, idealmente com alguns exemplos, mesmo que sejam inventados).
Robert Harvey

2
A coisa mais importante quando se fala em dissociar html, css e js é usar seletores de classe em vez de qualquer outro, esse é o conceito principal de metodologias como oocss e BEM.
angvillar

Aprenda React ou componentes da Web, e você não precisará mais se preocupar com os seletores em JS.
Andy Andy

Respostas:


35

Não há como evitar isso. Eles são acoplados porque interagem entre si. Se o seu javascript pretende fazer qualquer tipo de manipulação do DOM, ele precisa de uma maneira de fazer referência ao DOM.

Existem várias convenções para isso.

A API DOM de nível 2 fornece os métodos getElementById, getElementByTagName e getElementsByName. Até hoje, esses são os cavalos de trabalho de qualquer tipo de travessia DOM. Todos os outros seletores jQuery mais sofisticados resolvem uma combinação desses eventualmente e / ou a travessia direta de cada nó DOM (essa era a maneira de obter getByClassName).

Não há outro atalho. Javascript precisa saber o que fazer e onde. Normalmente, se um elemento tem um ID ou classe que é relevante apenas para scripts, muitas pessoas o prefixam com js-outro sinalizador óbvio.

Outra convenção mais recente é a seleção de atributos de dados.

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

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

O atributo de dados é geralmente usado para fins de script e selecionar usando isso faz algum sentido. A desvantagem é que isso é mais lento do que usar getElementById ().

Outra abordagem é a usada pelo angularJS, que cria um modelo de visualização. Nesta convenção, qualquer tipo de funcionalidade de script é especificado por atributos especialmente designados, como ng-disabled ng-hrefmuitos outros. Você não adiciona seletores no seu javascript. O documento HTML se torna a principal autoridade sobre o script e como, e o javascript funciona abstratamente. É uma boa abordagem, mas obviamente com uma curva de aprendizado mais alta que os métodos anteriores. E, novamente, o desempenho deve ser considerado.

Mas nunca pense que você pode escrever HTML interativo e javascript, e de alguma forma essas duas partes não conhecem a outra. É mais sobre como você pode limitar as referências a dependências.


2
Resposta brilhante, +1. Se apenas para mencionar atributos de dados como um mecanismo para evitar acoplamento forte
Fergus Em Londres

3
atributos de dados não são uma panacéia. Hoje em dia, eles são muito populares e as pessoas estão colocando tudo, menos a pia da cozinha. Muitas estruturas (por exemplo, jQuery UI) as utilizam extensivamente. Você precisa ser rigoroso com o namespace e outras convenções para evitar problemas. Eles ajudam a dissociar o HTML do JS, mas não facilitam necessariamente a depuração.
mastaBlasta

Eu nunca entendi por que o uso de classes, IDs e atributos de dados como ganchos e sinalizadores de estado precisava ser reinventado. Tudo o que a Angular conseguiu nesse sentido é uma redução no desempenho e substituiu a convenção amplamente conhecida / compreendida por uma nova, exigindo que você entenda como fazê-lo "da maneira Angular", inventando seus próprios atributos e tags. Não há uma enorme curva de aprendizado lá. É apenas mais lento, contrário à convenção perfeitamente razoável e comumente conhecida e à IMO completamente desnecessária.
Erik Reppen

9

Se você deseja renunciar à interatividade que obtém, pode evitar completamente o Javascript. Estruturas como o ASP.NET MVC são muito boas para exibir páginas que contêm apenas HTML, CSS e um botão SUBMIT.

ESTÁ BEM. Talvez isso seja um pouco extremo.

A dissociação em um aplicativo Web já ocorre em vários níveis. Os aplicativos REST permitem definir seu aplicativo em termos de "recursos da web" associados a um URL. Exibir modelos permite que você apresente dados à interface do usuário que está desacoplada do modelo de domínio, mas que possui a forma necessária para exibi-los adequadamente. As camadas de serviço permitem que uma interface do usuário seja trocada por outra e assim por diante.

Historicamente, sempre houve uma troca entre interatividade e acoplamento. Quanto mais interativa for sua página da Web, mais fortemente acoplada ao aplicativo será. Mas a lógica de interatividade na página da web está confinada à própria página da web; qualquer acoplamento com o servidor ocorrerá através do POST ou do AJAX. Portanto, não tenho certeza de que você deva se preocupar muito com o acoplamento no nível do Javascript, além de prestar atenção à maneira como os pacotes de dados são transmitidos entre o navegador e o servidor.

A abordagem mais "moderna" (ou seja, o sabor da semana) é provavelmente a aplicação de SPA .


Não me parece extremo. Muitos sites que fazem uso extensivo de JavaScript, a ponto de serem inutilizáveis ​​sem ele, na verdade não precisam dele. Oxalá seus desenvolvedores tinha mais de uma pista ...
Michael Hampton

5

Martin Fowler descreve uma abordagem para isso como o DOM segregado , em que você separa o JavaScript do DOM do JavaScript da lógica da página.

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

1
+1 Concordo totalmente em segregar a lógica DOM do JavaScript <-->. Eu realmente não gosto de atributos de dados, pois eles não são pertinentes ao DOM, mas para uma ferramenta externa. Eu sinto que uma abordagem mais limpa é ter algum tipo de mapeamento. Sim, isso pode significar que você possui um arquivo com referências a dois aspectos (por exemplo, funções JS e elementos DOM), em vez de, por exemplo, o DOM contendo algumas referências que o JS seleciona (que pode ser descrito como 'aspecto único '). No entanto, se feito com cuidado, isso pode ser muito sustentável, reutilizável e oferecer uma melhor separação de preocupações do que atributos de dados.
28414 awj

2

Não, o uso de seletores de classe, elemento e ID no cliente não deve ser evitado. A sintaxe é usada porque os seletores de CSS são uma linguagem de domínio muito madura e bem estabelecida, e ter um design comum facilita muito o compartilhamento de um modelo lógico comum de uma página entre programa e design, o que é uma coisa muito, muito boa.

Embora seja possível usar mal essa sintaxe e criar um aplicativo terrível e insustentável, isso é possível independentemente do seu idioma ou conjunto de ferramentas.


2
Na verdade, eu recomendo o uso de seletores de classe, elemento e ID para muitas coisas e, em vez disso, concentro-me no uso de [data-*]seletores de atributos personalizados , que podem ser usados ​​de maneiras muito poderosas.
zzzzBov

2
Aconselhamento ruim em minha mente, especialmente quando se trata de escrever JS modular / reutilizável que não deve assumir pressupostos nos seletores. Os atributos de dados são uma ideia melhor para esses cenários.
Fergus Em Londres

3
@zzzzBov - Eu sei que é uma microoptimização, mas as pesquisas de ID e de classe são muito mais rápidas que as pesquisas de atributos de dados. Mas sim, gosto da ideia de usar diferentes conjuntos de atributos para lidar com diferentes preocupações.
Jimmy Breck-McKye

0

Alguém precisa construir uma interface do gerenciador de caminho do jQuery para uma camada indireta e de cache no domínio.

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

Então,

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

Tão,

// 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({});
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.