我有以下几行HTML:
<div class="hiddenClass"> // this implies display:none
<span>
<input type="text" id="hiddenInput"/>
</span>
</div>
和一个Javascript事件(在jQuery $ .ajax()调用的“succes”方法中触发),需要使该div可见,然后将焦点设置为控件。类似的东西:
this.DOMElements.divElement.className="showClass"; //a CSS class with display:block;
this.DOMElements.hiddenInputElement.focus();
this.DOMElements.hiddenInputElement.select();
很奇怪,这段代码只在部分时间内有效。在某些情况下(仅有时!!),焦点/选择命令会生成有关聚焦/选择不可见控件的警告。控件将可见,但焦点不会移动,文本也不会被选中。
我通过在单独的函数中移动焦点/选择代码并通过
延迟调用来找到(某种程度上)解决方案this.DOMElements.divElement.className="showClass"; //a CSS class with display:block;
setTimeout("focusinput('hidddenInput')",1);
好的,最后我的问题:因为javascript是单线程的..为什么在我使父div可见的时间和我可以在子输入元素上设置焦点/选择的时间之间有延迟?这怎么可能是竞争条件?
编辑:在IE8中发生
答案 0 :(得分:1)
如果您正在使用jQuery,请使用它来显示和设置焦点:
$(".hiddenClass").fadeIn("fast",
function() {
$("#hiddenInput").focus();
}
);
或
$(".hiddenClass").show(0,
function() {
$("#hiddenInput").focus();
}
);
如果你想显示它而没有任何淡入。
基本上它正在淡化隐藏的div(如果你想要显示一个特定的div而不是所有带有.hiddenClass的元素,你可以用id替换.hiddenClass),一旦完成它就会执行回调函数来给出专注于输入。
这样你就不会在完全显示div之前尝试给出输入焦点。
答案 1 :(得分:1)
好的,最后我的问题:因为javascript是单线程的..为什么在我使父div可见的时间和我可以在子输入元素上设置焦点/选择的时间之间存在延迟? / p>
你刚回答了自己的问题:这发生了,因为 JS是单线程的;也就是说,它阻止浏览器更新其呈现,直到脚本完成执行。
所以当你执行代码时:
divElement.className="showClass";
元素的className属性已更新,但由于您的脚本仍在执行,因此元素不会立即重新绘制为可见。因此,当您执行
时hiddenInputElement.focus();
该元素仍然隐藏,您收到错误。
因此,在您的第一个版本中,单个线程中的执行顺序是:
使用setTimeout
方法时,序列为:
答案 2 :(得分:0)
我不确定这里发生了什么,但是获取对你使用的div的引用,将它存储在变量中,然后对其进行操作,而不是使用getElementByID获取它可能不是一个坏主意( )每一次。
所以你的代码就是:
var myDiv = document.getElementById("hiddenInput");
if(myDiv)
{
myDiv.className="showClass"; //a CSS class with display:block;
myDiv.focus();
myDiv.select();
}
另外:有一些javascript函数允许浏览器启动另一个thead(例如,load()函数);只需要记住一些事情:)
答案 3 :(得分:0)
我之前遇到过这种情况。在大多数情况下,我发现通过在设置后设置超时来解决IE中的问题。不幸的是,这不是最干净的解决方案。