ブックマークレット用の信頼できるlocalStorage

拡張機能とは異なり、 ブックマークレットはシンプルさとブラウザー間の互換性に適しています 。 もちろん、ウィンドウコンテキスト(ページコンテンツ)によって制限されますが、多くの場合これで十分です。 また、 localStorage



メカニズムの出現により、クライアント側でデータを保存およびクエリする簡単な方法が得られました。



たとえば、このようなシンプルなブックマークレットを使用して、一度に読むことができない長い記事の場所に中間の「ブックマーク」を保存します。



 javascript:(function(d, scrT){ scrT = d.documentElement.scrollTop || d.body.scrollTop; if (scrT) { localStorage['bmk_' + d.location.href] = scrT; } else { scrollTo(0, localStorage['bmk_' + d.location.href] || 0); } })(document)
      
      





同じブックマークレットは、読書場所の保存と切り替えの両方に同時に機能します。 ページがロードされたばかりの場合、またはスクロールの初期状態(たとえば、 Home



キーが押された状態)の場合、ブックマークレットは以前に保存された場所に移動する必要があると想定し、 localStorage



から抽出してページにスクロールします。 ページがすでにスクロールされている場合、ブックマークレットはスクロールの現在の状態を保存します。



モニターのサイズと解像度、ブラウザーウィンドウのサイズ、およびそのメイン部分(サイドバーとツールバーを除く)のサイズが変わらない場合、ページスケールとそのメイン構造は変わりません-プログラムは時計のように動作します。 つまり、ほとんどの場合、そのシンプルさが信頼できます。



ただし、サイトではlocalStorage



扱いがlocalStorage



ます。 まったく使用しない人もいます。 積極的に使用する人もいますが、自分で作成または変更したキー(Twitterなど)のみを使用します。 しかし、絶対的な君主がいます:たとえば、FacebookはlocalStorage



定期的に完全にクリアし、おそらくlocalStorage.clear()



メソッドをlocalStorage.clear()



。 もちろん、最後のタイプのサイトを非難することは何もありません-彼らはこのエリアの主権者であり、部外者が彼らの財産を使いたいかもしれないという事実を考慮する義務はありません。



そのような場合に自分を守る方法は? もちろん、 IndexedDB



切り替える(サイトが再びクリアしない場合)か、拡張機能を作成することができます(Google ChromeはlocalStorage



を拡張機能に割り当てますlocalStorage



はこれを許可しませんが、共通設定データベースにデータを保存する独自の方法を提供します)-これはそのためだけですこのような複雑なツールを使用するのはあまり便利ではありません。



残念ながら、ページの内部フレームに属するlocalStorage



を使用することはできません(見つかった場合)。これにより、同じソースの原則を実行できなくなります



ただし、解決策があります-一見、扱いにくいですが、実際にはすべてを一度設定して、あらゆる場面でテンプレートを用意しておけば、非常に簡単で便利です。



Window.postMessage



テクノロジーが役立ちます。 次のような小さなWebページを作成するだけです。



 <!doctype html> <html> <head><meta charset="UTF-8"><title></title> <script> function processMessage(event) { if (event.data.action == 'get') { event.source.postMessage(localStorage[event.data.key], event.origin); } else { localStorage[event.data.key] = event.data.value; } } window.addEventListener('message', processMessage, false); </script> </head> <body></body> </html>
      
      





次に、 http:



およびhttps:



プロトコルをサポートするホスティング(たとえば、すべての登録ユーザーがアクセスできるGitHub Pagesなど)に配置します。 その後、このページを任意のドキュメントの内部フレームとして埋め込み、ブックマークレットが機能するコンテキストでメインドキュメントウィンドウから通信を確立localStorage



このページ自体のブックマークレットとlocalStorage



間のプロキシサーバーとして、つまり小さなサーバーのように使用できますデータベース



残念ながら、セキュリティ上の制限により、これらのニーズに合わせてローカルページを埋め込むことはできませんが、そのような小さなページの読み込みは、キャッシュされていなくても完全に見えません。



新しいメソッドのためにブックマークレットを作り直すことは残っています。 もちろん、サイズは9行からほぼ40行(判読可能なフォーマット)に増加しますが、それでもコードは非常に単純なままです。 ユーザーのブックマークレットの操作はまったく変更されません。



 javascript:(function(d, mySt, scrT){ scrT = d.documentElement.scrollTop || d.body.scrollTop; mySt.origin = d.location.protocol + '//user.github.io'; mySt.URL = mySt.origin + '/storage/storage.html'; mySt.iframe = d.querySelector('iframe#myStorageIframe'); if (mySt.iframe) { mySt.iframe.contentWindow.postMessage( scrT ? {'action': 'set', 'key': 'bmk_' + d.location.href, 'value': scrT} : {'action': 'get', 'key': 'bmk_' + d.location.href}, mySt.origin ); } else { function processMessage(event) { if (event.origin == mySt.origin) { scrollTo(0, event.data || 0); } } addEventListener('message', processMessage, false); mySt.iframe = d.body.appendChild(d.createElement('iframe')); mySt.iframe.style.display = 'none'; mySt.iframe.id = 'myStorageIframe'; mySt.iframe.src = mySt.URL; mySt.iframe.addEventListener('load', function() { mySt.iframe.contentWindow.postMessage( scrT ? {'action': 'set', 'key': 'bmk_' + d.location.href, 'value': scrT} : {'action': 'get', 'key': 'bmk_' + d.location.href}, mySt.origin ); }); } })(document, {})
      
      





主な原則は同じままです。ブックマークレットはスクロールの状態を分析し、初期位置ではブックマークを抽出してそれに沿って移動し、スクロールの中間位置では状態を保存します。



変更点は次のとおりです。



最初に、ブックマークレットは3つのプロパティを持つサービスオブジェクトmySt



(myStorage)を作成します:origin-宛先のソース、 URL



(前のプロパティに基づいて)に必要な情報をインターフェイスに提供する-フレームを完全なアドレスに設定する、 iframe



フレーム自体にリンクする https:



プロトコルのページでは通常のプロトコルのページを埋め込むことができないため、最初の段階で現在のプロトコルを決定し、それに応じて、 origin



URL



プロパティを形成しURL



(無効な条件付きURLの例では、「ユーザー」をページがこのサイトに配置されている場合は、実際のユーザー名)。



その後、ブックマークレットは、中間ページが既に組み込まれているかどうかを確認します(この記事をしばらく読んでウィンドウを閉じずにブックマークを保存した場合、念のためまたは一時的に不在の場合、フレームが既に組み込まれている可能性があり、挿入を繰り返す必要があります)。 ページが組み込まれている場合、すぐに通信に進みます。保存するキーと値を送信するか、以前に保存したキーの値を要求します。 通信は非同期に行われるため、これ以上行うことはありません。値を要求しても、フレームを埋め込んだときにハングしたハンドラーが応答を取得します(以下を参照)。



フレームがない場合は、次の手順を実行します。



1.将来のために、将来の中間ウィンドウの応答ハンドラーをメイン文書に添付します。

2.干渉しないように、ウィンドウ自体に組み込み、非表示にします。

3.プロキシの準備ができたら、中間ウィンドウに1回限りのダウンロードハンドラーを置いて通信を開始します。 このハンドラーでは、既製の中間ページが検出されると、前述のケースと同じアクションを実行します。



コードは、標準、ライブラリの汎用性、清潔さを主張するものではなく、私はプロのプログラマーではありません。 したがって、修正や警告をいただければ幸いです。



それまでの間、ブックマークレットの動作はFirefox(Nightly)、Google Chrome(Canary)、Internet Explorer(11)の最新バージョンで正常にテストされています。



All Articles