我如何知道 jquery html() 的更改何时完成?

发布于 2024-08-27 22:36:53 字数 317 浏览 3 评论 0原文

我正在使用 jQuery 更改标签的 HTML,新的 HTML 可能是一个非常长的字符串。

$("#divToChange").html(newHTML);

然后我想选择在新 HTML 中创建的元素,但是如果我将代码紧跟在上面一行后面,它似乎会创建一个竞争条件使用长字符串,其中 html() 所做的更改可能不一定完成渲染。在这种情况下,尝试选择新元素并不总是有效。

我想知道的是,当 html() 的更改完成渲染时,是否会触发事件或以其他方式收到通知?我遇到了 jQuery watch 插件,它可以作为解决方法,但并不理想。有更好的办法吗?

I'm using jQuery to change the HTML of a tag, and the new HTML can be a very long string.

$("#divToChange").html(newHTML);

I then want to select elements created in the new HTML, but if I put the code immediately following the above line it seems to create a race condition with a long string where the changes that html() is making may not necessarily be finished rendering. In that case, trying to select the new elements won't always work.

What I want to know is, is there an event fired or some other way of being notified when changes to html() have finished rendering ? I came across the jQuery watch plugin, which works alright as workaround but it's not ideal. Is there a better way ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

戈亓 2024-09-03 22:36:54

7 年后,我刚刚遇到了一种与 @mikel 描述的场景一模一样的情况,我无法避免“基于计时器的解决方案”。因此,我只是分享我开发的解决方案,以防有人仍然遇到问题。

我讨厌在我的代码中使用 setTimeoutsetInterval 。因此,我创建了一个小插件,您可以将其放在您认为最好的位置。我使用了 setInterval,但您可以将其更改为 setTimeout 或您想到的其他解决方案。这个想法只是创建一个承诺并不断检查该元素。一旦准备好,我们就兑现承诺。

// jquery.ensure.js

  $.ensure = function (selector) {
    var promise = $.Deferred();
    var interval = setInterval(function () {
      if ($(selector)[0]) {
        clearInterval(interval);
        promise.resolve();
      }
    }, 1);
    return promise;
  };

// my-app.js

  function runWhenMyElementExists () {
    // run the code that depends on #my-element
  }

  $.ensure('#my-element')
    .then(runWhenMyElementExists);

It's 7 years latter and I just ran into a scenario exactly like the one @mikel described, where I couldn't avoid a "timer based solution". So, I'm just sharing the solution I developed, in case anyone out there is still having issues with this.

I hate having setTimeouts and setIntervals in my code. So, I created a small plugin that you can put where you think it's best. I used setInterval, but you can change it to setTimeout or another solution you have in mind. The idea is simply to create a promise and keep checking for the element. We resolve the promise once it is ready.

// jquery.ensure.js

  $.ensure = function (selector) {
    var promise = $.Deferred();
    var interval = setInterval(function () {
      if ($(selector)[0]) {
        clearInterval(interval);
        promise.resolve();
      }
    }, 1);
    return promise;
  };

// my-app.js

  function runWhenMyElementExists () {
    // run the code that depends on #my-element
  }

  $.ensure('#my-element')
    .then(runWhenMyElementExists);
翻身的咸鱼 2024-09-03 22:36:53

正如评论者已经提到的,JavaScript 是单线程的,因此你无法获得竞争条件。

然而,可能会让您感到困惑的是,在线程完成之前,UI 不会根据 JavaScript 进行自我更新。这意味着整个方法必须完成,包括调用 html(...) 之后的所有代码,然后浏览器才会呈现内容。

如果调用 html(...) 后的代码依赖于在继续之前重新计算的页面布局,则可以执行以下操作:

$("#divToChange").html(newHTML);
setTimeout(function() {
    // Insert code to be executed AFTER
    // the page renders the markup
    // added using html(...) here
}, 1);

使用 setTimeout(...)1 的 > 会推迟执行,直到调用函数中的当前 JavaScript 代码完成并且浏览器更新了 UI 后。这可能会解决您的问题,但很难判断,除非您可以提供您所遇到的错误的可重现示例。

As a commenter already mentioned, JavaScript is single threaded, so you can't get race conditions.

What may trip you up however, is the fact that the UI will not update itself based on JavaScript, until a thread is finished. This means that the entire method must finish, including all code after you call html(...), before the browser will render the content.

If your code after calling html(...) relies on the layout of the page being recalculated before continuing, you can do something like this:

$("#divToChange").html(newHTML);
setTimeout(function() {
    // Insert code to be executed AFTER
    // the page renders the markup
    // added using html(...) here
}, 1);

Using setTimeout(...) with a time of 1 in JavaScript defers execution until after the current JavaScript code in the calling function finishes and the browser has updated the UI. This may solve your problem, though it is difficult to tell unless you can provide a reproducible example of the error you're getting.

蹲在坟头点根烟 2024-09-03 22:36:53

使用 .ready jQuery 函数

$("#divToChange").html(newHTML).ready(function () {
                    // run when page is rendered
                    });

use .ready jQuery function

$("#divToChange").html(newHTML).ready(function () {
                    // run when page is rendered
                    });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文