【问题标题】:Do something when all dynamically created images have loaded加载所有动态创建的图像后执行某些操作
【发布时间】:2023-03-03 03:28:01
【问题描述】:

我想做的是创建一个动态的图像墙。

我正在做的是这样的:

  1. 调用 API 以获得一些响应。根据响应创建对象数组
  2. 基于数组,为每个包含img 的对象制作 HTML 元素。
  3. 创建所有这些 HTML 元素后,将其附加到 DOM,然后调用最终函数。

这是我到目前为止的内容(截断以了解重点):

编辑:代码发生了一些变化。滚动到问题底部以获取当前代码的链接。

// based on one post, construct the html and return it
function getOneHtml(post, w) {
  console.log("getting one html");

  var outerDiv = $("<div>", {class: "brick"});
  outerDiv.width(w);

  var img = $("<img />");
  img.attr("src", post.img_src);

  img.on('load', function() {
    console.log("img loaded");
    var ratio = this.width / w;
    h = this.height / ratio;

    $(this).css({'height': h});

    // ...
    // ...
    // create the element

    // an alternative I'm using for now is directly append
    // the created HTML onto the page, but that results
    // in a kinda messy interface.
    return outerDiv[0].outerHTML;
  });
}

// queries an api and then calls callback after everything is done
function requestData(subreddit, callback) {
  // array of objects with link to image, post title, link to reddit
  posts = [];

  var w = $(window).innerWidth() / 3, 
      html = ''; // holds all of the inner HTML for all elements

  $.get("url here", function(data) {
    var arr = data.data.children;

    arr.forEach(function(res_post) {
      console.log("looping in requestData");
      // prepare a post object
      // ...
      // ...

      html += getOneHtml(post, w); // get the HTML for this post
    });

    // this should happen after everything else is done
    console.log("calling callback");
    callback(html);
  });
}

// complete the DOM
function makeWall(html) {
  console.log("making wall");
  // do stuff
}

现在控制台中的程序轨迹是这样的:

looping in requestData
getting one html 
looping in requestData
getting one html 
... // bunch of times
calling callback
making wall
(20) img loaded

所以现在的问题是,在加载每个图像之前都没有准备好 HTML,因此它实际上并没有附加到 DOM。

如何确保事情按照我希望的顺序发生?我尝试将代码重构为更多的异步风格,但没有奏效(不是我的强项)。

我也尝试查看$.Deferred,但我不明白它,以及如何将它集成到我的代码中。

感谢任何帮助。

编辑:

我认为看看我在做什么可能会有所帮助:http://karan.github.io/griddit/

加载时,我希望图像先加载,然后淡入。目前,它们显示,然后隐藏,然后淡入。这是来源:https://github.com/karan/griddit/blob/gh-pages/js/main.js

此外,如果您向下滚动一页或两页,然后再向上滚动,一些图像会显示在其他图像后面。

【问题讨论】:

标签: javascript jquery asynchronous jquery-events jquery-deferred


【解决方案1】:

您可以使用.done(),如.done() 上的the jQuery API documentation 中所述,具体说明了如何将.done()$.get() 一起使用。

很简单:

$.get( "test.php" ).done(function() {
  alert( "$.get succeeded" );
});

具体...

如上面提供的 API 文档链接所示,您可以将 .done() 调用以菊花链形式连接在一起。

$.get(url,handler).done(function(){console.log('calling callback')},callback);

【讨论】:

  • .done 被点击后仍然加载图像。所以这不是很有帮助。
  • 其实,你可以把.done()的电话串起来!
【解决方案2】:

注意,不确定包含的插件的功能,例如,#grid 布局, css 等图像 widthheight#grid 布局未解决,保留现有部分重新组合以尝试清晰流动。

以下内容仅用于满足// Do something when all dynamically created images have loaded 的要求。在 jsfiddle 上查看控制台

另请注意,jsfiddle 格式问题。为了测试作品,从原始帖子的链接中提取了 2 个插件。尝试了 jsfiddle 的 TidyUp 功能,它插入了换行符。

片段可能需要重新格式化;尽管根据原始帖子,当前的 jsfiddle 确实提供了 callback 功能。再次,请参阅控制台。感谢分享。

更新

      $(function() {
        // the name of the last added post 
        var last_added = '';
        // to control the flow of loading during scroll var scrollLoad = true;
        var q = 'cats'; 
        var callbacks = $.Callbacks();
        // callback,
        // Do something when all dynamically created images have loaded
        var callback = function (cb) {
          return console.log( cb||$.now() )
        };
        callbacks.add(callback);
        function getOneHtml(post, w, count){ 
          var img = $("<img>", {
                        "src" : post.img_src,
                        "width" : w 
                    });
        img.on('load', function(e) { 
          var ratio = e.target.width / w;
          h = e.target.height / ratio;
          $(e.target).css('height',h)
        });

        var link = $("<a>", {
                        "href" : post.permalink,
                        "target" : "_blank",
                        "html" : img 
                   });

        var outerDiv = $("<div>", {
                        "class" : "brick",
                        "style" : "width:" + w
                       });

        $.when($(outerDiv).appendTo("#grid"),
        $(link),
        count)
        .then(function(div, _link, _count) {
          // `image` `fadeIn`; adjustable
          $(_link).appendTo($(div)).hide(0).fadeIn(2000);
          return _count
        })
        .always(function(_count){
          callbacks.fireWith(window, [_count + " images appended to grid at " + $.now()])
        });
        };

        function requestData(subreddit,callback) {
        //array of objects with link to image, post title,link to reddit
          posts=[];
          var w = $(window).innerWidth() / 3;
          html = '';
          $.ajax({
            type : 'get',
            url : "http://api.reddit.com/r/" + subreddit + "/hot.json?&after=" + last_added,
            beforeSend : function () {
              $("#searchterm").addClass("loadinggif");
            },
            complete : function () {
              $("#searchterm").removeClass("loadinggif");
            },
            success : function (data) {
              var arr = data.data.children;
              var count = null;
              arr.forEach(function(res_post) {
                if(!res_post.data.is_self&&(/\.(gif|jpg|jpeg|tiff|png)$/i).test(res_post.data.url)) {
                  // `images` count
                  ++count;
                  var post = {
        'title' : res_post.data.title,
        'img_src': res_post.data.url,
        'name' : res_post.data.name,
        'permalink': 'http://reddit.com' + res_post.data.permalink
        };
             getOneHtml(post, w, count);
        }
        last_added = res_post.data.name;
        });
        scrollLoad = true;
        // callback,
        // Do something when all dynamically created images have loaded
        // see `console`; adjustable
        callbacks.fireWith( window, [$(".brick img").size() + " appended to grid, callback at " + $.now()]);
        }});
        }

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                // function makeWall() {}
})

jsfiddle http://jsfiddle.net/guest271314/ggsY9/

【讨论】:

  • 所以我有这个,但你假设我想要一个 50px x 50px 的图像。我想获取图像的尺寸,这意味着我需要另一个 onload 回调。
  • data.data.children ,img 维度内的实际数据未在原帖中提供。 post 和 jsfiddle 上的文章仅作为示例 pattern 或模板;可调整以满足所需的图像尺寸或其他参数。上面的部分和 jsfiddle 的相关部分可能是 .bricklength 存储为变量的部分 - 可以检查以确定是否已加载来自 $.get() 调用的所有图像 - 然后继续 @987654339 @ 功能。也许发布实际的data.data.children 响应,并在原始帖子中展示 jsfiddle 的问题?
  • 我认为看看我在做什么可能会有所帮助:karan.github.io/griddit 当你加载时,我希望图像先加载,然后淡入。目前,它们显示出来,然后隐藏和然后淡入。这是来源:github.com/karan/griddit/blob/gh-pages/js/main.js。此外,如果您向下滚动一页或两页,然后再向上滚动,一些图像会显示在其他图像后面。
  • 谢谢。将实际的append 部分添加到原始帖子中可能有帮助吗?目前看来,这个问题的查看者没有可查看的那篇文章(除非阅读上面的评论) - 其中img 附加到文档中。无论是否“凌乱”(阅读:主观?),提供该部分可能会改变提供答案的方法?请注意,似乎超过20 图像 附加到文档?将再次浏览 repo,原始帖子。感谢分享
猜你喜欢
  • 1970-01-01
  • 2011-09-26
  • 2012-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多