2009-09-24 9 views
13

これは、JavaScriptとInternet Explorerのさまざまなバージョンで長年取り組んできた中で最も曖昧なバグです。私たちはいくつかの(非)便利な方法にYUI 2.7を使用しています。一口、jQueryのためにやるべきこと....JavaScript:入力要素のフォーカスを設定したときのInternet Explorerの表示エラー

これはInternet Explorer 6とInternet Explorer7に影響します。 Internet Explorer 8は正しく動作します。他のすべてのブラウザも適切に動作します。

問題:私は特定の要素に焦点を当てて設定すると、私は次のエラーを取得する:

Can't move focus to the control because it is invisible, not enabled, or of a type that does not accept focus. 

だから私は、入力要素が含まれている「を追加 - コメントログインオーバーレイ」と呼ばれるdiv要素を持っています。このdivは、ユーザーが 'login'と呼ばれるいくつかのリンクの1つをクリックするまでdisplay:noneです。

DOM内の 'add-comment-login-overlay'の位置を移動し、display:blockを設定し、次にフォーカスを設定する 'login'リンクを選択するJavaScriptコードですオーバーレイの最初の入力フィールド。私が上で書いたエラーを引き起こしているのは、フォーカスを設定するこのプロセスです。

//Get Login links in comment forms. 
links = YAHOO.util.Dom.getElementsByClassName('addCommentLoginLink'); 

//Set click event for login links. 
YAHOO.util.Event.addListener(links, "click", function(el){ 

    //Stop link. 
    YAHOO.util.Event.preventDefault(el); 

    //Move login overlay in DOM. 
    if(el.srcElement){ 
     var target = el.srcElement; 
    }else{ 
     var target = el.currentTarget; 
    } 

    YAHOO.util.Dom.insertAfter(overlay, target.parentNode.parentNode.parentNode.parentNode); 

    //Set to visible. 
    YAHOO.util.Dom.setStyle(overlay,'display', 'block'); 

    //Set focus to username field. 
    document.getElementById('add-comment-login-overlay-username-input').focus(); 
}); 

オーバレイのdivが完全に表示されていることは絶対に確認できます。私はそれを見ることができます。私は何が起きているのかを測定するためにsetIntervalタイマーを追加しましたが、何の効果もありません。ある時点で、オーバーレイが表示されてから、focus()が呼び出されてからエラーが発生するまでに、10秒間が経過しました。エラー以外にも、このエラー以外のフォームは完全に機能しています。

これは、オーバーレイHTMLコードを単純化したものです。

<div id="add-comment-login-overlay" class="add-comment-login-overlay" style="display: block;"> 
    <div class="add-comment-login-overlay-content clearfix"> 
     <div class="add-comment-login-overlay-signin clearfix"> 
      <input type="text" tabindex="2001" id="add-comment-login-overlay-username-input"/> 
      <input type="password" tabindex="2002" id="add-comment-login-overlay-password-input"/> 
     </div> 
    </div> 
</div> 

答えて

17

これは、IEのちょっとしたバグです(これは8で修正されていることを知ってうれしいです)。私は公式の原因を知らないが、私はそれはIEが実行コンテキストが完了するまでDOMを塗り替えていないとしなければならないと信じて、それはそれはまだ隠さだと思っている間その間要素focus()にしよう:

function calledAtSomePoint() { // begin execution 

    // ... 

    element.style.display = ''; // show container 
    input.focus(); // IE thinks element is hidden 

    // end of execution, IE repaints the DOM but it's too late 
} 

The solution is to use setTimeout

setTimeout(function() { 
    document.getElementById('add-comment-login-overlay-username-input').focus() 
}, 0) 

私はそれがjQueryのを含む、多くの-A-時間が起こる持っていました。どのライブラリにも問題はありません。 setTimeoutは、いつも私の周りに働いてきました。

+0

私はIE 8でこの問題を抱えていましたが、私の問題はフォームがwindow.showModalDialog(...)の呼び出しによって開かれていたという事実と関係していたと思います。この回避策は私にとって完璧に機能しました。ありがとう! – Sanjamal

+0

これはDotNetNukeの問題で私のために働いた!新鮮なクレセントをありがとう! –

+0

明らかにIE11にはまだ存在していますが、今回は有効性のために500msのタイマーが必要です。 – Jason

1

try/catchブロックでフォーカスを設定します。

+0

残念ながら私は漏れの多いダムにガムを入れてパッチを張り切ろうとしていません。私は、これが何を引き起こしているのかを知りたい。 – Geuis

+5

私の意見では、ie6のガムがベストプラクティスです。このブラウザはあなたがそれらを理解しようとしていない奇妙なバグでいっぱいです、あなたはアプリを動作させるようにしてみてください。私はIod3nアプローチをテストしていませんが、それがうまくいけば、パフォーマンスがまったく損なわれなければ、ビールのためにあなたのアプリを外出させるべきです。 – GmonC

0

私は、insertAfter呼び出しがIE DOMを混乱させると言いたいと思います。 insertAfterコールを使わずにコードをテストできますか?同じように失敗しますか?そうでない場合、同じ結果を達成する別の方法がありますか?おそらくノードをコピーするのではなく、ノードをコピーしてオリジナルを削除するのでしょうか?

関連する問題