12

jQueryを使用してタグのHTMLを変更していますが、新しいHTMLは非常に長い文字列になる可能性があります。

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

次に、新しいHTMLで作成された要素を選択したいのですが、上記の行の直後にコードを配置すると、長い文字列で競合状態が作成され、html()による変更が必ずしもレンダリングを終了しない場合があります。その場合、新しい要素を選択しようとしても、常に機能するとは限りません。

私が知りたいのは、html()への変更がレンダリングを終了したときに発生するイベントまたは通知される他の方法はありますか?私はjQueryウォッチプラグインに出くわしました。これは回避策としては問題なく機能しますが、理想的ではありません。もっと良い方法はありますか?

4

3 に答える 3

6

すでに述べたように、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(...)JavaScriptでの時間での使用1は、呼び出し元の関数の現在のJavaScriptコードが終了し、ブラウザーがUIを更新するまで、実行を延期します。これで問題が解決する場合がありますが、発生しているエラーの再現可能な例を提供できない限り、判断するのは困難です。

于 2010-04-03T02:55:24.237 に答える
1

それは7年後のことで、@ mikelが説明したのとまったく同じシナリオに遭遇しました。そこでは、「タイマーベースのソリューション」を避けられませんでした。ですから、誰かがまだこれに問題を抱えている場合に備えて、私が開発したソリューションを共有しているだけです。

setTimeoutコードにsとsを含めるのは嫌いsetIntervalです。そこで、私はあなたがそれが最良だと思うところに置くことができる小さなプラグインを作成しました。私はを使用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);
于 2018-01-10T16:20:26.170 に答える
1

.readyjQuery関数を使用する

$("#divToChange").html(newHTML).ready(function () {
                    // run when page is rendered
                    });
于 2020-10-19T14:45:54.840 に答える