Javascript 加载所有动态创建的图像后执行某些操作
我想做的是创建一个动态的图像墙 我现在做的是:Javascript 加载所有动态创建的图像后执行某些操作,javascript,jquery,asynchronous,jquery-events,jquery-deferred,Javascript,Jquery,Asynchronous,Jquery Events,Jquery Deferred,我想做的是创建一个动态的图像墙 我现在做的是: 调用API以获得一些响应。基于响应创建对象数组 基于数组,为每个对象创建HTML元素,其中也包含img 创建所有这些HTML元素后,将其附加到DOM,并调用最后一个函数 这就是我到目前为止所做的(为了让大家明白这一点,我将其截断): 编辑:代码有点变化。滚动至问题底部,以获得当前代码的链接。 // based on one post, construct the html and return it function getOneHtml(post
img
// 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
}
所以现在的问题是,在加载每个图像之前,HTML是没有准备好的,因此它实际上没有连接到DOM
我如何确保事情按我希望的顺序发生?我尝试将代码重构成更为异步的风格,但没有成功(这不是我的强项)
我还试着查看了$。延迟,但我不理解它,以及如何将它集成到我的代码中
感谢您的帮助
编辑:
我想这可能有助于了解我在做什么:
加载时,我希望先加载图像,然后淡入。目前,它们先出现,然后隐藏,然后淡入。以下是来源:
此外,如果向下滚动一到两页,然后向上滚动,一些图像会显示在其他图像后面。您可以使用.done()
,如中所述。done()
特别说明了如何将.done()
与$.get()一起使用
简单到:
$.get( "test.php" ).done(function() {
alert( "$.get succeeded" );
});
具体地说。。。
正如上面提供的API文档链接所示,您可以同时调用菊花链.done()
$.get(url,handler).done(function(){console.log('calling callback')},callback);
注意,不确定所包含插件的功能,例如,#grid
布局,
css
等。图像宽度
、高度
和网格
布局未寻址,除了为保持流程清晰而重新组合的现有片段
当所有动态创建的图像都加载了
要求时,请执行以下操作。请参阅JSFIDLE上的控制台
另请注意,JSFIDLE格式的问题。为了测试这件作品,从原始帖子的链接中引入了2个插件。尝试了jsfiddle的TidyUp
功能,该功能插入了换行符
工件可能需要重新格式化;尽管目前的JSFIDLE确实提供了回调
功能,正如最初的帖子所说。同样,请参见控制台。谢谢分享
更新
$(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() {}
})
$(函数(){
//上次添加的帖子的名称
var last_added=“”;
//在scroll var scrollLoad=true期间控制加载流;
var q=‘猫’;
var callbacks=$.callbacks();
//回拨,
//加载所有动态创建的图像后执行某些操作
变量回调=函数(cb){
返回console.log(cb | |$.now())
};
callbacks.add(callback);
函数getOneHtml(post,w,count){
var img=$("你读过和吗?也许这有助于更好地理解承诺。getOneHtml
目前有效吗?callback
和makeWall
的作用是什么?相同,相似吗?@FelixKling是的,但正如我说的,我并没有真正理解它。@guest271314是的getOneHtml
工作得很好。在这种情况下,>回调
是makeWall
。如果没有设置其他维度,它会起作用。请参阅此处的演示:在点击.done
后仍然加载图像。因此这不是很有帮助。实际上,您可以链接.done()
互相调用!所以我有了这个,但是你假设我想要一个50px x 50px的图像。我想要一个图像的尺寸,这意味着我需要另一个onload
回调。data.data.children
,img
尺寸中的实际数据在原始帖子中没有提供。帖子中的文章和JSFIDLE are仅作为示例图案或模板;可调整以满足所需的图像尺寸或其他参数。上面和JSFIDLE的相关部分可能是.brick
类长度
存储为变量的部分-可以检查以确定$.get()中的所有图像
call loaded-然后继续执行callback
函数。可能会在原始帖子中发布实际的data.data.children
响应和JSFIDLE演示问题?我想这可能有助于了解我在做什么:加载时,我希望先加载图像,然后淡入。目前,它们会显示,然后隐藏,然后淡入。来源如下:。此外,如果你向下滚动一到两页,然后向上滚动,一些图像会显示在其他图像的后面。谢谢。可能有助于将实际的附加部分添加到原始帖子中?目前看来,此问题的浏览者没有该文章可供查看(除非阅读上述评论)-文档中附加了img
。无论是否“凌乱”(阅读:主观?),提供该部分可能会改变提供答案的方式?注意,文档中附加了20多张img
图像?将再次浏览repo、原始帖子。感谢分享
$(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() {}
})