複数ウィンドウのスクロール、入力を同期するGreasemonkeyスクリプト(globalStorageを使った同ドメイン間のスクリプトの通信)
デモ動画:
2008-09-24_1540 - javascripter's library
// ==UserScript== // @name syncScroll // @namespace http://d.hatena.ne.jp/javascripter/ // @include http* // ==/UserScript== GM_registerMenuCommand("start demo", function(e){ syncScroll(); }); function syncScroll(){ var scrollService = new SyncService("scroll"); scrollService.addListener(function(message){ var [x, y] = eval(message); window.scrollTo(x, y); }); window.addEventListener("scroll", function(e){ scrollService.message(uneval([window.scrollX, window.scrollY])); }, false); var inputService = new SyncService("input"); inputService.addListener(function(message){ var o = eval(message); var [x, y] = o.pos; var elem = document.elementFromPoint(x, y); elem.value = o.value; }); window.addEventListener("input", function(e){ var elem = e.target; var pos = elem.getBoundingClientRect(); inputService.message(uneval({pos: [pos.left, pos.top], value: elem.value})); }, false); } function SyncService(uname){ this._uname = "SyncService" + uname; this._listeners = []; this._lastItem = null; this._listen(); } SyncService.prototype.addListener = function(fn){ this._listeners.push(fn); }; SyncService.prototype.removeListener = function(fn){ this._listeners.splice(this._listeners.indexOf(fn), 1); }; SyncService.prototype.message = function(str){ unsafeWindow.globalStorage[location.host].setItem(this._uname, str); }; SyncService.prototype._listen = function(){ var self = this; function listener(){ var item = unsafeWindow.globalStorage[location.host].getItem(self._uname); item && (item = item.value); if (item != self._lastItem){ self._lastItem = item; self._listeners.forEach(function(fn){ fn(item); }); } } window.addEventListener("storage", listener, false); this._listener = listener; window.addEventListener("beforeunload", function(e){ window.removeEventListener("storage", listener, false); unsafeWindow.globalStorage[location.host].removeItem(self._uname); }, false); };
unsafeWindowを使ったり、JSONのパースにevalを使ったり、安全ではないので、使い終わったらオフにするかアンインストールするべき。