2009-09-24 74 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是display:none,直到用戶點擊幾個名爲「login」的鏈接之一。

以下是我正在使用的JavaScript代碼,它選擇'login'鏈接,它移動DOM中'add-comment-login-overlay'的位置,設置display:block,然後設置焦點覆蓋圖中的第一個輸入字段。這是造成我上面寫的錯誤的重點設置過程。

//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) 

我已經受夠了發生許多-A-時間,包括使用jQuery。這不是任何圖書館的錯。 setTimeout一直爲我工作。

+0

我在IE8中遇到了這個問題,但是我認爲我的問題與窗口被window.showModalDialog(...)調用打開的事實有關。這種解決方法對我來說非常合適。謝謝! – Sanjamal

+0

這在DotNetNuke問題上適用於我!謝謝Crescent Fresh! –

+0

顯然它仍然存在於IE11中,只有這個時間500毫秒的定時器纔能有效。 – Jason

1

將焦點設置在try/catch塊中。

+0

不幸的是,我沒有試圖在漏水壩中放一塊膠來修補它。我想知道這是什麼原因造成的。 – Geuis

+5

嗯,在我看來,ie6中的一塊口香糖是最佳做法。這個瀏覽器充滿了你不想理解它們的奇怪的錯誤,你只是試着讓你的應用程序工作。我還沒有測試過Iod3n的方法,但如果它有效,如果它不會影響性能,那麼您應該爲您的應用修補一個啤酒。 – GmonC

0

在猜測,我會說insertAfter調用令IE瀏覽器DOM困惑。你可以在沒有insertAfter電話的情況下測試代碼嗎?它是否以同樣的方式失敗?如果不是,還有另外一種方法可以達到同樣的結果嗎?也許複製節點並刪除原件,而不是移動節點?

相關問題