JAMADAM.COM

RSS Subscribe to my RSS feed

Stripe Calendar

Sep, 2010
Aug 1516171819202122232425262728293031 Sep 123456789

Entry: jQueryでCtrl + 左クリック

jQueryでCtrl + 左クリック

Initial post: 2009.06.05 | Last modified: 2009.06.05

ブログのリンクを、Ctrl + 左クリックのときはjavascriptで処理しないように変更した。event.metakeyでmacのコマンドキーにも対応。

$(selector).live('click', function(event) {
    
    // jQueryのliveメソッドと右クリックにまつわるバグを回避
    if (event.which != undefined && event.which != 1) {return}
    
    // Ctrl+左クリックの場合はキャンセル
    if (event.metaKey) {return}

    // ここに目的の処理
});

Entry: AJAXデータの取得先URLをどう管理するかという話

AJAXデータの取得先URLをどう管理するかという話

Initial post: 2009.06.01 | Last modified: 2009.06.01

AJAX満載のサイトでアンカーに紐づいたAJAXデータの取得先URLをどう管理するかという話。with jQuery1.3.2。

HTML

<a href="./path/to/parmalink.html">通常リンク</a>
<a href="./path/to/snippet.html" class="widget-opener">動的コンテンツ</a>

Javascript

$('a.widget-opener').live('click', function () {
    $.get($(this).attr('href'), function(html){
        //appendなりprependなり
    });
    
    return false;
});

上記の場合、javascriptオフの人が「動的コンテンツ」を叩くとHTMLスニペットやjsonテキストが画面いっぱいに広がるページに遷移してしまったりする。 また、検索クローラーはリンク先のページを収集してしまうかもしれない。

かといって、href="#"とでもして、すべてのアンカーにidをふって、script内でURLを関連づけていくのも煩雑だ。

HTML

<a id='id1' href="#" class="widget-opener">記事1</a>
<a id='id2' href="#" class="widget-opener">記事2</a>
<a id='id3' href="#" class="widget-opener">記事3</a>

Javascript

url.id1 = './path/to/snippet1.html';
url.id2 = './path/to/snippet2.html';
url.id3 = './path/to/snippet3.html';

そこで、アンカータグのonclickとjQueryの$.data()メソッドでAJAX URLをインラインで管理するようにしてみた。 $.data()はDOM要素に紐づいたデータを管理することが目的という、本件におあつらえ向きなメソッド。

HTML

<a href="#" class="widget-opener" onclick="$.data(this, 'ajaxURL', './ajax1.html')">記事1</a>
<a href="#" class="widget-opener" onclick="$.data(this, 'ajaxURL', './ajax3.html')">記事2</a>
<a href="#" class="widget-opener" onclick="$.data(this, 'ajaxURL', './ajax3.html')">記事3</a>

Javascript

$('a.widget-opener').live('click', function () {
    $.get($.data(this, 'ajaxURL'), function(html){
        //appendなりprependなり
    });
    
    return false;
});

onclickとliveでバインドしたイベントとの実行順が気になったけど、意図した順番に実行されている。ここで念のためonmousedownとかに逃げてしまうと、 今度は.trigger()が使えなくなってしまうのでonclickしかない。実行順が覆るケースがあるようなら、click.not_inlineというようにnamespacedイベントを利用して onclickイベントとの実行順を制御することもできる。

また、パーマリンクが存在するアンカーであれば、当然hrefにそれをかける。

<a href='./parmalink1.html' class="widget-opener" onclick="$.data(this, 'ajaxURL', './ajax1.html')">記事</a>

こうすることで、新規タブでリンクを開く可能性に配慮した仕組みも実現できる。実際、このブログの「最近の記事」のボタンは左クリックで新規ウィジェットを起動するけど、コンテキストメニューから新規タブでパーマリンクを開くこともできる。そして、この2つのURLをひとつのアンカータグ内で管理している。

まあ、HTML内に書くのには$.data()はちょっとだけ汚らしいというのは認める。

Entry: jQueryの.live()が右クリックに反応してしまう現象の回避方法(改)

jQueryの.live()が右クリックに反応してしまう現象の回避方法(改)

Initial post: 2009.05.31 | Last modified: 2009.06.01

.live() wrongly firing upon right click
http://www.nabble.com/.live()-wrongly-firing-upon-right-click-td22820456s27240.html

jQuery1.3.2にて。.live()にclickを指定するとき、本来なら左クリックイベントにバインドされるべきところが、右クリックなどにもbindされてしまう。なお、click以外のイベントについては未検証。

回避方法。

$(selector).live('click', function(event) {
    
    // jQueryのliveメソッドと右クリックにまつわるバグを回避
    if (event.which != undefined && event.which != 1) {return}
    
    // ここに目的の処理
});

event.whichは1のとき左クリック、2, 3はそれぞれ中央と右。らしい。

[追記] .trigger('click')したときにはevent.whichはセットされない。なのでevent.which != undefinedが必要かもしれない

[追記] return falseじゃなかったね。単にreturnで十分。ちなみにこのバグ全体はFirefoxのみの現象らしい。