JavaScript:将焦点设置在输入元素上时Internet Explorer中的可见性错误

时间:2009-09-24 23:15:24

标签: javascript internet-explorer focus

这可能是我在使用JavaScript和任何版本的Internet Explorer多年中遇到的最不起眼的错误。我们将YUI 2.7用于某些(非)便利方法。叹了口气,我会为jQuery做些什么......

这会影响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.

所以我有一个名为'add-comment-login-overlay'的div,它包含input元素。此div显示为:none,直到用户单击名为“login”的多个链接之一。

以下是我正在使用的JavaScript代码,它选择“登录”链接,它移动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>

3 个答案:

答案 0 :(得分: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。这不是任何图书馆的错。 setTimeout一直在为我解决问题。

答案 1 :(得分:1)

将焦点设置在try / catch块中。

答案 2 :(得分:0)

猜测,我会说insertAfter调用混淆了IE DOM。你可以在没有insertAfter电话的情况下测试代码吗?它是否以同样的方式失败?如果没有,是否有另一种方法可以达到相同的效果?也许复制节点并删除原件,而不是移动节点?