【问题标题】:document ready after dom manipulationdom 操作后文档准备就绪
【发布时间】:2012-10-16 12:36:53
【问题描述】:

我正在使用Phonegap 做一个应用程序,并且我正在使用自建的幻灯片转换来更改页面。 它的工作原理是这样的:

每个页面都是一个div,具有 100% 的高度和宽度,所以如果我更改页面,我将下一个 div 设置为当前活动的右侧并将两者都滑动到左侧。

现在的问题是:滑动工作正常,但它是在右侧div 的内容完全加载之前执行的。所以右边的div滑入空白,几百毫秒后才会出现内容。

我用document.ready 尝试过,但据我所知,此事件仅在第一次加载DOM 时执行。

在我用Javascript 操作DOM 后,有人知道我如何等待DOM 再次完全呈现吗?

【问题讨论】:

  • 在启动动画之前,您需要遍历新页面上的图像并确保它们都具有真实的 .height 属性(意味着它们已完成加载)。

标签: javascript mobile dom-manipulation ready


【解决方案1】:

在您的情况下,您可以在下一个 div 的内容中选择一个元素,并使用$(...).length 继续检查它。如果值 > 0,则 DOM 已加载,您可以更改页面。

你可能想试试这个功能:

Function.prototype.deferUntil = function(condition, timeLimit) {
    var ret = condition();

    if (ret) {
        this(ret);
        return null;
    }

    var self = this, interval = null, time = ( + new Date());
    interval = setInterval(function() {
        ret = condition();
        if (!ret) {
            if (timeLimit && (new Date() - time) >= timeLimit) {
                // Nothing
            } else {
                return;
            }
        }
        interval && clearInterval(interval);
        self(ret);
    }, 20);

    return interval;
};

用法:

(function() {
    console.log('Next page loaded');
}).deferUntil(function() {
    return $('#nextDiv').length > 0;
}, 3000);

上面的例子会每隔 20 毫秒(不超过 3 秒)检查一次有 id="nextDiv" 的 div。加载 div 后,控制台会显示“已加载下一页”。

你可以试试这个fiddle

【讨论】:

    【解决方案2】:

    有一个 DOMNodeInserted 事件应该像 document.ready 一样工作,但只针对单个 DOM 节点。但它已被弃用并且有很多问题。 StackOverflow 用户找到了一个在所有移动浏览器中运行良好的替代方案:Alternative to DOMNodeInserted

    【讨论】:

      【解决方案3】:

      这是一个函数,一旦所有与 jquery 选择器匹配的图像都完成加载,就会触发回调

      Js Fiddle Sample

      //css
      input {width: 420px;}
      
      //html
      <div id="container"></div>
          <input type="text" value="http://goo.gl/31Vs" id="img1">
          <br><input type="text" value="http://wall.alafoto.com/wp-content/uploads/2010/11/Fractal-Art-Wallpapers-09.jpg" id="img2">
          <br><input type="text" value="http://pepinemom.p.e.pic.centerblog.net/ssg8hv4s.jpg" id="img3">
          <br><input type="button" value="Load images" name="loadImages" id="btn">
      
              <div id="message"></div>
      
      //javascript
      
      //Call a function after matching images have finished loading
      function imagesLoadedEvent(selector, callback) {
          var This = this;
          this.images = $(selector);
          this.nrImagesToLoad = this.images.length;
          this.nrImagesLoaded = 0;
      
          //check if images have already been cached and loaded
          $.each(this.images, function (key, img) {
              if (img.complete) {
                  This.nrImagesLoaded++;
              }
              if (This.nrImagesToLoad == This.nrImagesLoaded) {
                  callback(This.images);
              }
          });
      
          this.images.load(function (evt) {
              This.nrImagesLoaded++;
              if (This.nrImagesToLoad == This.nrImagesLoaded) {
                  callback(This.images);
              }
          });
      }
      
      $("#btn").click(function () {
          var c = $("#container"), evt;
          c.empty();
          c.append("<img src='" + $("#img1").val() + "' width=94>");
          c.append("<img src='" + $("#img2").val() + "' width=94>");
          c.append("<img src='" + $("#img3").val() + "' width=94>");
          evt = new imagesLoadedEvent("img", allImagesLoaded);
      });
      
      function allImagesLoaded(imgs) {
          //this is called when all images are loaded
          $("#message").text("All images loaded");
          setTimeout(function() {$("#message").text("");}, 2000);
      }
      

      【讨论】:

        【解决方案4】:

        您可以使用 jQuery ajax 加载内容,并在成功时使用幻灯片运行函数。

        $("#page1").load('page2.html', function() {
            //do your custom animation here
        });
        

        尽管我不完全确定您是如何加载内容的。它是静态的(已经存在但只是不可见?)还是加载了 ajax?

        编辑:您可以在几毫秒内执行一个小的 .delay() 或 setTimeout,然后为滑动设置动画。

        【讨论】:

        • 感谢您的回答。内容在手机数据库里,所​​以我从那里取出来,插入到div中,然后滑进去。设置超时的东西是,大页面大约需要600ms,而小页面大约需要50ms .我不想为小页面等待 600 毫秒,因为大页面需要这个时间。内容有时是静态的,有时是从 javascript 变量中加载出来的。
        • 数据库查询完成后是否有回调可以等待?如果使用ajax,可以使用$(document).on('ajaxComplete', function(){/*做动画*/});
        【解决方案5】:

        我在制作砌体网站时遇到了类似的问题。我使用 window.onload 在初始化 masonry.js 之前等待所有元素完成加载。我还将window.onload 放在.onchange 函数中,每次调整视口大小时都会触发它。

        我相信应用类似的原则会解决您的问题。

        【讨论】:

          【解决方案6】:

          试一次

          $(window).bind('load',function(){
          //code
          });
          

          【讨论】:

            【解决方案7】:

            也许你可以在你的 div 上设置一个事件。

            myDiv.onafterupdate = myHandler;
            
            function myHandler() {
               // Do here what you want to do with the updated Div.
            }
            

            这对你有帮助吗?

            【讨论】:

              【解决方案8】:

              在 jquery 中,您可以在 DOM 操作代码之后使用 $()。

              $(function(){
              //code that needs to be executed when DOM is ready, after manipulation
              });
              

              $() 调用一个函数,该函数要么注册一个 DOM 就绪回调(如果将函数传递给它),要么从 DOM 返回元素(如果将选择器字符串或元素传递给它)

              你可以在这里找到更多
              difference between $ and $() in jQuery
              http://api.jquery.com/ready/

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-03-04
                • 2016-07-17
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多