Щільне з'єднання Javascript, HTML та CSS: сучасніший підхід?


29

Дуже часто бачити, як Javascript прив'язаний до певних селекторів, щоб знайти елементи, зберігати дані та слухати події. Також звичайно бачити ці самі селектори, які використовуються для стилізації.

jQuery (та його селекторний двигун Sizzle) підтримують та сприяють цьому, посилаючись на елементи з синтаксисом типу CSS. Таким чином, цю техніку особливо складно «вивчити» (або рефактор) під час створення проектів.

Я зрозумів, що це результат історії розробки HTML і Javascript, і що браузери були побудовані для ефективного споживання / розбору / та надання такого роду з'єднань. Але оскільки веб-сайти стають все більш складними, ця реальність може створити труднощі в організації та підтримці цих окремих шарів.

Моє запитання: чи можна і чи слід цього уникати на сучасних веб-сайтах?

Якщо я новачок у передових розробках, і хочу навчитися речам «правильно», чи варто навчитися розв’язувати та уникати таких залежностей з самого початку? Чи означає це уникати jQuery на користь бібліотеки, яка рекламує більш розв'язану структуру?


1
Як би подібна річ працювала? Як ви, наприклад, вимкніть елемент керування на сторінці, фактично не торкаючись цього елемента чи не знаючи про нього? (це мій маленький спосіб сказати, що вам потрібно бути більш конкретним щодо того, що ви маєте на увазі під розв'язкою, в ідеалі з деякими прикладами, навіть якщо вони надумані).
Роберт Харві

2
Найголовніше, коли ви говорите про розв'язку html, css та js, це використання селекторів класів замість будь-яких інших, це основна концепція таких методологій, як oocss та BEM.
ангвіллар

Дізнайтеся про React або веб-компоненти, і вам більше не доведеться турбуватися з селекторами в JS.
Енді

Відповіді:


35

Неможливо цього уникнути. Вони сполучені через те, що взаємодіють між собою. Якщо ваш JavaScript має намір робити будь-які маніпуляції з DOM, то йому потрібен спосіб посилання на DOM.

Для цього існують різні умовності.

API DOM рівня 2 забезпечує методи getElementById, getElementByTagName та getElementsByName. На сьогоднішній день це робочі коні будь-якого обходу DOM. Всі інші більш фантазійні jQuery-селектори вирішують комбінацію цих результатів та / або пряму обхід кожного вузла DOM (це було способом зробити getByClassName).

Іншого ярлика немає. Javascript повинен знати, що робити і де. Як правило, якщо в елементі є ідентифікатор або клас, що стосується лише сценаріїв, багато людей будуть префіксувати його js-чи іншим очевидним прапором.

Ще одна більш нова умова - це вибір атрибутів даних.

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

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

Атрибут даних, як правило, використовується для сценаріїв, а вибір, який використовується, має певний сенс. Недолік у тому, що це повільніше, ніж використання getElementById ().

Іншим підходом є той, який використовує angularJS, який створює модель перегляду. У цій конвенції будь-який тип функцій сценаріїв визначається спеціально призначеними атрибутами, як ng-disabled ng-hrefі багато інших. Ви не додаєте селекторів у свій JavaScript. Документ HTML стає головним органом щодо того, що написано та як, і javascript на ньому працює абстрактно. Це хороший підхід, але, очевидно, з вищою кривою навчання, ніж попередні методи. І знову ж таки, продуманість повинна враховуватися.

Але ніколи не думайте, що ви можете писати інтерактивні HTML та JavaScript, і якось обидві ці частини не знають про іншу. Це більше про те, як можна обмежити посилання на залежності.


2
Блискуча відповідь, +1. Якби тільки згадати атрибути даних як механізм уникнення тісного зчеплення
Фергюс в Лондоні

3
дані-атрибути не є панацеєю. Вони дуже популярні в ці дні, і люди вкладають у них все, крім кухонної раковини. Дуже багато фреймворків (наприклад, інтерфейс jQuery) широко використовують їх. Ви повинні бути дуже суворими з простором імен та іншими умовами, щоб уникнути проблем. Вони допомагають роз’єднати HTML від JS, але вони не обов'язково полегшують налагодження.
mastaBlasta

Я ніколи не розумів, чому використання класів, ідентифікаторів та атрибутів даних у якості гачків та прапорів стану потрібно переосмислити. Все, що досягається в цьому плані, - це зниження продуктивності і замінило широко відому / зрозумілу конвенцію на нову, яка вимагає зрозуміти, як це зробити "кутовим шляхом", придумуючи власні атрибути та теги. Тут немає величезної кривої навчання. Це просто повільніше, протилежне абсолютно розумній і загальновідомій конвенції та абсолютно непотрібному ІМО.
Ерік Реппен

9

Якщо ви готові відмовитися від інтерактивності, яку ви отримаєте, ви можете повністю уникати Javascript. Такі структури, як ASP.NET MVC, дуже добре обслуговують сторінки, що містять лише HTML, CSS та кнопку SUBMIT.

ДОБРЕ. Можливо, це трохи екстремально.

Розв'язка веб-програми вже відбувається на багатьох рівнях. Програми REST дозволяють визначити ваш додаток з точки зору "веб-ресурсів", пов'язаних із URL-адресою. Моделі перегляду дозволяють представляти дані в інтерфейс користувача, який відокремлений від доменної моделі, але має форму, необхідну для правильного його відображення. Сервісні шари дозволяють замінити один інтерфейс користувача на інший тощо.

Історично завжди було взаємодія між інтерактивністю та зв'язком. Чим інтерактивніша ваша веб-сторінка, тим щільніше поєднане з додатком. Але логіка інтерактивності на веб-сторінці обмежується лише веб-сторінкою; будь-яке з'єднання з сервером відбудеться через POST або AJAX. Тому я не впевнений, що вам слід надто перейматися зв'язком на рівні Javascript, крім того, щоб звертати увагу на спосіб передачі пакетів даних між браузером та сервером.

Найбільш "сучасний" підхід (тобто аромат тижня), ймовірно, SPA-програми .


Це не звучить для мене екстремально. Багато сайтів, які широко використовують JavaScript, настільки, що без нього вони непридатні, насправді це не потрібно. Хіба що їхні розробники мали більше підказки ...
Майкл Хемптон,

5

Мартін Фаулер описує один підхід до цього як відокремлений DOM , де ви відокремлюєте свій DOM JavaScript від логіки JavaScript на своїй сторінці.

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

1
+1 Я повністю згоден з розділенням JavaScript <--> логіки DOM. Мені дуже не подобаються атрибути даних, оскільки вони не стосуються DOM, а для зовнішнього інструменту. Я відчуваю, що більш чистим підходом є створення певного типу картографування. Так, це може означати, що тоді у вас є файл із посиланням на два аспекти (наприклад, JS-функції та елементи DOM), а не, наприклад, DOM, що містить деякі посилання, які підбирає JS (який може бути описаний як "одноаспектний" '). Однак, якщо зробити це продумано, це може бути дуже ремонтоприйнятним, багаторазовим і запропонувати краще розділити проблеми, ніж атрибути даних.
awj

2

Ні, не слід уникати використання селекторів класів, елементів та ідентифікаторів на стороні клієнта. Синтаксис використовується тому, що селектори CSS є дуже зрілою та добре усталеною мовою домену, і, маючи спільний дизайн, набагато простіше ділитися загальною логічною моделлю сторінки між програмою та дизайном, що дуже, дуже добре.

Хоча можливо використовувати цей синтаксис неправильно та створити жахливий і нездійснений додаток, таке можливо незалежно від вашої мови чи набору інструментів.


2
Я фактично рекомендую не використовувати селектори класів, елементів та ідентифікаторів для багатьох речей, а замість цього зосереджуюсь на використанні спеціальних [data-*]селекторів атрибутів, які можна використовувати дуже потужними способами.
zzzzBov

2
Погана порада в моїй думці, особливо якщо мова йде про написання модульного / багаторазового використання JS, який не повинен робити припущення щодо селекторів. Атрибути даних є кращою ідеєю для цих сценаріїв.
Фергюс у Лондоні,

3
@zzzzBov - Я знаю, що це мікрооптимізація, але пошук ідентифікаторів та класів набагато швидше, ніж пошук даних-атрибутів. Але так, мені подобається ідея використовувати різні набори атрибутів для вирішення різних проблем.
Джиммі Брек-Маккі

0

Комусь потрібно створити інтерфейс менеджера контурів jQuery для шару непрямості та кешу до дому.

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

Потім,

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

Так,

// 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({});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.