pjaxによる画面遷移ではユーザースクリプトが新しく呼び出されない。ここでは、GitHubでpjaxによる画面遷移が発生したことをユーザースクリプト側で検知する方法をいくつか紹介する。Chrome Extensionなどのブラウザ拡張を書くときにも参考になるかもしれない。
URLをポーリングする
setInterval
などで定期的にURLを確認することでpjaxによる画面遷移が検知できる。
URLが変更されたときに発生するイベントはないようだ1。
MutationObserverでDOMの変更を検知する
おそらく一番まっとうな方法。かつてはDOMの変更検知にはDOMNodeInsertedをはじめとするmutation eventsが使われていたが、現在は非推奨になっていて、代わりにMutationObserverが提供されている。
使用例など
- github-linker/injection: GitHub Linkerのコンポーネントの一つ。npmとbowerのパッケージとして提供されている。
- app.js · kyanny/chrome-ext-wip-pull-request-unhighlighter-for-github(Chrome Extension)
- inject.js · NARKOZ/crank-for-rubygems(Chrome Extension)
- github-userscripts/refer-issue-when-creating.user.js(ユーザースクリプト)
独自イベントを取得する
どこでも使える方法ではないが、サイト側のJavaScriptで独自にイベントが発行されていることがある。
GitHubではpjaxの実装にdefunkt/jquery-pjaxを使っているので2、pjax処理の過程でpjax:success
などのイベントがjQueryを使って発火される。
jQueryから発行されるイベントの名前に:
が含まれる場合、vanilla JSから取得することはできないので、何らかの方法でコンテンツと同じコンテキストでJavaScriptを実行する必要がある。
GitHubではCSPで'unsafe-inline'
が設定されているため、Location hackやContent Script Injectionは使えない。unsafeWindow
からjQueryを呼び出してイベントハンドラを設定する以外の方法はないのではないかと思う。
使用例など
-
history.popState()
が実行されたときに発生するPopStateEvent、hash fragmentが変更されたときに発生するHashChangeEventなどはある。 ↩ -
将来的にはgithub/pjaxに置き換えられそう。 ↩