【问题标题】:Checking to see if a DOM element has focus检查 DOM 元素是否具有焦点
【发布时间】:2018-04-25 18:21:49
【问题描述】:

我有一个灯箱文本框,它使用来自 ASP.NET UpdatePanel 的 AJAX 调用显示。当灯箱显示时,我使用灯箱中文本框的focus() 方法立即将焦点带到文本框。

在 Firefox 中,文本框毫无问题地获得焦点。在 IE 中,除非我使用

,否则文本框不会获得焦点
setTimeout(function(){txtBx.focus()}, 500);

我假设在加载 DOM 元素之后稍微稍后触发 focus 方法。

问题是,就在那条线的上方,我已经在检查元素是否为空/未定义,所以如果对象到达那条线,它应该已经存在,它只是不允许自己获得焦点由于某种原因离开。

显然,设置一个计时器来“修复”这个问题并不是解决这个问题的最佳或最优雅的方法。我希望能够执行以下操作:

var txtBx = document.getElementById('txtBx');

if (txtPassword != null) {
    txtPassword.focus();
    while (txtPassword.focus === false) {
        txtPassword.focus();
    }
}

有什么方法可以告诉我一个文本框有焦点,所以我可以做上面的事情吗?

还是我看错了?

编辑
为了澄清,我没有在页面加载时调用代码。脚本位于页面顶部,但它位于一个函数内,该函数在 ASP.NET 的异步回发完成时调用,而不是在页面加载时调用。

因为这是在 Ajax 更新之后显示的,所以应该已经加载了 DOM,所以我假设 jQuery 的 $(document).ready() 事件在这里没有帮助。

【问题讨论】:

  • 可能是在灯箱+文本框渲染之前脚本正在执行?你是怎么打开灯箱的?也许发布一些代码。
  • 这当然有可能,我只是不知道该怎么做才能解决这个问题。
  • setTimeout() 延迟为 0 是否有效?

标签: javascript internet-explorer


【解决方案1】:

尝试将设置焦点的 javascript 放在页面末尾而不是开头,或者在页面加载事件之后触发。这将有助于确保在设置焦点之前完全加载 DOM。

我为此使用了FastInitJQuery $(document).ready() 也可以。

【讨论】:

    【解决方案2】:

    你可以试试这个:

    1. 使用PageRequestManagerendRequest 事件。一旦 Ajax 更新完成,该事件就会触发。
    2. 在事件处理程序中关注文本框

    这里是一些示例代码:

    <script type="text/javascript">
        function onRequestEnd()
        {
         var txtBx = $get('txtBx');
         txtBx.focus();
        }  
        Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onRequestEnd);
    </script>
    

    要首先关注文本框,您可以使用pageLoad 函数(Application 客户端对象的load 事件的快捷方式):

    <script type="text/javascript">
    function pageLoad()
    {
        var txtBx = $get('txtBx');
        txtBx.focus();
    }
    </script>
    

    【讨论】:

    • 这正是我现在实际使用的。元素的 focus() 方法在 onRequestEnd() 方法中被调用。
    【解决方案3】:

    您可以尝试这样的 [IE 特定]。 (未经测试)

    theAjaxCreatedElement.onreadystatechange = function() {
        if ( this.readyState != "complete" ) 
            return;
        this.focus();
    };
    

    另一种方法可能是用onfocus改变元素的背景颜色,然后用js检索它检查它是否应该是,如果不是:重新聚焦元素。

    【讨论】:

    • 我试过了。 readyState 已经“完成”了,这让我很烦恼。 IE 说 DOM 元素已经准备好了,但是在它“真正准备好”之前你不能对它做具体的事情,我想这是描述它的最佳方式。
    【解决方案4】:

    似乎 IE 直到脚本完成运行后才更新 DOM。因此,焦点循环测试将不允许 DOM 更新。使用setTimeout 可能是唯一可行的解​​决方案。

    您使用.focus() 的示例是一个众所周知的示例,请参见例如this answer.

    【讨论】:

      【解决方案5】:

      您是否尝试将 autofocus="autofocus" 属性添加到您通过 Ajax 调用的文本框元素?

      通常,当我需要某些额外的 JavaScript 功能来在动态内容上运行时,我会简单地将该 JavaScript 添加到被调用的内容中。

      该 JavaScript 在添加到 DOM 后也会执行。我认为将 JavaScript 写入您的父文件然后“监听”对 DOM 的更改是没有意义的。就像你提到的,对于这样的事情,setTimeout() 更像是一种黑客攻击:)

      【讨论】:

        【解决方案6】:

        IE 中有几样东西可以解决问题:

        1. 如果焦点元素有不同的z-index - 你可以快速将z-index设置为当前焦点元素(可能设置hidden属性),设置焦点,然后将其设置回原来的z-index .

        2. 尝试blur()当前焦点元素。

        3. 如果元素是 'shimed' - 聚焦 'shim' 元素。

        【讨论】:

        • “垫片”是什么意思?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-18
        • 1970-01-01
        • 1970-01-01
        • 2014-04-04
        相关资源
        最近更新 更多