jQuery事件用于渲染元素

5
我试图在屏幕外进行所有的DOM操作,然后再将其显示。这样可以实现,但现在我遇到了这样的情况:我想在浏览器上呈现表单时,让第一个输入文本获得焦点。

类似这样: myForm.prependTo(myDiv).show().find('input:first').focus();

问题是当表单还没有完成渲染时就调用了焦点函数,导致出现了以下错误:'Can't move focus to the control because it is invisible, not enabled, or of a type that does not accept the focus'

其他网页开发人员如何处理操作屏幕外元素并使其可见的类似情况? 我希望jQuery有类似于下面的东西
myForm.prependTo(myDiv, function() { /* 在渲染代码中 */ })

我知道其中一种方法是设置一个定时器,当它触发时,我把焦点放在输入框上,但我觉得这不是最干净的方式。 我知道iframe有一个onload事件,所以我很好奇人们通常是否会在一些隐藏的iframe中绘制他们的元素,并侦听其load事件来知道何时完成元素的渲染? 如果是这样,您可以向我展示一个这样做的示例吗?

你为什么不能在表单显示后直接调用.focus呢? - Emmett
就像我之前所说的那样,我遇到了“无法移动焦点...”错误。这是因为在浏览器仍在渲染表单时调用了焦点。基本上,浏览器会说:“嘿,你不能在元素上设置焦点,它还没有显示出来”。 - paul smith
好的,我原本以为 myDiv 直到后面才会显示出来。 - Emmett
你在屏幕外具体在做什么?如果你没有意识到,大多数DOM操作不会在代码运行时实时发生。浏览器往往会将这些操作排队,然后在JS执行完成后重新布局页面。 - jfriend00
我在屏幕外向表单添加元素。之后,我将其移动到一个空的中心 div 中,然后使其可见(使用 .show()),然后聚焦于第一个输入字段。没有什么花哨的。 - paul smith
2个回答

2
myForm.prependTo(myDiv).show(function(e){
    $(this).find('input:first').focus();
});​

1
请注意,.show() 是同步的,因此您不需要使用完成函数。 - jfriend00
该函数本身可能是同步的,但浏览器的绘图必须是异步的,因为如果不是这样,我就不会遇到手头的问题 :) - paul smith
我想知道的是如何知道浏览器渲染完成的时间。一个简单的技巧是使用计时器,但我并不认为这是正确的做法。 - paul smith

1
我知道我晚了7年,但我有一个类似的问题,我通过将渲染后需要发生的事情放在准备好的处理程序中来解决它。
我有一个恢复功能,但几乎没有视觉反馈表明元素已被恢复。
我尝试先清空元素。它仍然有效,但仍然没有任何视觉反馈。

$("#someSelector").empty(); restore();

然后我发现ready()发生在渲染之后;所以我把它改成了这样.... $("#someSelector").empty().ready(function() { restore(); });
现在restore()直到empty()操作RENDERS之后才会发生。这意味着我的元素似乎被清空然后重新填充(它总是这样做的,但现在用户可以看到它发生)。
几天前我用一种模糊的搜索方式找到了这个解决方案,解决了一个不同的问题。 然后我再次需要它,但又不太记得我做了什么。 现在我的搜索包括“jquery”和“render”等词,并引导我来到这里。
最终,我查看了我的代码,找出了我做了什么,我认为在这里发布它可能是一个好主意,以防其他人偶然发现这篇文章并真正需要在渲染后执行某些操作。
干杯。

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