英語原文:The seven rules of Unobtrusive JavaScript
元のアドレス: http://icant.co.uk/articles/seven-rules-of-unobtrusive-javascript/
原作者: クリス・ハイルマン
翻訳アドレス: http://www.zhuoqun.net/html/y2008/1103.html
前に書いた: kejun が少し前に私たちに JavaScript をトレーニングしていたとき、彼はこの 1 つの記事を含む多くの古典的な記事をスライドで推奨しました。読んだ後はとても良い気分になりますが、記事を深く理解できないことがよくあり、たまたまこの記事の中国語版が見つからなかったので、それを翻訳することを思いつきました。共有して理解が深まると思います。この記事の著者 Chris Heilmann は Yahoo! の英国人エンジニア (Kejun によれば「ゴッドファーザー」のような存在) であり、この記事の翻訳も彼の承認を受けています。
もう一つ、私はこれまでにたくさんの翻訳をしてきましたが、その時は翻訳のための翻訳が多く、専門的な記事は理解できないことが多く、今に至るまで翻訳者を続けています。今後もいくつかの記事を翻訳していきますが、慎重に理解する必要がある古典的な記事のみを翻訳する必要があります。時間があれば、さらにコードを書くことをお勧めします。
用語の翻訳: 「目立たない JavaScript」という用語については、特に適切な翻訳が思いつきません。ネットで調べてみると、「控えめなJavaScript」と訳されているものもあれば、「非侵入型JavaScript」と訳されているものもあり、台湾では「侵入しないJavaScript」と訳されているものもあり…いろいろ調べた結果、私は「no intrusive JavaScript」を使用することにしました。この翻訳は「邪魔な JavaScript」です(これはまだ私にはあまり適していませんが)、詳しくはこの記事を参照してください。実際、「目立たない JavaScript」には多くの意味が含まれており、一言でまとめるのは難しいので、興味のある方は Wikipedia の「目立たない JavaScript」の説明をご覧ください。なお、翻訳とは著者の意図を表現するものであり、必ずしも一字一句訳す必要はないと考えますので、読者の理解を容易にするために、記事中で一部削除したり追加したりしていますが、これらは以上です。元のテキストの意味を損なうことなく、基づいて実行されます。
もう一つ注意点があって、私の翻訳能力は素人なので、間違いがあるかもしれませんので、ご指摘をお願いします。
目立たない JavaScript を何年も開発、指導、作成してきた結果、私は次のガイドラインを発見しました。この方法で JavaScript を設計して実行する方が良い理由を少しでも理解していただければ幸いです。これらのルールにより、製品をより迅速に、より高品質で、メンテナンスが容易に提供できるようになりました。
1. いかなる仮定もしないでください (JavaScript は信頼性の低いアシスタントです)
おそらく、目立たない JavaScript の最も重要な特徴は、いかなる仮定もするのをやめなければならないことです。JavaScript
が利用可能であると仮定しないでください。可能であると考えたほうがよいでしょう。直接依存するのではなく、利用できません。
メソッドとプロパティをテストして機能することを確認するまで、ブラウザーがメソッドとプロパティをサポートしていると想定しないでください。
HTML コードが思ったほど正しいとは考えず、毎回チェックして、利用できない場合は何もしないでください。
JavaScript 機能を入力デバイスから独立させる 他のスクリプトが JavaScript の機能に影響を与える可能性があることに注意してください。そのため、スクリプトのスコープができるだけ安全であることを確認してください。
スクリプトの設計を開始する前に、まず考慮すべきことは、スクリプトを作成する HTML コードをチェックし、目標の達成に役立つものがないかどうかを確認することです。
2. フックとノードの関係を見つける (HTML はスクリプト作成の基礎です)
スクリプトを書き始める前に、JavaScript を書きたい HTML を確認してください。 HTML が整理されていない、または不明な場合、適切なスクリプト ソリューションを用意することはほぼ不可能です。JavaScript で過剰なマークアップを作成するか、アプリケーションが JavaScript に過度に依存する可能性があります。
HTML では考慮すべき点がいくつかあります。それは、フックとノードの関係です。
<1>.HTML フック
HTML の元の最も重要なフックは ID であり、ID には最速の DOM メソッド getElementById を通じてアクセスできます。有効な HTML ドキュメント内のすべての ID が一意である場合 (IE には名前と ID に関するバグがありますが、一部の優れたライブラリはこの問題を解決します)、ID を使用することは安全で信頼性が高く、テストが簡単です。
他のフックには、HTML 要素と CSS クラスがあります。HTML 要素には getElementsByTagName メソッドを通じてアクセスできますが、CSS クラスにはほとんどのブラウザでネイティブ DOM メソッドを通じてアクセスできません。ただし、CSS クラス名にアクセスできるメソッド (getElementsByClassName と同様) を提供する外部クラス ライブラリが多数あります。
<2>.HTML ノードの関係
HTML に関するもう 1 つの興味深い点は、次の質問について考えてみましょう。DOM
のトラバースを最小限に抑えて、最も簡単にターゲット ノードに到達するにはどうすればよいでしょうか。
どのマークを変更すると、変更が必要なできるだけ多くの子ノードにアクセスできるようになりますか?
特定の要素には、別の要素に到達するために使用できるどのような属性または情報がありますか?
DOM のトラバースはリソースを大量に消費し、時間がかかるため、ブラウザですでに使用されている手法を使用して実行する必要があります。
3. 走査は専門家に任せます (CSS、DOM をより速く走査します)。DOM
をスクリプト化し、メソッドまたはプロパティ (getElementsByTagName、nextSibling、previousSibling、parentNode など) を使用して DOM を走査することは、多くの人を非常に混乱させるようです。 。 面白い。興味深いのは、これらのことを別のテクノロジーである CSS を通じてすでに実行していることです。
CSS は、CSS セレクターを使用してターゲット要素にアクセスし、DOM をトラバースすることでその視覚的プロパティを変更する手法です。 DOM を使用する JavaScript の複雑な部分は、CSS セレクターで置き換えることができます。
var n = document.getElementById('nav');
if(n){
var as = n.getElementsByTagName('a');
if(as.length > 0){
for(var i=0;as[i];i++){
as[i].style.color = '#369';
as[i].style.textDecoration = 'なし';
}
}
}
/* 次のコードは上記と同じ機能を持ちます*/
#nav a{
色:#369;
テキスト装飾:なし;
}
これは非常に強力なテクニックであり、有効に活用できます。これを実現するには、DOM 内の高レベルの要素にクラスを動的に追加するか、要素 ID を変更します。 DOM を使用して CSS クラスをドキュメントの本文に追加すると、デザイナーはドキュメントの静的バージョンと動的バージョンを簡単に定義できます。
JavaScript:
vardynamicClass = 'js';
var b = ドキュメント.ボディ;
b.クラス名 = b.クラス名 ? b.クラス名 + 'js' : 'js';
CSS:
/* 静的バージョン*/
#nav {
....
}
/* 動的バージョン*/
body.js #nav {
....
}
4. ブラウザーとユーザーを理解する (そして、既存の使用パターンに基づいて必要なものを構築する)
控えめな JavaScript の大部分は、ブラウザーがどのように動作するか (特にブラウザーがどのようにクラッシュするか) とユーザーが何を期待しているかを理解することです。ブラウザに関係なく、JavaScript を使用してまったく異なるインターフェイスを簡単に作成できます。ドラッグ アンド ドロップ インターフェイス、折りたたみ領域、スクロール バー、スライダーはすべて JavaScript を使用して作成できますが、この問題は単純な技術的な問題ではなく、次の点について検討する必要があります。
この新しいインターフェイスは入力デバイスから独立できるか?そうでない場合、何を信頼できますか?
作成した新しいインターフェイスはブラウザまたはその他のリッチ インターフェイスのガイドラインに従っていますか (マウスを使用して直接マルチレベル メニューを切り替えることができますか? それともタブ キーを使用する必要がありますか?)
JavaScript に依存する機能はどのようなものを提供する必要がありますか?
最後の質問は、必要に応じて DOM を使用して何もないところから HTML を作成できるため、実際には問題ではありません。この例としては、「印刷」リンクがあります。ブラウザにはドキュメントを印刷するための JavaScript 以外の機能が提供されていないため、そのようなリンクを作成するには DOM を使用する必要があります。展開および折りたたみコンテンツ モジュールを実装するクリック可能なタイトル バーにも同じことが当てはまります。タイトル バーはキーボードでアクティブにすることはできませんが、リンクはアクティブにすることができます。したがって、クリック可能なタイトル バーを作成するには、JavaScript を使用してリンクを追加する必要があります。そうすれば、キーボードを使用するすべてのユーザーがコンテンツ モジュールを折りたたんだり展開したりできるようになります。
この種の問題を解決するための優れたリソースは、デザイン パターン ライブラリです。ブラウザー内のどのものが入力デバイスに依存しないのかを知ることについては、経験の蓄積に依存します。最初に理解する必要があるのは、イベント処理メカニズムです。
5. イベントを理解する (イベント処理が変化を引き起こす)
イベント処理は、目立たない JavaScript への第 2 ステップです。重要なのは、すべてをドラッグ可能にしたり、クリック可能にしたり、インライン処理を追加したりすることではなく、イベント処理は完全に分離できるものであることを理解することです。 HTML、CSS、JavaScript は分離しましたが、イベント処理の分離はそれほど進んでいません。
イベント ハンドラーは、ドキュメント内の要素で発生する変更を監視します。イベントが発生すると、ハンドラーは素晴らしいオブジェクト (通常は e という名前のパラメーター) を見つけ、何が起こったのか、そしてそれに対して何ができるのかを要素に伝えます。 。
ほとんどのイベント処理で本当に興味深いのは、それがアクセスしたい要素だけで発生するのではなく、DOM の上位のすべての要素で発生することです (ただし、すべてのイベントがこのようになるわけではありません。フォーカス イベントとブラー イベントは例外です)。 。たとえば、この機能を使用してナビゲーション リストにイベント ハンドラーを 1 つだけ追加し、イベント ハンドラー メソッドを使用して実際にイベントをトリガーした要素を取得できます。この手法はイベント委任と呼ばれ、いくつかの利点があります。
各要素をチェックするのではなく、要素が存在するかどうかをチェックするだけで済むことです。また、対応するイベント ハンドラーを削除せずに子ノードを動的に追加または削除できることも覚えておいてください。異なる要素上の同じイベントに応答する場合、イベントが親要素に伝播するのを停止したり、HTML 要素 (リンクなど) のデフォルトの動作をオーバーライドしたりできます。ただし、ブラウザーは HTML 要素に理由があって動作を与えるため、これは良い考えではない場合があります。たとえば、リンクはページ内のターゲットを指す場合があり、リンクを変更しないでおくと、ユーザーはページの現在のスクリプト状態をブックマークすることもできます。
6. 他のもの (名前空間、スコープ、スキーマ) について考える
自分のコードがドキュメント内の唯一のスクリプト コードになることはほとんどありません。したがって、他のスクリプトによってオーバーライドされる可能性のあるグローバル関数やグローバル変数がコード内に存在しないことを確認することが特に重要です。この問題を回避するために使用できるパターンがいくつかありますが、最も基本的なパターンは、var キーワードを使用してすべての変数を初期化することです。次のスクリプトを作成するとします。
var nav = document.getElementById('nav');
関数 init(){
// 何かをする
}
関数 show(){
// 何かをする
}
関数リセット(){
// 何かをする
}
上記のコードには、nav というグローバル変数と、init、show、reset という 3 つの関数が含まれています。これらの関数は nav 変数にアクセスでき、関数名を通じて相互にアクセスできます。
var nav = document.getElementById('nav');
関数 init(){
見せる();
if(nav.className === 'show'){
リセット();
}
// 何かをする
}
関数 show(){
var c = nav.className;
// 何かをする
}
関数リセット(){
// 何かをする
}
コードをオブジェクトにカプセル化することで、上記のグローバル コーディングを回避できます。これにより、関数をオブジェクト内のメソッドに、グローバル変数をオブジェクト内のプロパティに変えることができます。 メソッドとプロパティを定義するには「名前 + コロン」メソッドを使用する必要があり、各プロパティまたはメソッドの後に区切り文字としてカンマを追加する必要があります。
var myScript = {
nav:document.getElementById('nav'),
init:function(){
// 何かをする
}、
show:function(){
// 何かをする
}、
リセット:関数(){
// 何かをする
}
}
すべてのメソッドとプロパティには、「クラス名 + ドット演算子」を使用して外部からも内部からもアクセスできます。
var myScript = {
nav:document.getElementById('nav'),
init:function(){
myScript.show();
if(myScript.nav.className === 'show'){
myScript.reset();
}
// 何かをする
}、
show:function(){
var c = myScript.nav.className;
// 何かをする
}、
リセット:関数(){
// 何かをする
}
}
このモデルの欠点は、メソッドから他のメソッドやプロパティにアクセスするたびに、先頭にオブジェクトの名前を追加する必要があり、オブジェクト内のすべての要素に外部からアクセスできることです。ドキュメント内の他のスクリプトから一部のコードにアクセスできるようにしたい場合は、次のモジュール パターンを検討してください。
var myScript = function(){
//これらはプライベートメソッドとプロパティです
var nav = document.getElementById('nav');
関数 init(){
// 何かをする
}
関数 show(){
// 何かをする
}
関数リセット(){
// 何かをする
}
//パブリック メソッドとプロパティは、オブジェクト構文を使用して return ステートメントでラップされます。
戻る {
public:function(){
}、
foo:'バー'
}
}();
返されたパブリック プロパティとメソッドには、前のコードと同じ方法 (この場合は myScript.public() と myScript.foo) にアクセスできます。しかし、ここにはもう 1 つの不快な点があります。外部からパブリック メソッドにアクセスする場合、または内部のプライベート メソッドからアクセスする場合は、依然として長い名前を記述する必要があります (オブジェクトの名前は非常に長くなる場合があります)。これを回避するには、それらをプライベートとして定義し、return ステートメントでエイリアスのみを返す必要があります。
var myScript = function(){
// これらはプライベート メソッドとプロパティです
var nav = document.getElementById('nav');
関数 init(){
// 何かをする
}
関数 show(){
// 何かをする
// 何かをする
}
関数リセット(){
// 何かをする
}
var foo = 'バー';
function public(){
}
//アクセスしたいプライベート メソッドとプロパティへのポインタのみを返します
戻る {
パブリック:パブリック、
ふー:ふー
}
}();
これにより、コード スタイルの一貫性が確保され、メソッドやプロパティにアクセスするために短いエイリアスを使用できるようになります。
メソッドやプロパティを外部に公開したくない場合は、すべてのコードを匿名メソッドにカプセル化し、その定義の直後に実行できます。
(function(){
// これらはすべてプライベートなメソッドとプロパティです
var nav = document.getElementById('nav');
関数 init(){
// 何かをする
show(); // ここではクラス名のプレフィックスは必要ありません
}
関数 show(){
// 何かをする
}
関数リセット(){
// 何かをする
}
})();
このパターンは、一度だけ実行され、他の関数に依存しないコード モジュールに最適です。
上記のルールに従うことで、コードはユーザーにとってより適切に機能し、マシン上でより適切に実行され、他の開発者のコードとより適切に連携できるようになります。ただし、考慮する必要があるグループが 1 つあります。
7. コードを引き継ぐ開発者を考慮する (メンテナンスが容易になります)
スクリプトを本当に目立たないものにするための最後のステップは、スクリプトを作成した後に再チェックし、コードが完成したらコードを引き継ぐ開発者に配慮することです。スクリプトが有効になります。次の質問について考えてみましょう。
すべての変数名と関数名は意味があり、理解しやすいものですか?
コードは適切に整理されていますか?最初から最後までスムーズに流れますか?
すべての依存関係は明らかですか?
混乱を引き起こす可能性のあるコメントが可能な限り追加されていますか?
注意すべき最も重要なことは、ドキュメント内の HTML コードと CSS コードは JavaScript よりも変更される可能性が高いことを認識することです (視覚効果を担うため)。したがって、スクリプト コードにはエンド ユーザーが参照できるクラスと ID を含めず、構成情報を保持するオブジェクトに分離します。
myscript = function(){
var config = {
ナビゲーションID:'nav',
可視クラス: '表示'
};
var nav = document.getElementById(config.navigationID);
関数 init(){
見せる();
if(nav.className === config.visibleClass){
リセット();
};
// 何かをする
};
関数 show(){
var c = nav.className;
// 何かをする
};
関数リセット(){
// 何かをする
};
}();
このようにして、管理者は他のコードを変更することなく、これらのプロパティを変更する場所を知ることができます。
詳細情報 以上
が私が発見した 7 つのガイドラインです。上記のトピックについて詳しく知りたい場合は、次のリンクを参照してください。