• 締切済み

onclickとonkeypressの重複

W3Cのアクセシビリティ指針によれば、onclick属性を指定するならonkeypress属性も指定せよ、とのことですが、たとえば<input type="button">にこの両方を指定すると、IEなどの場合、このボタンにフォーカスがある状態でスペースキーを押すと、onkeypressイベント→onclickイベントというように両方とも発生してしまいます。 本来、ポインティングデバイスの代替の操作のためであるにもかかわらず、これでは逆にアクセシビリティは低下するばかりでなく、処理によっては2回行って欲しくない場合もあり、なんとも面倒です。 考えられる対策としては、たとえば、ほとんどのブラウザではキーでもonclickが起きるようになっているため、あえてonkeypressのほうはダミーを指定しておく、などでしょうか。 これに対してのお考えや、対策など御教授いただけたらと思います。 よろしくお願いいたします。

みんなの回答

noname#39970
noname#39970
回答No.6

うーん そうなるとやっぱりこうなるのかなぁ・・・ //------------ ck=0; kp=0; //mouse function act_m(){  if(ck<kp){kp=ck;return;}  Test01();  if(ck==kp)ck++; } //key function act_k(){  if(kp<ck){ck=kp;return;}  Test01();  if(kp==ck)kp++; } function Test01(){  //ここに処理 } //------------ でもほんとならinputはformのパーツだから、邪道っぽいかもしれないけどNo5の3つめみたいなonSubmitで処理な方がいいのかも。 >> ダミーを入れるくらいなら動作安定の為に排除 >具体的な問題などお教えいただけないでしょうか 現行のブラウザでは多分問題は起こらない。 だからと言って古いブラウザもまだ有るし新しいブラウザで大丈夫で有り続ける保証はどこにもない。 余計な処理を書いて予期せぬ動作をするかもしれないなら排除すべきである、と言ってるだけ。

taseki
質問者

お礼

う~ん…それだと今度は、片方のイベントが発生した後、もう片方のイベントが発生した場合に、やはり実行されません…。 > 余計な処理を書いて予期せぬ動作をするかもしれないなら排除すべきである、と言ってるだけ。 なるほどそう言うことでしたか。 イベントキャンセルは、ごくありきたりな処理でもあって、予期せぬ動作をする可能性も、今後サポートされなくなる見込みも、今のところ特に考えられないので、やはりとりあえずはこれが良さそうですね。

taseki
質問者

補足

※下の「お礼」欄の続き ちなみに、タイマーを使うと言う手も考えてみましたが(およそ現実的でないほど短時間に複数起動される場合は処理をキャンセルさせる方法)、しかしこれでは、キーによって「押したとき」と「離したとき」に起動される場合があり、押し方によっては結果は同じなので、やめました。

noname#39970
noname#39970
回答No.5

>すべてを適える そもそも各ブラウザが個々個々に実装をしていてW3Cに完全準拠できていないのが現状なのでどこか捨てる必要が有る。 onKeypressにダミーを入れるくらいなら動作安定の為に排除すべき。(つまり書かない) W3Cが何と言うかは別としてプログラミング的には onClickというのは onMouseDownとonMouseUpの組みなのに対して onKeypressは onKeyDownとonKeyUpの組みでは無いので等価としての処理を行うのは誤りとなる。 正しく対応するのならkeyDownで正しくオブジェクト内で入力を開始した事を認識しkeypressによって目的のキーが押されているのを確認しkeyUpによって発動すべき。 食い違いの実装が有る以上は完全に満足させるためには作成者が煩わしいコーディングをしなければならない事になる。 (ちょっと前までレイヤーを使う為にIEとNNを判別して別々の処理を書いて同じに見せる無駄が有ったのと似ている) 諦めて排除も1つの選択だと思うけど。 //--------------ボタンが「再計算」系で何度も実行される場合 flg=false; //mouse function act_m(){  if(flg){flg=false;return;}  Test01();  flg=true; } //key function act_k(){  if(flg){flg=false;return;}  Test01();  flg=true; } function Test01(){  //ここに処理 } //--------------ボタンはページ表示後1度しか使われない場合 flg=false; function Test01(){  if(flg){return;}  //ここに処理  flg=true; } //--------------邪道系 <form action="javascript:()" onSubmit="document.getElementById('EvLog').innerHTML='test';">  <input type=submit value=" TEST "> </form> <form action="javascript:()" onSubmit="document.getElementById('EvLog').innerHTML='';">  <input type=submit value=" Clear "> </form> <div id="EvLog"></div>

taseki
質問者

お礼

ご回答ありがとうございます。 ですが・・・そのロジックは、単に「2回に1回しか処理しない」というだけのような気が…。 一応、実際に試してみましたが、やはり2回のイベントに対して1回処理するだけでした。 あくまでも、必ずしもイベントが重複するわけではないので… また、act_m と act_k という同じ処理の関数を2つ作る意味もありませんし、言わばフラグはカウンターの役割ですよね?(ゼロのとき実行、1がMAXでゼロリセットする) せっかく回答いただいたのに、すみません。 > onKeypressにダミーを入れるくらいなら動作安定の為に排除すべき よろしければ、その動作不安定になるという点、具体的な問題などお教えいただけないでしょうか。

noname#39970
noname#39970
回答No.4

>マウス以外への考慮なんて、文書がやるべきではなくブラウザやOS側の役目 だからブラウザは可能なように改良されたんだと思う。 昔はボタンにtabでフォーカスする事すらできなかった。 で、考えたんだけどflagのような物を用意してそれ見て判定するのはどうかな。 ページ更新されないまま何度も呼ばれるようならonClick側とonKeypress側で1つずつ用意(例としてck、kpで表記) ・どちらの処理でも ck == kp なら続行し、処理の終りで呼ばれた方の変数をインクリメント ・しかし ck != kp なら ckとkp を同じ値にし、処理は続行せずにreturn これなら繰返しでも大丈夫のような・・・ あんまり美しいアルゴリズムじゃない気がするけど。。。

taseki
質問者

お礼

ご回答ありがとうございます。 すみません、ちょっと解らなかったのですが、具体的に御教授いただけないでしょうか。 私が下に書いた処理キャンセルフラグを、キーが押されている間にオンにしておくのではなく、ページの更新で制御する、ということでしょうか。 そのページの更新とは、どのようなことでしょうか。 お手数ですが、よろしくお願いします。 前に書いたように、そもそも、ほとんどのブラウザが、ブラウザ自身のほうで代替操作を用意しているので、 ●アクセシビリティを低下させず ●重複起動による不具合を回避し ●W3Cの指針にも従う というすべてを適える方法は、やはりonkeypress="return false" または void でダミーを指定しておくしかないのかな、と思い始めています…。

noname#39970
noname#39970
回答No.3

onClickとして反応するキーは無視するように作ったら良いと思う。 その上でonClickとして反応しないキーを拾ってonClickで呼んでるやつを呼んだら良いのでは?

taseki
質問者

お礼

ご回答ありがとうございます。 残念ながら、少なくともIEでは、onclickイベントの中で押されているキーが取得できないか、あるいはキーを離したときに呼ばれるので取得できない(この可能性は低そう)ようです。 onclickイベントの中で押されたキーを取得できる方法をご存知でしたら、御教授いただければ助かります。 それともう一つ、キーによる違いというのは、おそらく環境に依存しますよね。それらに対応する方法が見当たらず あるいは、それこそ指針などで規定されていれば一部の環境をあきらめるのも考えられますが、それもないようです。 今のところ、onkeydownで「onclickキャンセル」フラグを立てて、onkeyupでフラグをオフ、という方法を思いついたのですが(つまりキーが押されている間はonclickイベントはキャンセルさせる)、コードは簡単ですがどうもタグが煩雑すぎる… しかし、よく言われてはいますが、アクセシビリティ指針は本当に疑問の多い発展途上なものですね。 そもそもマウス以外への考慮なんて、文書がやるべきではなくブラウザやOS側の役目というか義務でしょうに…

taseki
質問者

補足

下のフラグの方法ですが、IEのスペースキーでは、離したときにonkeyup⇒onclickという順に発生してしまい、ダメでした・・

回答No.2

>onkeypressイベント→onclickイベントというように両方とも発生してしまいます。 済みません。一時期再現していたと思っていたのですが、手元で再現しなくなっちゃいました。考え直してきます。

taseki
質問者

お礼

ありがとうございます。 実験のための再現は、以下を使ってください。 とりあえずIE用ですが(しかもかなり荒いコードですが)、適宜編集してください。 <html> <head> <script type="text/javascript"> function Test01(sEv){ document.getElementById("EvLog").insertAdjacentHTML("BeforeEnd", sEv + "<br>"); } </script> </head> <body> <input type="button" value=" TEST " onclick="Test01('onclick');" onkeypress="Test01('onkeypress');"> <input type="button" value=" Clear " onclick="document.getElementById('EvLog').innerHTML = '';"> <div id="EvLog"></div> </body> </html> たとえばIEの場合は、 スペースキーを押したとき⇒onkeypress、離したとき⇒onclick エンターキーを押したとき⇒onkeypressとonclick ESCキー、文字キー⇒onkeypress といった具合です。

回答No.1

何か駄目だ・・・こんなのしか思いつかない・・・ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>ふはは</title> <script type="text/javascript"> function huga(){ test = document.getElementById('hoge'); test.firstChild.nodeValue = test.firstChild.nodeValue + a; alert(test.firstChild.nodeValue); } a=0; </script> </head> <body> <div id="hoge"></div> <p><a href="gahagaha.html" style="border:red solid;" onclick="if(a==0){huga();};a=0;" onkeypress="a=1;huga();">イベント実験</a></p> <p><input type="button" style="border:green solid;" onclick="if(a==0){huga();};a=0;" onkeypress="a=2;huga();" value="Event" /></p> </body> </html> Javascript慣れしている訳じゃないから間違ってるかも(汗

関連するQ&A