- ベストアンサー
HTML:Tableタグに対し、JavaScriptで動的にイベントを追加する方法
- HTMLのTableタグにJavaScriptで動的にイベントを追加する方法について説明します。
- 特にダブルクリックイベントを実行する際に、クリックイベントまで発動してしまう問題について解決策を提案します。
- 例を挙げながら、適切なイベントのattachEvent方法を使用することで、ダブルクリック時にはダブルクリックイベントのみ実行されるように設定する方法を説明します。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
作ってみました。 click, dblclick イベントを排他的に扱う - jsdo.it http://jsdo.it/think49/o3aq ・クリック 一定時間(600ミリ秒)後にクリック処理する ・ダブルクリック 即座にダブルクリック処理する (クリック処理は行わない) ・トリプルクリック ダブルクリック処理する。(ダブルクリック後、一定時間(600ミリ秒)は入力を受け付けない) > ダブルクリックイベントハンドラが終了するまでは、クリックイベントを検知する機構を無効にしているみたいですね。 この動作だけではトリプルクリックで「ダブルクリック処理 → クリック処理」となることを防げなかった(ダブルクリック処理がすぐに終わってしまう)ので、ダブルクリック処理後、一定時間入力を受け付けないようにしました。
その他の回答 (5)
- babu_baboo
- ベストアンサー率51% (268/525)
しんぐるでも、とりぷるでも、それいじょうでも、いけるかもしんないじょ! ぜんかくくうはくは、はんかくにしてちょ! <!DOCTYPE html> <title></title> <body> <table id="hoge" border="1"> <tr> <td>Click Test </table> <script> //@cc_on var ClickListener = function ( interval /* ,Function1, Function2, .. */ ) { var functionList = arguments; //? var timerId, counter; var that = this; this.listener = function ( evt ) { var cbFunc, func; if (timerId) { clearTimeout (timerId); timerId = null; counter++; } if (func = functionList[ counter ]) { cbFunc = (function (f, e, t) { return function ( ) { t.reset (); f.call (null, e); }; })(func, evt, that); timerId = setTimeout (cbFunc, interval); } else that.reset(); }; this.reset = function ( ) { timerId = null; counter = 1; }; this.reset(); }; //___ var fuga = new ClickListener (400, function (e) { alert("1 click! " + e.type); }, function (e) { alert("2 click! " + e.type); }, function (e) { alert("3 click! " + e.type); }); //___ document.getElementById('hoge'). /*@if (@_jscript_version > 5.8) addEventListener( @elif (@_jscript_version <= 5.8) attachEvent( 'on'+ @else@*/ addEventListener( /*@end@*/ 'click', fuga.listener, false); </script>
- fujillin
- ベストアンサー率61% (1594/2576)
#1です。 手元にIE6しかないので、それ以上のバージョンは確認できないのですが… トリプルクリック時のイベントの発生の仕方 IE6 : click dblclick click fx3.5 : click click dblclick click となって、2回目のクリック時にIEではdblclcikのみ、fxはclickとdblclickが発生するという仕様の違いがあるみたい。(IE8は不明) fxのような仕様であれば、dblclickは監視しなくてもclickのみの監視でできそうだと思っていたのですが、そうは問屋がおろさないというのがいつもながらのIEということなのかな? 試みにサンプルを作成してみました。 どのような処理の使い分けをなさるつもりかわかりませんが、ユーザのミスクリックで違うクリックをしてしまうことがあるので、その辺の冗長性を用意しておくことも必要な気がします。 (サンプルでは遅延時間約0.6秒。長いほど正しく判定はできるけれど…) <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="ja"> <head><title>test</title> <meta http-equiv="Content-Script-Type" content="text/javascript"> </head> <body> <table id="table01"> <tr><td> <input type="button" value="click for test"> </td></tr> </table> <hr><div id="memo"></div> <script type="text/javascript"> <!-- (function() { var buffer = [], interval = 600; // 遅延時間 約0.6秒 var t = document.getElementById("table01"); /*@cc_on@if(1) t.attachEvent('onclick', clickListener); t.attachEvent('ondblclick', clickListener); @else*/ t.addEventListener('click', clickListener, false); t.addEventListener('dblclick', clickListener, false); /*@end@*/ function clickListener(evt) { if (evt.type == "click") { //イベント処理を終了するため必要なデータを一時保存 buffer.push(evt.target || evt.srcElement); setTimeout( function() { if (buffer.length) singlClickProcess(buffer.shift()); }, interval); } else { buffer = []; doubleClickProcess(evt); } } function singlClickProcess() { document.getElementById("memo").innerHTML += "SingleClickProcess\<br\>"; } function doubleClickProcess() { document.getElementById("memo").innerHTML += "DoubleClickProcess\<br\>"; } })(); //--> </script> </body> </html>
- think49
- ベストアンサー率59% (285/482)
> また、単純にスタックする方法だとトリプルクリックされると、ダブルクリック+シングルクリック となってシングルクリックだけとして認識してしまう可能性がありますね。 Windows Explorer で実験してみたところ、トリプルクリックはダブルクリックと等価の動作をするようです。 ダブルクリックイベントハンドラが終了するまでは、クリックイベントを検知する機構を無効にしているみたいですね。 フォームコントロールのボタンにはdisable属性が定義されていますが、table (tdかな?) にも同様の属性を定義すればいけそうです。 WAI-ARIA の aria-selected属性、aria-disabled属性、aria-busy属性 を使い分けるとして、ダブルクリック処理中は aria-busy属性 が適当でしょうか。 http://www.hitachi.co.jp/universaldesign/wai-aria/wd_20090224/#aria-busy
- think49
- ベストアンサー率59% (285/482)
「DOM L3 Events」には UIEvent.detail がありますが、ダブルクリックで click が発動してしまうのは変わらないので意図に沿わないですね。 なにより、IE8 が UIEvent.detail に対応していませんし…。 (※以下、全角空白は半角空白に置換してください) <script type="text/javascript"> function clickListener (event) { console.log(event.type + ': ' + event.detail); // クリック回数を出力 } if (document.addEventListener) { document.addEventListener('click', clickListener, false); document.addEventListener('dblclick', clickListener, false); } else if (document.attachEvent) { document.attachEvent('onclick', clickListener); document.attachEvent('ondblclick', clickListener); } </script> dblclick - DOM L3 Events http://www.w3.org/TR/DOM-Level-3-Events/#event-type-dblclick UIEvent - DOM L3 Events http://www.w3.org/TR/DOM-Level-3-Events/#events-Events-UIEvent これが期待通りに動作したら、clickイベントは dblclick が発動するまで待ってから発動する仕様でなければならないので、理解できる動作ではありますが…。 > ダブルクリックしたときは、ondblclickのみ実行されるようにするにはどうしたらよいでしょうか。 クリック回数以外に実行条件に違いはありませんか? あれば、それを使いますし、なければ fujillinさん の仰る方法しか思いつきません。 dblclick を設定せず、click のみでダブルクリックイベントを判定すればいいと思います。 click を検知後、一定時間後に click が発生すれば dblclick として判断し、click が発生しなければ click と判断します。 一般にお年を召した方はダブルクリックのインターバルが長い傾向にあるので、可能ならばダブルクリックと判断するまでの時間をユーザが設定できるといいですね。
- fujillin
- ベストアンサー率61% (1594/2576)
確かに両方発生するみたいですね。 イベント発生時にすぐに処理をしないで、発生したことをスタックしておいて、setTimeoutなどでタイムラグをおいてから判別して処理をするようにすれば一応判定ができそう。 ただし、ダブルクリックの間隔はユーザーが設定できるので、どのくらいのタイムラグをおくかが難しそうですね。(0.2~0.4秒くらいかな~という感じではありましたが…) 短すぎると、ダブルクリックしているのに認識されないことが起こりうるし、あまり時間を長くすると処理のレスポンスが悪くなるだけだし… また、単純にスタックする方法だとトリプルクリックされると、ダブルクリック+シングルクリック となってシングルクリックだけとして認識してしまう可能性がありますね。 スタックの方法をを工夫すれば、これは回避できるかもしれませんが…
お礼
think49さんサンプルありがとうございました。違和感なく実現できそうですありがとうございました。 ほかの皆様も情報ありがとうございました。希望通り実現できそうですご協力に感謝いたします。