プロが教えるわが家の防犯対策術!

HTML:Tableタグに対し、JavaScriptで動的にイベントを追加しようとしています。
onclick / ondblclickイベントを目的のTableに対しattachEventすると、ダブルクリックの
際に、onclickイベントまで発動してしまいます。

ダブルクリックしたときは、ondblclickのみ実行されるようにするにはどうしたらよいでしょうか。

例)
<script type="text/javascript">
function click01() {...}
function dblclick01() {...}

table01.attachEvent("onclick",click01)
table01.attachEvent("ondblclick",dblclick01)
</script>
(略)
<table id="table01">
...

A 回答 (6件)

確かに両方発生するみたいですね。



イベント発生時にすぐに処理をしないで、発生したことをスタックしておいて、setTimeoutなどでタイムラグをおいてから判別して処理をするようにすれば一応判定ができそう。
ただし、ダブルクリックの間隔はユーザーが設定できるので、どのくらいのタイムラグをおくかが難しそうですね。(0.2~0.4秒くらいかな~という感じではありましたが…)
短すぎると、ダブルクリックしているのに認識されないことが起こりうるし、あまり時間を長くすると処理のレスポンスが悪くなるだけだし…

また、単純にスタックする方法だとトリプルクリックされると、ダブルクリック+シングルクリック となってシングルクリックだけとして認識してしまう可能性がありますね。
スタックの方法をを工夫すれば、これは回避できるかもしれませんが…
    • good
    • 0

「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-t …
UIEvent - DOM L3 Events
http://www.w3.org/TR/DOM-Level-3-Events/#events- …

これが期待通りに動作したら、clickイベントは dblclick が発動するまで待ってから発動する仕様でなければならないので、理解できる動作ではありますが…。

> ダブルクリックしたときは、ondblclickのみ実行されるようにするにはどうしたらよいでしょうか。
クリック回数以外に実行条件に違いはありませんか?
あれば、それを使いますし、なければ fujillinさん の仰る方法しか思いつきません。

dblclick を設定せず、click のみでダブルクリックイベントを判定すればいいと思います。
click を検知後、一定時間後に click が発生すれば dblclick として判断し、click が発生しなければ click と判断します。
一般にお年を召した方はダブルクリックのインターバルが長い傾向にあるので、可能ならばダブルクリックと判断するまでの時間をユーザが設定できるといいですね。
    • good
    • 0

> また、単純にスタックする方法だとトリプルクリックされると、ダブルクリック+シングルクリック となってシングルクリックだけとして認識してしまう可能性がありますね。


Windows Explorer で実験してみたところ、トリプルクリックはダブルクリックと等価の動作をするようです。
ダブルクリックイベントハンドラが終了するまでは、クリックイベントを検知する機構を無効にしているみたいですね。

フォームコントロールのボタンにはdisable属性が定義されていますが、table (tdかな?) にも同様の属性を定義すればいけそうです。
WAI-ARIA の aria-selected属性、aria-disabled属性、aria-busy属性 を使い分けるとして、ダブルクリック処理中は aria-busy属性 が適当でしょうか。
http://www.hitachi.co.jp/universaldesign/wai-ari …
    • good
    • 0

#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>
    • good
    • 0

しんぐるでも、とりぷるでも、それいじょうでも、いけるかもしんないじょ!


ぜんかくくうはくは、はんかくにしてちょ!

<!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>
    • good
    • 0

作ってみました。



click, dblclick イベントを排他的に扱う - jsdo.it
http://jsdo.it/think49/o3aq

・クリック
一定時間(600ミリ秒)後にクリック処理する

・ダブルクリック
即座にダブルクリック処理する (クリック処理は行わない)

・トリプルクリック
ダブルクリック処理する。(ダブルクリック後、一定時間(600ミリ秒)は入力を受け付けない)

> ダブルクリックイベントハンドラが終了するまでは、クリックイベントを検知する機構を無効にしているみたいですね。
この動作だけではトリプルクリックで「ダブルクリック処理 → クリック処理」となることを防げなかった(ダブルクリック処理がすぐに終わってしまう)ので、ダブルクリック処理後、一定時間入力を受け付けないようにしました。
    • good
    • 0
この回答へのお礼

think49さんサンプルありがとうございました。違和感なく実現できそうですありがとうございました。


ほかの皆様も情報ありがとうございました。希望通り実現できそうですご協力に感謝いたします。

お礼日時:2010/07/31 23:59

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!