jQuery的focus()在IE8中有时无法正常工作

16
我正在使用jQuery开发Web应用程序。我有一个功能,可以添加3个输入字段的新行。创建这些DOM元素后,我想将其中一个输入字段聚焦。我调用所需输入字段上的jQuery focus()函数来实现它。
问题是,在IE6和FF3.5中调用focus()函数正常工作,但在IE8中不起作用。
我试图制作一个简单的工作示例来展示此问题,但是使用简化版本的代码,focus()函数正常工作。因此,我的猜测是在调用focus()时DOM尚未准备就绪。为此,我尝试调用setTimeout('myFocus()',400)。在某些情况下,我成功了,确实聚焦了输入字段,但并不总是有效。它随机地无法聚焦我的输入字段。
问题是:是否有人面临类似的问题,是否有任何想法如何解决?使用setTimeout感觉像非常丑陋的解决方法。
先谢谢。
<html>
<head>
    <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
    <script type="text/javascript">
        function performChanged() {
          formChanged = true;
        }

        function handleChange() {
          var parentDiv = $('#container');
          newValue = $(html).html();

          parentDiv.html(newValue);
          $(".sel1",parentDiv).bind('change',handleChange);
          //alert('Uncomment this and after alert focus will be on input');
          $("input.cv_values",parentDiv).focus();
        }

        $(document).ready(function() {
          $('.trackChange').bind('change', handleChange);
        });
        var html = '<div class=\"div1\">\n<select class=\"sel1\" id=\"sel1\" name=\"sel1\"><option value=\"\"><\/option>\n<option value=\"11\">Select me to see problem<\/option>\n<\/select>\n\n\n<input class=\"cv_values\" id=\"sel3\" name=\"sel3\" size=\"30\" type=\"text\" value=\"\" /><br/>Focus should in input field. With alert it is but without alert focus is not there</div>';
    </script>
</head>
<body>
    <select class="trackChange" onchange='performChanged();'>
      <option value=""></option>
      <option value="1" >Select me to generate new inputs</option>
    </select>

    <div id="container"></div>
</body>

复现步骤: 1)从第一个下拉列表中选择值,您会发现第一次输入有效。 2)从第二个下拉列表中选择值。您会看到错误已经复现。

然后在代码中,您可以注释掉显示JS alert()的行。奇怪的是,如果有此alert(),那么聚焦就能正常工作。

希望这可以帮助您了解我的问题所在。

P.S. 我需要我的应用程序以这种方式工作-在从下拉列表中选择值之后重新生成这些输入框。这是我应用程序的简化示例;)。


1
发布代码片段会让事情变得更容易。 - krishna
你尝试过专注于窗口的“load”事件吗(而不是“DOMContentLoaded”,也就是document.ready(...))? - kangax
7个回答

30

我的应用程序也遇到了类似的问题,但是我无法通过你的代码重新现出这个焦点问题。我的问题略有不同,因为我的页面有一个链接哈希值,导致IE不能将我的元素聚焦。

无论如何,为了解决这个问题,我添加了一个超时:

setTimeout(function () {
  $('.my-thing').focus();
}, 100);

用户不会注意到,但它让IE稍微喘口气。


你知道为什么这个解决方案有效吗?(哦,谢谢。它绝对有效。) - jjnguy
1
从一些古老的文档中得知:要使文本框聚焦并预先选择框内的所有文本,需要在元素上使用focus()和select()方法的序列。如果此序列需要在窗口更改后发生(例如关闭警告对话框后),请将这些方法放在单独的函数中,并通过setTimeout()方法在对话框的alert()方法后调用此函数。这允许IE/Windows正确地排序语句执行。 - davidchambers
谢谢提供的解决方法。虽然不太美观,但我找不到更优雅的解决方案了... 如果有人能找到更好的解决方法,我会很感激他们能解释一下!在我的情况下,即使只有1毫秒的超时,它似乎也能正常工作,不过对用户来说,无论是1毫秒还是100毫秒都无法察觉 :) - thetoolman

8

结合 Kazys 的解决方案,我发现这个解决方案可以解决我的所有问题(使用 IE8 和 .HTA 文件):

$("elem").blur();
$("elem").focus().focus();

我不知道为什么,但在IE中调用两次焦点似乎有所帮助。
编辑: 我发现调用.show()和.select()也有帮助。

$("id").focus().focus(); 对我来说是有效的,使用它有什么不利之处吗?@Max Mayhem - bumbumpaw
目前我还没有意识到任何问题。 - Max Mayhem
在IE11中也为我解决了问题!谢谢 :) - Krenor
$("elem").focus().select(); 对我也起作用了,但仍然不确定为什么会出现这个问题(聚焦于文本框但之前没有选择它)。 - Kendall

6

奇怪的是我也遇到了同样的问题,并使用纯JavaScript解决了它:

document.getElementById('friend_name').focus();

在IE8中,使用jQuery相当的代码$('#friend_name').focus();无法正常工作,:-/


3
这是你可能想向jQuery基金会报告的事情。 - Fresheyeball

4

我曾遇到和IE8相似的问题,当打开对话框时,我希望能够聚焦在输入框上。我使用了autoOpen = false属性,但发现只有对话框中第一个可聚焦元素无法聚焦。我尝试了setTimeout函数,但只有偶尔有效。后来我通过先使元素失焦再聚焦的方式解决了这个问题。

$('#dialog').find('#name').blur();
$('#dialog').find('#name').focus();

谢谢!当延迟无法帮助时,这正是人们需要做的。 - Episodex

1

由于您尚未发布任何代码,您是否在使用:

$(document).ready(function(){
    //code here
});

这将使JavaScript在HTML加载后运行。

而且你应该也使用实时事件。当你向DOM添加输入时,它们将自动绑定焦点。

$("p").live("focus", function(){
   alert( $(this).text() );
});

这意味着每个创建的 p 都将绑定一个焦点。


我想聚焦一些输入,但我不需要知道那个聚焦事件。P.S. jQuery当前稳定版本不支持“focus”事件的实时处理。 - oskarae

1

这是目前设置焦点的最佳解决方案:

$('.elt').fadeIn(200, function() {$('.elt').focus();});


0

这是一个老问题,但它在搜索中排名靠前,所以我想更新一下。

我不知道是否曾经有过修复的时间,但我今天在使用jquery-2.1.3的IE11中再次遇到了这个问题。我发现按照Ponny上面所说的,在setTimeout中包装焦点调用对我来说效果最好。

在某些情况下,我确实需要增加超时时间才能使其正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接