Тесная связь между Javascript, HTML и CSS: более современный подход?

29

Очень часто Javascript привязывают к определенным селекторам, чтобы находить элементы, хранить данные и прослушивать события. Также распространено видеть те же самые селекторы, используемые для стиля.

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

Я понял, что это результат истории разработки HTML и Javascript, и что браузеры были созданы для эффективного использования / разбора / и рендеринга такого рода связи. Но поскольку веб-сайты становятся все более сложными, эта реальность может создать трудности при организации и поддержании этих отдельных слоев.

Мой вопрос: можно ли этого избежать на современных веб-сайтах?

Если я новичок в разработке front-end и хочу изучать вещи «правильным образом», стоит ли учиться отделять и избегать таких зависимостей с самого начала? Означает ли это, что нужно избегать jQuery в пользу библиотеки, которая продвигает более разделенную структуру?

Стюарт Кершоу
источник
1
Как бы это сработало? Как, например, отключить элемент управления на странице, не затрагивая его каким-либо образом или не зная об этом? (это мой маленький способ сказать, что вы должны быть более конкретными в отношении того, что вы подразумеваете под разделением, в идеале с некоторыми примерами, даже если они придуманы).
Роберт Харви
2
Когда вы говорите о разъединении html, css и js, самое важное - это использовать селекторы классов вместо любых других, это основная концепция методологий, таких как oocss и BEM.
Ангвилар
Изучите React или веб-компоненты, и вам больше не придется беспокоиться о селекторах в JS.
Энди

Ответы:

35

Нет способа избежать этого. Они связаны, потому что они взаимодействуют друг с другом. Если ваш javascript намеревается выполнять какие-либо манипуляции с DOM, ему нужен способ ссылки на DOM.

Есть различные соглашения для этого.

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

Там нет другого ярлыка. Javascript должен знать, что делать и где. Как правило, если элемент имеет идентификатор или класс, который имеет отношение только к сценариям, многие люди ставят перед ним префикс js-или какой-либо другой очевидный флаг.

Другое более новое соглашение - выбор атрибута данных.

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

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

Атрибут data, как правило, используется в целях написания сценариев, и его выбор имеет смысл. Недостаток в том, что это медленнее, чем при использовании getElementById ().

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

Но никогда не думайте, что вы можете написать интерактивный HTML и javascript, и каким-то образом обе эти части не знают друг о друге. Это больше о том, как вы можете ограничить ссылки на зависимости.

mastaBlasta
источник
2
Блестящий ответ, +1. Если бы только упоминание атрибутов данных как механизма, позволяющего избежать жесткой связи
Fergus In London
3
Атрибуты данных не являются панацеей. Они очень популярны в наши дни, и люди вкладывают в них все, кроме раковины. Многие фреймворки (например, jQuery UI) широко их используют. Вы должны быть очень строгими с пространством имен и другими соглашениями, чтобы избежать проблем. Они помогают отделить HTML от JS, но не обязательно облегчают отладку.
mastaBlasta
Я никогда не понимал, почему нужно заново изобретать использование классов, идентификаторов и атрибутов данных в качестве хуков и флагов состояния. В этом отношении все, чего добился Angular, - это снижение производительности и замена широко известного / понятного соглашения новым, требующим понимания, как это сделать «угловым путем», изобретая свои собственные атрибуты и теги. Там нет огромной кривой обучения там. Это просто медленнее, противоречит совершенно разумному и общеизвестному соглашению и совершенно ненужной ИМО.
Эрик Реппен
9

Если вы хотите отказаться от интерактивности, которую вы получаете, вы можете полностью избежать Javascript. Фреймворки, такие как ASP.NET MVC, очень хороши в обслуживании страниц, которые содержат только HTML, CSS и кнопку SUBMIT.

ХОРОШО. Может быть, это немного экстрим.

Разделение в веб-приложении уже происходит на многих уровнях. Приложения REST позволяют определять ваше приложение в терминах «веб-ресурсов», связанных с URL-адресом. Модели представления позволяют вам представлять данные в пользовательском интерфейсе, который отделен от модели предметной области, но имеет форму, необходимую для правильного отображения. Уровни обслуживания позволяют менять один пользовательский интерфейс на другой и т. Д.

Исторически всегда существовал компромисс между интерактивностью и взаимодействием. Чем более интерактивна ваша веб-страница, тем более тесно она связана с приложением. Но логика интерактивности на веб-странице ограничена самой веб-страницей; любая связь с сервером происходит через POST или AJAX. Поэтому я не уверен, что вы должны быть чрезмерно обеспокоены связью на уровне Javascript, кроме как обращать внимание на то, как пакеты данных передаются между браузером и сервером.

Наиболее «современный» подход (т. Е. Аромат недели) - это, вероятно, SPA-приложения .

Роберт Харви
источник
Не звучит экстремально для меня. Многие сайты, которые широко используют JavaScript, до такой степени, что они бесполезны без него, на самом деле не нуждаются в нем. Если бы у их разработчиков было больше подсказок ...
Майкл Хэмптон
5

Мартин Фаулер описывает один из подходов к этому как Segregated DOM , где вы отделяете свой DOM JavaScript от логики страницы JavaScript.

Application Logic <----> DOM Manipulation <----> DOM / HTML
Рори Хантер
источник
1
+1 Я полностью согласен с разделением логики JavaScript <-> DOM. Мне действительно не нравятся атрибуты данных, поскольку они относятся не к DOM, а к внешнему инструменту. Я чувствую, что более чистый подход заключается в том, чтобы иметь некоторый тип картирования. Да, это может означать, что у вас есть файл со ссылками на два аспекта (например, функции JS и элементы DOM), а не, например, DOM, содержащий некоторые ссылки, которые JS берет (которые могут быть описаны как «одноаспектные»). «). Однако, если все сделано вдумчиво, это может быть очень легко обслуживаемым, многократно используемым и предлагать лучшее разделение проблем, чем атрибуты данных.
awj
2

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

Хотя можно неправильно использовать этот синтаксис и создать ужасное и не поддерживаемое приложение, это возможно независимо от вашего языка или набора инструментов.

DougM
источник
2
На самом деле я рекомендую не использовать селекторы классов, элементов и идентификаторов для многих вещей, а вместо этого сосредоточиться на использовании пользовательских [data-*]селекторов атрибутов, которые можно использовать очень мощными способами.
zzzzBov
2
На мой взгляд, плохой совет, особенно когда речь идет о написании модульных / многоразовых JS, которые не должны предполагать селекторы. Атрибуты данных - лучшая идея для этих сценариев.
Фергус в Лондоне
3
@zzzzBov - я знаю, что это микрооптимизация, но поиск по идентификатору и классу намного быстрее, чем поиск по атрибуту данных. Но да, мне нравится идея использования разных наборов атрибутов для решения разных задач.
Джимми Брек-МакКей
0

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

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({});
отметка
источник