Jul 25, 2005
ホイール回転でAmazonのカートを少し便利にする
今、Amazon最速検索の改良バージョンを作っているのだが、Amazonはカートに入れるのは簡単なのにカートから削除するのとかがとても面倒くさい。そんなわけなのでホイール回転で注文数を変更できるようにするBookmarkletを書いてみた。input type=textで、かつ、数値が入っている入力ボックス上でホイールを回転させると数値を変更できる。IEとFirefox兼用、他のブラウザはホイールを使えないので無理。ホイールマウスを持っていない人が切なくなるが、持ってる人が便利なのに越したことはない。
こんな感じで動く。
http://la.ma.la/misc/demo/amazonwheel.htm
Bookmarklet
ホイールで数量変更
Greasemonkeyスクリプトにしてみた。内容は同じ。
http://la.ma.la/misc/userjs/AmazonCartHelper.user.js
Amazonのカートを想定して作ったけれど、日付を入れるようなボックスとか、他にも何かと使い回しが利くはず。逆に言うと、こういう改良が利くので日付を入れるようなボックスはプルダウンメニューではなくて、普通のテキストボックスの方が良いと思う。
----
技術的な解説。
改行抜きで見づらいが、短いのでまあいいか。
javascript:(function(){var inp=document.getElementsByTagName("input");for(var i=0;i<inp.length;i++){var c=inp[i];if(c.type=="text"&&c.value!=""&&!isNaN(c.value)){var mkfunc=function(t){return function(e){var ct=e.wheelDelta||(e.preventDefault(),-e.detail);ct<0?t.value++:(t.value>0)?t.value--:0;return false}};var func=mkfunc(c);c.attachEvent?c.attachEvent("onmousewheel",func):c.addEventListener("DOMMouseScroll",func,false);}}})();
mkfuncが関数を返す関数で、現在のループ中で選択されているinputボックスへの参照を残している。例えば対象となるinput要素が10000個あったら別々の「無名関数」が10000個できる、といった具合。クロージャというらしいですが綴りがよくわからないので、いつも関数を作るということでmkfuncとかそういう名前を使ってます。
逆に、変数に「名前付きの」関数を代入してやるとうまくいかない。
javascript:(function(){var inp=document.getElementsByTagName("input");for(var i=0;i<inp.length;i++){var n=inp[i];if(n.type=="text"&&n.value!=""&&!isNaN(n.value)){var c=n;var func=function(e){var ct=e.wheelDelta||(e.preventDefault(),-e.detail);ct<0?c.value++:(c.value>0)?c.value--:0;return false};c.attachEvent?c.attachEvent("onmousewheel",func):c.addEventListener("DOMMouseScroll",func,false);}}})();これは少し変わった動作をする。funcが「同じ関数」を参照してしまい、その関数内で使われている変数の参照先がループによって上書きされる。具体的には一番最後のinputボックスの数値が変化するようになる。
つまりこうなる。
http://la.ma.la/misc/demo/scopechain.htm
ちょっとした神秘だ。
別にクロージャを使わなくても同等のことは出来て、IE用のe.srcElementとFirefox用のe.targetを関数内で分岐させれば良い。
javascript:(function(){var inp=document.getElementsByTagName("input");for(var i=0;i<inp.length;i++){var c=inp[i];if(c.type=="text"&&c.value!=""&&!isNaN(c.value)){var func=function(e){var t=e.srcElement||e.target;var ct=e.wheelDelta||(e.preventDefault(),-e.detail);ct<0?t.value++:(t.value>0)?t.value--:0;return false};c.attachEvent?c.attachEvent("onmousewheel",func):c.addEventListener("DOMMouseScroll",func,false);}}})();
こっちの方が普通だし、メモリにもやさしい。ようするにクロージャとかカッコいい言葉を使ってみたかっただけだ。
----
まあ、こんなことはどうでも良くて、たかだか500byteでユーザビリティを劇的に改善することが出来るのだということをあなた方は知らなさ過ぎるのです。
Edit this entry...
wikieditish message: Ready to edit this entry.
A quick preview will be rendered here when you click "Preview" button.