【问题标题】:Does Jquery append() behave asynchronously?Jquery append() 行为是否异步?
【发布时间】:2011-07-02 09:31:11
【问题描述】:

我看到许多帖子 (append supposedly immediate) 在此问题上接受的答案相互矛盾。我们正在使用 JQuery 1.4 (http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js) 并且 append() 似乎是异步的,这样:

已编辑以在 AJAX 回调上下文中显示代码

 ...
 var message = $.ajax({
   type: "GET",
   url: "/getVolumes/" +  _Id,
   async: false 
 }).responseText;
 if (parseInt(message) != 0){
   var $results = $(message);
   $MAIN_DIV.append($results);
   retrieveTargets();
 }
...    
function retrieveTargets(){
  var $targets = $(".resultTargets");
}

按预期执行和创建页面,但目标查询在运行时不会产生任何结果。在 JS 控制台中运行相同的代码会按预期检索元素。

如果这是 JQuery 中的预期行为,那么等待追加完成的正确方法是什么?

【问题讨论】:

  • jQuery 1.8??怎么会??你来自未来?? :)
  • Append 是同步的,但您的 Ajax 调用不是。此代码位于何处?在你的ajax调用的回调函数中?
  • 用正确的版本编辑。我敢打赌这会在 1.8 中按我想要的方式工作。
  • 什么是.resultTargets?它是您的 ajax 响应中的一个元素吗?你也可以这样访问它: var targets = $results.find('.resultTargets');
  • 如果将console.log( $MAIN_DIV.length ) 放在$MAIN_DIV.append(... 之前会发生什么?

标签: jquery asynchronous append


【解决方案1】:

所有的 cmets 都帮助追踪了这一点。我在控制台中关注红鲱鱼。 问题不在于同步性,而在于下一行:

$targets.each( function(){
  ...
  this.html();
  ...

需要

$(this).html();

简而言之,每个人都是正确的。 Jquery append() 行为同步。

【讨论】:

  • 但要小心像 this 这样的 DOM 滋扰,它仍然可能导致意外结果(与 async 函数一样)
【解决方案2】:

试试这个,如果在append 之后还是不行的话。

$('#dynamic-container').append(<your-content>) ;
setTimeout(function() {
    ...code which addresses elements inside #dynamic-container...
},0) ;

更多详情:

  • 显然append 是同步的
  • 显然 DOM 不会同步更新,尤其是在 Google Chrome 中,我在尝试在 append 之后检索 div 的高度时遇到了这个问题
  • 我的假设是浏览器更新线程是异步更新的,下面有更多的 cmets,仍然不清楚事情是如何工作的,但该解决方案在所有情况下都适用于我。

【讨论】:

  • 这是不正确的。当 JavaScript 从 DOM 请求数据或测量值时,浏览器将更新其布局,即使它没有向用户显示。 (这就是layout thrashing的原因。)
  • 好的,渲染线程部分是我对浏览器如何处理 UI 更新的假设。我在我的代码中遇到了这个问题,并使用上面的解决方案修复了它。甚至可能是布局代码在函数在同一个线程中完成后运行。我不是浏览器如何工作的专家
  • 我不想这么说,但我认为你错了。我怀疑您是否能够简单地复制上述问题(一些 jsfiddle),从而隔离问题; .append 确实是完全同步的。另请注意,JavaScript 是单线程的,并且不允许事物(包括浏览器)同时改变数据。
  • 好的,这对我来说没有意义:我检查了我的代码,我正在将一个 agility.js 对象附加到 DOM 树。 Agility 触发一个事件,然后调用 jQuery 的 apprend 将对象的视图添加到 DOM 树中。令我困惑的是,如果 javascript 是单线程的,那么事件触发应该会导致立即调用 agility.js 处理程序,这似乎没有发生。这就是我最终使用 setTimeout 的原因。顺便说一句,我在 agility.js 中没有看到任何 setTimeout 调用
  • 啊!所以它是事件而不是延迟渲染的线程。谢谢你的艾伦。
猜你喜欢
  • 2017-12-19
  • 1970-01-01
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 2015-04-24
相关资源
最近更新 更多