アプリ版:「スタンプのみでお礼する」機能のリリースについて

フォーカス設定について教えてください。

テキストボックスに入力エラーがあった場合(数値チェックなど)、以下のようなスクリプトでメッセージボックスを出し、エラー項目にフォーカスをあて、エラー項目の背景色を変更しています。
通常は、問題なく動作するのですが、テキストボックス→セレクトボックスという順番にフォーム部品が並んでいると、エラー項目のテキストボックスと次の部品であるセレクトボックスの両方にフォーカスが当たってしまいます。
テキストボックスのみにフォーカスを当てたいのですか、どなたか理由と解決策を教えていただけないでしょうか。
よろしくお願いします。

//===================================================
// クライアントエラー時の処理
// 引数 1. oItem : エラー項目オブジェクト
//===================================================
function onErrorItem(oItem) {

var sErrCls = "";

var sErrCls = oItem.className;

if ( sErrCls.substr(0, 3) != "err" ) {
sErrCls = "err" + sErrCls;
}

//項目背景色反転&前回分項目背景色反転解除
fncObjTurnOver(oItem, sErrCls);

//フォーカス設定
if ((oItem.type == "text") || (oItem.type == "password")) {
//テキストボックスの場合
oItem.select();
}else{
oItem.focus();
}

}

/*エラーチェック*/
function fnCheckNum(object,msgID,msgParam){
if(fncIsNum(object) <0){
//メッセージボックスを出す
fncMsgPopUp(msgID, msgParam, null);
onErrorItem(object);
}
}

<呼び出し元>
<input type="text" size="3" name="hospCount" maxlength="2" class="InputNum" onblur="fnCheckNum(this,'E0004','病院数');">

A 回答 (4件)

「blur の後 focus できない」現象は Google Chrome 6, Firefox v3.6.6 で再現できました。


IE8, Opera v10.62 では再現しないようです。
どちらの動作が正しいのか、はちょっとわかりませんでした。
初めはイベントの実行順 (「focus -> click -> blur」の順に発火) に関係あるのかと思いましたが、focus() を実行するのはまた別の問題のような気もしますし…。

#1 さん紹介のコードで回避できることを確認できましたが、jQueryコードのようなので標準のJavaScriptコードでサンプルを書いてみました。(Google Chrome 6, Firefox v3.6.6, Opera v10.62, IE8 で動作確認済み)

(※以下、全角空白は半角空白に置換してください)

<form><p><input id="CHECK_NUMBER" type="text" /></p></form>
<script type="text/javascript"><!--
(function () {
 function blurListener (event) {
  var input = event.target;
  if (input.id !== 'CHECK_NUMBER') return;
  setTimeout(inputError, 1, input);
 }
 function blurHandler (event) {
  var input = event.srcElement;
  if (input.id !== 'CHECK_NUMBER') return;
  inputError(input, true);
 }
 function insertAfter (newElement, referenceElement) {
  var nextSibling = referenceElement.nextSibling, parentNode = referenceElement.parentNode;
  nextSibling ? parentNode.insertBefore(newElement, nextSibling) : parentNode.appendChild(newElement);
 }
 function inputError (input) {
  var nextSibling = input.nextSibling,
    text;
  if (/^\d+$/.test(input.value)) {
   if (nextSibling) nextSibling.parentNode.removeChild(nextSibling);
  } else {
   text = input.ownerDocument.createTextNode('数値を入力してください');
   nextSibling ? nextSibling.parentNode.replaceChild(text, nextSibling) : insertAfter(text, input);
  }
 }
 if (document.addEventListener) {
  document.addEventListener('blur', blurListener, true);
 } else if (document.attachEvent) {
  document.getElementById('CHECK_NUMBER').attachEvent('onblur', blurHandler);
 }
}).call(this);
//--></script>

window.setTimeout - MDC
https://developer.mozilla.org/ja/DOM/window.setT …


# 余談ですが、MDC には focus, blur イベントについて以下の注意書きがあります。

---
focus や blur イベントの処理中に、アラートダイアログを出してはいけません。 この挙動は、利用者にとってわずらわしいため、ユーザーインターフェイス設計として劣悪です。
https://developer.mozilla.org/ja/XUL_Tutorial/Fo …
---
    • good
    • 0

横からですが…



No1の補足の内容で、IE6だと再現できます…というか、ご提示のコードではフォーカスは移動していないので、ご質問の結果は当然の結果といえるのかも知れません。

No2様がご指摘のように、focus(); を実行することで、IE6ではフォーカスが移動するようになります。
しかし、fx(3.5)だとこれではフォーカスは移動しないようです。セレクト要素をblur()後にfocus()でもダメもみたいですね。
回答No1の参考サイトのようにsetTimeoutで行なうと、どちらでも意図通りに働くようになるようです。
    • good
    • 0

補足ありがとうございます。


ただ、当方の環境(IE8)では現象の確認ができませんでした。
ですが、テキストボックスの場合はなぜfocus()しないのでしょう?
select()とは別にfocus()も必要なのではないかと思うのですが。
先ほどのsetTimeoutは試されました?
    • good
    • 0
この回答へのお礼

ご回答くださった皆様大変ありがとうございました。
ログインIDがわからなくなってしまい、ご回答が遅れたことをお詫びいたしま
す。

yamada_gさんのご回答で問題解決できました。
そのほかの皆様のご回答も参考になりました。
大変助かりました。
本当にありがとうございました。

お礼日時:-0001/11/30 00:00

こういうことですかね?


http://se-suganuma.blogspot.com/2010/04/javascri …

できたら現象を再現できるコード、確認したブラウザなどの環境を載せていただけるとありがたいです。
    • good
    • 0
この回答へのお礼

ありがとうございます!
そうですよね、申し訳ありません。

動作環境はIE6です。
先ほどとはチェック内容など異なりますが、以下のコードで再現できると思います。


■スクリプト
/*---------------------------------------*/
/*エラーチェック(ロストフォーカス時)*/
/*---------------------------------------*/
function fnCheckNum1(obj){
//テキストフィールドに1が入力されたらエラー
if(obj.value=="1"){
alert("error");
if ((obj.type == "text") || (obj.type == "password")) {
//テキストボックスの場合
obj.select();
}else{
obj.focus();
}
}
}

■フォーム部分

<table><tr>
<td class="itemLabelMid">
生年月日
</td>
<td class="display">
&nbsp;西暦<input type="text" size="6" name="damageY" maxlength="4" class="InputDate" onblur="fnCheckNum1(this);">年
<input type="text" size="3" name="damageM" maxlength="2" class="InputDate" onblur="fnCheckNum1(this);">月
<input type="text" size="3" name="damageD" maxlength="2" class="InputDate" onblur="fnCheckNum1(this);">日
</td>
<td class="itemLabelMid" >
好きな食べ物
</td>
<td class="display">

&nbsp;<select name="hospCause">
<option value="0">
<option value="1">リンゴ
<option value="2">みかん <option value="3">ばなな
<option value="4">ぶどう
<option value="5">なし

</select>
</td>

</tr></table>

お礼日時:2010/09/21 16:24

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