数ヶ月間、ブックマークレットの開発に携わり、約12冊になりました。 jQueryとネイティブJavaScriptの両方を使用しました。 どのような落とし穴に遭遇したか、私が学んだこと、そして新たに発見したことについて-これはカットの下で議論されます。
1.接続
ブックマークレットをすでに開発している人は、この点をスキップできます。残りは簡単な例です。
< a href ="javascript: (function(){var a=document.createElement('script');a.type='text/javascript';a.src='http://example.com/bookm.js?'+(new Date).getTime()/1E5;document.getElementsByTagName('head')[0].appendChild(a)})();" onclick ="alert('Drag this button to your browser\'s bookmarks toolbar or right-click it and choose Bookmark This Link.');return false;" title ="Bookmarklet Title" > < img src ="http://example.com/img/bookmarklet.gif" align ="absmiddle" alt ="Bookmarklet Title" border ="0" />
</ a >
より読みやすい形式の「Href」:
javascript: ( function () {
var a = document .createElement( 'script' );
a.type = 'text/javascript' ;
a.src = 'http://example.com/bookm.js?' + ( new Date).getTime() / 1E5;
document .getElementsByTagName( 'head' )[0].appendChild(a)
})();
ここで、<script> </ script>要素を作成し、ブックマークレットをsrcとして使用して、ページの<head> </ head>に追加します。 記録
( new Date).getTime() / 1E5
ブックマークレットの現在のバージョンに常に接続し、キャッシュしないようにすることができます。 内容を頻繁に変更しない場合は、削除できます。
このようなブックマークレットは、Chrome、Safari、FireFoxのツールバーにドラッグアンドドロップすることでドラッグアンドドロップできます。 IEの場合、コンテキストメニューでブックマークバーへの追加を選択する必要があります。
2.構造
それでは、bookm.jsの内容を見てみましょう。 一般に、ブックマークレットの作成には2つのスタイルがあります。
2.1機能的アプローチ
( function () {
try {
//
} catch (e) {
console.log(e.name + ": " + e.message);
}
}())
このアプローチの主な利点は、変数のグローバルスコープが完全にクリーンなままであり、変数で詰まらないことです。 ただし、このアプローチは、小さくシンプルなスクリプトでのみ機能します。
2.2オブジェクト指向アプローチ
function ourSuperBookmarklet() {
// , this.a = '10';
}
ourSuperBookmarklet.prototype.someOtherFunction = function (abc) {
this .a += abc;
}
ourSuperBookmarklet.prototype.start = function () {
//
this .someOtherFunction(abc);
}
try {
var __osb = new ourSuperBookmarklet();
__osb.start();
} catch (e) {
console.log(e.name + ": " + e.message);
}
もう少しわかりました。
したがって、ここでは、クラス、そのプロパティ、およびメソッドについて説明します。 次に、try-catchコンストラクトで、このクラスのインスタンスを作成し、ローダーメソッドを実行します。
この場合、SuperBookmarkletと__osbはグローバルスコープに該当しますが、これは本当に必要です(詳細は後述)。
ユーザーがアクセスしたサイトにコードが直接挿入されることを決して忘れてはなりません。ミスがページ全体を破壊する可能性があります。 try-catchはこれに少し役立ちます。 主なもの-製品版からすべてのconsole.logを削除することを忘れないでください。
3.クラスのインスタンスを操作する
この例を考えてみましょう。
ourSuperBookmarklet.prototype.start = function () {
var si = setInterval( function () {
if (something) {
clearInterval(si);
this .a++;
}
}, 500);
}
this.a-この場合、クラスのプロパティを参照します。 これはインターバル関数へのポインターになるため、このようなレコードでは何も動作しません。 これを行うことができます:
ourSuperBookmarklet.prototype.start = function () {
var th = this ;
var si = setInterval( function () {
if (something) {
clearInterval(si);
th.a++;
}
}, 500);
}
そして、それは動作します。 ただし、各メソッドで特別な変数を作成して、どこでも同じになるようにします-松葉杖のように。
よりエレガントなソリューション(IMHO!)は、次のようにクラスインスタンスを参照することです。
ourSuperBookmarklet.prototype.start = function () {
var si = setInterval( function () {
if (something) {
clearInterval(si);
__osb.a++;
}
}, 500);
}
そして、これは非常に大きなオブジェクト指向のアプローチです。 おそらくこの例はあまり説得力がありませんが、こちらをご覧ください。
ourSuperBookmarklet.prototype.someOtherFunction = function (text, obj) {
obj.innerHTML = text;
}
ourSuperBookmarklet.prototype.start = function () {
var a = document .createElement( 'div' );
a.innerHTML = 'qwerty' ;
a.setAttribute( 'ommouseover' , '__osb.someOtherFunction(\'asdf\', this);' )
document .body.appendChild(a);
}
したがって、他のスクリプト/イベントなどからクラスのメソッドとプロパティにアクセスできます。 何がいいですか。
4. AJAX
ここで私はあなたを怒らせるために急いで。 お気に入りの$ .postと$ .getはここでは機能しません。
事実、ブラウザーレベルでは、xmlHttpRequestコンポーネントは別のドメインへのアクセスを禁止されています(これはすべてのブラウザーに適用されるわけではなく、必要に応じて動作します)。詳細は
en.wikipedia.org/wiki/Same_origin_policyです。 そして、私たちのコードはユーザーが訪れたサイトの一部になるので、私たちのサイトへのアピールは別のドメインへのアピールです。
それにもかかわらず、xmlHttpRequest'omユニフォームではありません。 かつて、私自身が以下で説明する方法に着手しましたが、この方法は非常に人気があることがわかりました。
ourSuperBookmarklet.prototype.request = function (str) {
var script = document .createElement( 'script' );
script.setAttribute( 'type' , 'text/javascript' );
script.setAttribute( 'src' , str);
document .getElementsByTagName( 'head' )[0].appendChild(script);
}
すべてがシンプルで、ブックマークレットを接続する方法と非常によく似ています(冒頭を参照)。 データを転送するだけの場合。 そして、コールバックを受信したい場合は? ここでは2つのメソッドを使用しますが、どちらもJSONに関連しています。
4.1 JSONP
ウィキペディアの例を取り上げます。 オブジェクトがあります
{ "Name" : "Cheeso" , "Rank" : 7}
そして、スクリプトを使用して渡します(この場合、動的に作成されます)。
< script type ="text/javascript" src ="http://server2.example.com/getjson?jsonp=parseResponse" ></ script >
最後に、転送する必要があります
parseResponse({ "Name" : "Cheeso" , "Rank" : 7})
parseResponseは、渡されたオブジェクトを処理するブックマークレット内のコールバック関数です。 私たちの場合、それは次のようなものになります
__osb.parseResponse({ "Name" : "Cheeso" , "Rank" : 7})
4.2 JSONP、ただしPなし
すべては問題ありませんが、正しい答えを要求できなかった場合、どのようにしてわかりますか? たとえば、私たちのサイトは敷設されました。 この場合、コンストラクトを使用します。
var c = 0;
var ci = setInterval( function () {
if (__osb.getInfo) {
clearInterval(ci);
//
}
if (c > __osb.timeout) {
clearInterval(ci);
//
}
c++;
}, 1000);
ここで__osb.timeoutは、サーバーからの応答を待機する秒数です。 質問-__osb.getInfoとは何ですか?
最初に(クラスコンストラクターで)getInfoをnullとして初期化しました。 サーバーからの応答は次のようになります。
__osb.getInfo = { "Name" : "Cheeso" , "Rank" : 7}
したがって、__ osb.getInfoがnullでなくなるとすぐに、待機を停止して応答の処理を開始します。そうでない場合は、エラーメッセージを表示します。
5. JSON
JSONについて話しているので、このトピックから少し戻って、良いニュースをいくつか伝えたいと思います。 人気のあるブラウザーの最新バージョンでは、オブジェクト/文字列をエンコード/デコードできるネイティブwindow.JSONオブジェクトが登場しました。
JSON.stringifyはオブジェクトを文字列にエンコードするために使用され、JSON.parseは逆変換に使用されます。 ネイティブJSONオブジェクトは、これらの変換を手書きのソリューションよりも高速に実行します。 したがって、window.JSONオブジェクトの可用性を確認することをお勧めします。使用できない場合のみ、独自の変換ソリューションを使用してください。
結論の代わりに
例では、ネイティブJavaScriptのみを使用しましたが、ブックマークレット自体を接続する前に、お気に入りのフレームワークを接続できます。 私が通常フレームワークを使用しない理由:
- 実行速度。 頻繁に通過する必要のあるオブジェクトが多数ある場合、プロセッサ時間とメモリの問題が最初に発生します。 純粋なJavaScriptは常にフレームワークよりも高速に実行されます。 彼らはより便利ですが。
- 信頼性 DOMの操作にネイティブ関数を使用すると、スクリプトが希望どおりに機能することが保証されます。 ブラウザー間の互換性を維持するために、多くの追加コードを作成する必要があると主張するかもしれません。 目を覚ます、人々! ブックマークレットを書いている間ずっと、IEと他のブラウザー(選択したテキストを操作する)といくつかの小さなブラウザーの重大な違いを覚えています。
- CDNからの独立。 動作するには、ユーザーのブラウザだけが必要です。それで終わりです。 あなたがCDNを使用しない場合、これは深刻な議論です。使用する場合、私は少し偏執的であり、理論的にはそれらもドロップ/破損などする可能性があると言います
- ネイティブJavaScriptとDOMを学びたい。 私にとってそれは重要な理由でした;-)