2

我有一些允许用户创作内容的 CMS 代码。我想显示在相应文本区域中键入的文本的预览(很像在 stakeoverflow 中的此处)。首次加载页面时,textarea 已被填充,并且 JavaScript 用于更新预览。预览部分的 DOM 完全更新后,将对预览部分执行进一步的后处理。

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

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

确保在开始后处理之前首先加载动态修改的 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);
}
4

2 回答 2

2

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

这里不需要使用$.Callbacks()或任何排队系统。

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

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

于 2012-07-19T18:43:47.857 回答
0

As suggested by Kevin B, the problem was that the call to html() doesn't always have data when this method is called. Eventually, it does, so polling is set up (yes, using setTimeout()); thank goodness for blocks (rather, anonymous functions) or this would not nearly be so elegant.

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);
}

Checking the browser console, we see that it handles this circumstance just fine. Never mind the fact that the polling shouldn't be required in the first place!

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
于 2012-07-19T21:51:59.357 回答