title: Will append() return when an element has been added to the page and is ready? What could be causing this?
body: <p>I have a div called imageContainer. imageContainer contains an img, I append a div that contains 256 child divs with background images to imageContainer and then remove the img. I do this like so:</p>
  
  <pre><code>  $imageContainer.append($container);
    $imgCurrent.hide();
  </code></pre>
  
  <p>I'm having an issue where in Chrome the div flickers for a split second and you can see what is behind imageContainer. If I change the code to the following then it works without a flicker:</p>
  
  <pre><code>  $imageContainer.append($container);
    setTimeout(function () {
        $imgCurrent.hide();
    }, 100); // 50ms still flickers
  </code></pre>
  
  <p>What I think might be happening is that the div gets appended, the img gets removed and then the child divs are rendered. The only thing is it all happens too fast to see/debug. I did think that the child divs were appearing but the background images were not beeing rendered quick enough. However I tried setting the background-color of each child div to red but still just saw what was behind instead of seeing any red. </p>
  
  <p>My only conclusion is that Chrome is taking a while to add the divs to the page, is there a way of checking for this? I don't want to just use setTimeout, could I just use <code>.ready()</code> or <code>.load()</code> (Not sure if <code>load()</code> will work for background-image, will it?)</p>
  
  <p>Thanks,</p>
  
  <p>Joe</p>
  
  <p>P.S. The images that are displayed are in the browser cache so there is no delay in actually fetching them.</p>
  
  <p>EDIT: New code which observes mutations - still doesn't work</p>
  
  <pre><code> function transition(duration, callback) {
      var runWhenReady = function () {
          $imgCurrent.hide();
  
          var transitionName;
          if (_args.randomTransition) {
              if (transitionIndex % _args.transitions.length == 0) {
                  shuffledTransitions = shuffle(_args.transitions);
              }
              transitionName = shuffledTransitions[transitionIndex % _args.transitions.length];
          } else {
              transitionName = _args.transitions[transitionIndex % _args.transitions.length];
          }
          transitionIndex++;
  
          runTransition(transitionName, $grid, x, y, duration, function () {
              var waitForAnimationToEnd = setInterval(function () {
                  // Although the set interval timer used in the trasition  has finished there may still be animations running
                  if (!$grid.children().is(':animated')) {
                      $grid.remove();
                      callback();
                      clearInterval(waitForAnimationToEnd);
                  }
              }, 20);
          });
      };
  
      // The more cells we have the better it looks but it lags in ff/ie
      var x = 16;
      var y = 16;
  
      var $grid = $('&lt;div /&gt;');
      $imageContainer.append($grid);
  
      // If the browser supports it then wait for the dom elements to load if not then just wait a while
      if (typeof (MutationObserver) == 'undefined') {
          setTimeout(runWhenReady, 200);
      } else {
          //TODO: Not sure if this works yet - if not then just use the code above
          $grid.data('mutations', 0);
          var observer = new MutationObserver(function (mutations) {
              // In Chrome I get all of the mutations at once but in some browsers / scenarios there may be multiple calls to this function so we maintain a counter
              $grid.data('mutations', parseInt($grid.data('mutations')) + mutations.length);
              if (parseInt($grid.data('mutations')) &gt;= x * y) {
                  observer.disconnect();
                  runWhenReady();
              }
          });
          var config = { attributes: false, childList: true, characterData: false };
          observer.observe($grid[0], config);
      }
  
      currentImageToGrid($grid, x, y);
  }
  </code></pre>