Javascript、HTML、およびCSS間の緊密な結合:より現代的なアプローチ?


29

要素を見つけ、データを保存し、イベントをリッスンするために、特定のセレクターにバインドされたJavascriptを見るのは非常に一般的です。これらの同じセレクターがスタイリングに使用されることもよく見られます。

jQuery(およびそのセレクターエンジンSizzle)は、CSSタイプの構文で要素を参照することにより、これをサポートおよび促進します。そのため、プロジェクトを構築するときに、この手法を「学習」(またはリファクタリング)することは特に困難です。

これはHTMLとJavascriptの開発の歴史の結果であり、この種のカップリングを効率的に消費/解析/レンダリングするためにブラウザーが構築されていることを理解するようになりました。しかし、Webサイトがますます複雑になるにつれて、この現実により、これらの個別のレイヤーを整理および維持するのが難しくなります。

私の質問は、これは現代のウェブサイトで回避できますか?

私がフロントエンド開発に不慣れで、「正しい方法」で学習したい場合、そのような依存関係を最初から切り離して回避することを学ぶ価値はありますか?これは、より分離された構造を促進するライブラリを支持してjQueryを避けることを意味しますか?


1
そのようなことはどのように機能しますか?たとえば、ページ上のコントロールを実際に何らかの方法で触った​​り、知識を持たずに無効にするにはどうすればよいですか?(これは、たとえたとえそれらが不自然であったとしても、理想的にはいくつかの例で分離することによってあなたが何を意味するかについて、より具体的にする必要があると言う私の小さな方法です)。
ロバートハーヴェイ14年

2
html、css、jsの分離について話すとき最も重要なことは、他の代わりにクラスセレクターを使用することです。これは、oocssやBEMのような方法論の中核概念です。
アンヴィラール14年

ReactまたはWebコンポーネントを学習すれば、JSのセレクターを気にする必要はもうありません。
アンディ

回答:


35

それを避ける方法はありません。それらは相互作用するため、結合されています。JavaScriptが何らかの種類のDOM操作を実行する場合は、DOMを参照する方法が必要です。

それにはさまざまな規則があります。

レベル2 DOM APIは、getElementById、getElementByTagName、およびgetElementsByNameメソッドを提供します。今日まで、これらはあらゆる種類のDOMトラバーサルの主力製品です。他のすべての手の込んだjQueryセレクターは、最終的にこれらの組み合わせに解決されるか、各DOMノードの真っ直ぐなトラバース(これがgetByClassNameを行う方法でした)。

他のショートカットはありません。Javascriptは何をどこで行うかを知る必要があります。通常、スクリプトにのみ関連するidまたはクラスが要素にある場合、多くの人がそれに接頭辞js-または他の明らかなフラグを付けます。

もう1つの新しい規則は、データ属性の選択です。

<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 UIなど)がそれらを広範囲に使用しています。問題を回避するために、ネームスペースやその他の規則を厳しくする必要があります。HTMLをJSから切り離すのに役立ちますが、必ずしもデバッグが簡単になるとは限りません。
mastaBlasta 14年

クラス、ID、およびデータ属性をフックおよび状態フラグとして使用する必要がある理由を、再発明する必要はありませんでした。その点でAngularはすべてパフォーマンスの低下を達成し、広く知られている/理解されている慣習を新しい方法に置き換えました。大きな学習曲線はありません。それはただ遅く、完全に合理的で一般的に知られている慣習と完全に不要なIMOに反しています。
エリックReppen

9

取得する対話性を無視する場合は、Javascriptを完全に回避できます。ASP.NET MVCのようなフレームワークは、HTML、CSS、および[送信]ボタンのみを含むページの提供に非常に適しています。

OK。多分それは少し極端です。

Webアプリケーションでの分離は、多くのレベルですでに発生しています。RESTアプリケーションを使用すると、URLに関連付けられた「Webリソース」の観点からアプリケーションを定義できます。ビューモデルを使用すると、ドメインモデルから切り離されたUIにデータを表示できますが、適切に表示するために必要な形状を持っています。サービスレイヤーを使用すると、1つのUIを別のUIと交換できます。

歴史的に、双方向性と結合の間には常にトレードオフがありました。Webページがよりインタラクティブになればなるほど、アプリケーションと密接に結び付きます。ただし、Webページの対話性ロジックはWebページ自体に限定されます。サーバーとのカップリングは、POSTまたはAJAXのいずれかを介して発生します。したがって、ブラウザとサーバーの間でデータパケットが渡される方法に注意を払う以外に、Javascriptレベルでのカップリングについて過度に懸念すべきかどうかはわかりません。

最も「現代的な」アプローチ(つまり、今週の風味)は、おそらくSPAアプリケーションです


私には極端に聞こえません。JavaScriptを広範囲に使用している多くのサイトは、JavaScriptなしでは使用できないという点で、実際には必要ありません。彼らの開発者はもっと手掛かりを持っていたでしょうか?
マイケルハンプトン14年

5

Martin Fowlerは、これへのアプローチの1つとして、ページロジックJavaScriptからDOM JavaScriptを分離するSegregated DOMについて説明しています。

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

1
+1 JavaScript <-> DOMロジックを分離することに完全に同意します。データ属性はDOMに関連しているのではなく、外部ツールに関連しているため、私はデータ属性が本当に好きではありません。より明確なアプローチは、ある種のマッピングを持つことだと思います。はい、これは、たとえば、JSが取得するいくつかの参照を含むDOM(「単一アスペクト」 ')。ただし、思慮深く行われた場合、これは非常に保守性が高く、再利用可能であり、データ属性よりも懸念をよりよく分離できます。
awj 14年

2

いいえ、クラス、要素、およびIDセレクターをクライアント側で使用することは避けてください。 CSSセレクターは非常に成熟し、確立されたドメイン言語であるため、構文が使用されます。また、共通のデザインを使用すると、プログラムとデザイン間でページの共通の論理モデルをはるかに簡単に共有できます。これは非常に良いことです。

この構文を誤って使用し、ひどく保守不能なアプリケーションを作成することは可能ですが、言語やツールセットに関係なく可能です。


2
実際、クラス、要素、およびIDセレクターをさまざまなことに使用することはお勧めし[data-*]ません。代わりに、非常に強力な方法で使用できるカスタム属性セレクターの使用に焦点を当てます。
zzzzBov 14年

2
特に、セレクターを前提としないモジュラー/再利用可能なJSの作成に関しては、私の頭の中のアドバイスは不十分です。これらのシナリオでは、データ属性の方が適しています。
ロンドンのファーガス14年

3
@zzzzBov-それは微最適化であることは知っていますが、IDとクラスのルックアップはデータ属性のルックアップよりもはるかに高速です。しかし、はい、異なる懸念を処理するために異なる属性セットを使用するというアイデアが好きです。
ジミーブレックマッキー14年

0

誰かは、domへのインダイレクションおよびキャッシュレイヤー用の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({});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.