在进一步处理之前等待动态DOM更新

时间:2012-07-19 17:57:52

标签: jquery jquery-callback

我有一些CMS的代码,允许用户创作内容。我想显示在相应的textarea中输入的文本的预览(很像这里的关注溢出流)。首次加载页面时,已填充textarea,并使用JavaScript更新预览。一旦预览部分的DOM完全更新,就会在预览部分上执行进一步的后处理。

我发现了感兴趣的问题jQuery/Javascript - How to wait for manipulated DOM to update before proceeding with function,但它的答案依赖于setTimeout(),我发现它在过去有些问题,因为它不清楚在执行前暂停多少秒。

大约50%的时间,我的后处理过早地被解雇,因为DOM还没有完成更新。为了解决这个问题,我尝试使用jQuery的Callbacks队列机制。

确保在后处理开始之前首先加载动态修改的DOM的最佳方法是什么?

,例如,

// using the provided source content, update the DOM indicated by
// the destination css selector string
function updatePreview(cssSelectorDst, content){
  $(cssSelectorDst).html(content);
  console.log("preview updated");
}

// if a <ul> appears at the beginning of the content, designate it
// as a keypoints section
function updateKeypoints(cssSelectorDst){
  ...
  console.log("keypoints updated");
}

// update preview section using content from iframe (using tinyMCE)
function updateFromIframe(iframeSelector, cssSelectorSrc, cssSelectorDst){

  // gather source data
  var iframe = $(iframeSelector);
  var content = $(iframe).contents().find(cssSelectorSrc).html();

  // set up callbacks to ensure proper order and completion of actions
  var callbacks = $.Callbacks();
  callbacks.add(updatePreview);
  callbacks.add(updateKeypoints);
  callbacks.fire(cssSelectorDst, content);
}

2 个答案:

答案 0 :(得分:2)

.html是同步的,代码在它完成附加html之后才会开始执行。

此处无需使用$.Callbacks()或任何排队系统。

// Update Preview
updatePreview();
updateKeypoints();

如果您发现这不起作用,那不是因为.html()尚未完成,问题出在其他地方。

答案 1 :(得分:0)

正如Kevin B所建议的那样,问题是当调用此方法时,对html()的调用并不总是有数据。最终确实如此,因此设置了轮询(是的,使用setTimeout());谢天谢地(更确切地说,匿名函数),或者这不会那么优雅。

function updateFromIframe(iframeSelector, cssSelectorSrc, cssSelectorDst){
  var iframe = $(iframeSelector);
  var content = $(iframe).contents().find(cssSelectorSrc).html();

  if(content == null){
    console.log("content not yet available; trying again...");
    return setTimeout(function(){updateFromIframe(iframeSelector, cssSelectorSrc, cssSelectorDst)}, 50);
  }

  updatePreview(cssSelectorDst, content);
  updateKeypoints(cssSelectorDst, content);
}

检查浏览器控制台,我们看到它处理这种情况就好了。没关系,首先不应该要求投票!

content not yet available; trying again...
content not yet available; trying again...
content not yet available; trying again...
content not yet available; trying again...
content not yet available; trying again...

content: <ul><li>condimentum rhon ... nunc, <br><br></p>
preview updated

keypoints updated