Javascript-从URL中获取多个图像的信息,然后将它们插入DOM
Javascript - Get info for multiple images from their URL, then insert them into DOM
我需要从图像的url中获取图像的高度和宽度,并根据图像的方向(纵向或横向)以不同的方式显示该图像。我通过API请求获取图像。
我目前正在使用以下代码,需要帮助的代码从switch
语句的case: 'link'
部分的attachments if statement
内的行var img = new Image;
开始。
FB.api('/', 'POST', {
batch: [
{
method : 'GET',
name : 'user',
relative_url : '/me'
},
{
method: 'GET',
name : 'post-ids',
relative_url: '/group-id/feed?fields=id',
omit_response_on_success : false
},
{
method : 'GET',
name : 'post-data',
relative_url : '?ids={result=post-ids:$.data.*.id}&fields=id,actions,application,from,to,message,message_tags,with_tags,picture,place,properties,source,status_type,link,description,caption,attachments,object_id,type,created_time,updated_time,likes.summary(1),comments.summary(1)',
omit_response_on_success : false
},
{
method : 'GET',
name : 'post-likes',
relative_url : '?ids={result=post-ids:$.data.*.id}/likes?limit=5000',
omit_response_on_success : false
},
{
method : 'GET',
name : 'post-comments',
relative_url : '?ids={result=post-ids:$.data.*.id}/comments?fields=id,actions,application,from,to,message,message_tags,with_tags,picture,place,properties,source,status_type,link,description,caption,attachments,object_id,type,created_time,updated_time,likes.summary(1)&limit=5000',
omit_response_on_success : false
}
]
}, function (response) {
var membody = JSON.parse(response[0].body);
console.log('Successful login for: ' + membody.name);
var posts = JSON.parse(response[1].body);
//console.log(posts);
//console.log(posts.data[0].id);
var feed = JSON.parse(response[2].body);
for(var x = 0; x < posts.data.length; x++) {
//console.log(posts.data[x].id);
var post = feed[posts.data[x].id];
console.log(post);
var entry = '<div class="post">';
var from_id = post.from.id,
from_name = post.from.name,
post_id = post.id,
type = post.type,
created_time = post.created_time;
entry += '<div class="post-title"><a href="http://www.facebook.com/' + from_id + '">' + from_name + '</a> posted a ' + type + ' - <time>' + relativeTime(created_time);
if(post.application) {
var app_id = post.application.id,
app_name = post.application.name,
app_namespace = post.application.namespace;
entry += ' via ' + app_name + '</time></div>';
} else { entry += '</time></div>'; }
switch(post.type) {
case 'status' :
if(post.actions) {
}
if(post.message) {
var message = nl2br(post.message);
if(post.message_tags) {
var message_tags = post.message_tags;
for (var tag in message_tags) {
if (message_tags.hasOwnProperty(tag)) {
var message_tag_id = message_tags[tag][0].id;
message_tag_length = message_tags[tag][0].length;
message_tag_name = message_tags[tag][0].name;
message_tag_offset = message_tags[tag][0].offset;
message_tag_type = message_tags[tag][0].type;
var link = '<a href="http://www.facebook.com/' + message_tag_id + '">' + message_tag_name + '</a>';
message = message.replace(message_tag_name, link);
}
}
}
entry += '<div class="post-message" style="margin:8px 0;">' + message + '</div>';
}
if(post.attachments) {
var att = post.attachments.data[0];
if(att.description) var att_description = att.description;
if(att.type) var att_type = att.type;
if(att.title) var att_title = att.title;
switch(att.type) {
case 'unavailable' :
entry += '<div class="status-att" style="border: 1px solid #ccc; padding: 8px;"><div class="status-att-title" style="font-weight: bold;">' + att_title + '</div><div class="status-att-desc">' + att_description + '</div></div>';
break;
}
}
if(post.to) {
var to_id = post.to.data[0].id,
to_name = post.to.data[0].name;
}
if(post.updated_time) var updated_time = post.updated_time;
if(post.likes) {
}
if(post.comments) {
}
break;
case 'link' :
console.log(JSON.stringify(post));
if(post.attachments) {
var att = post.attachments.data[0];
if(att.type) var att_type = att.type + 'd';
else var att_type = 'posted';
}
entry += '<div class="post-title"><a href="http://www.facebook.com/' + from_id + '">' + from_name + '</a> ' + ((att.type) ? 'shared' : 'posted') + ' a ' + type + ' - <time>' + relativeTime(created_time);
if(post.application) {
var app_id = post.application.id,
app_name = post.application.name,
app_namespace = post.application.namespace;
entry += ' via ' + app_name + '</time></div>';
} else { entry += '</time></div>'; }
if(post.message) {
var message = nl2br(post.message);
if(post.message_tags) {
var message_tags = post.message_tags;
for (var tag in message_tags) {
if (message_tags.hasOwnProperty(tag)) {
var message_tag_id = message_tags[tag][0].id;
message_tag_name = message_tags[tag][0].name;
var link = '<a href="http://www.facebook.com/' + message_tag_id + '">' + message_tag_name + '</a>';
message = message.replace(message_tag_name, link);
}
}
}
entry += '<div class="post-message" style="margin:8px 0;">' + message + '</div>';
}
if(post.attachments) {
var att = post.attachments.data[0];
if(att.subattachments) {
$(att.subattachments.data).each(function (i, item) {
var sub_img_height = item.media.image.height,
sub_img_width = item.media.image.width,
sub_img_src = item.media.image.src,
sub_target = item.target.url,
sub_type = item.type;
entry += '<img src="' + sub_img_src + '"/><br/>---<br/>' + target + '<br/>---<br/>' + title + '<br/>---<br/>';
});
} else {
var target = att.target.url,
title = att.title;
entry += '<a class="link" href="' + (post.link ? post.link : target) + '" style="color: #000; text-decoration: none;">';
if(post.picture) {
// there's a photo
if(post.picture.indexOf('imdb') > -1) {
entry += '<div style="float: left; width: 158px;"><img src="' + post.picture + '" style="width: 158px;"/></div>';
entry += '<div style="float: left; width: 400px; padding: 8px; border-top: 1px solid #ccc; border-right: 1px solid #ccc; border-bottom: 1px solid #ccc;"><div class="link-title" style="padding-bottom: 8px; font-weight: bold;">' + title + '</div>';
if (post.description) entry += '<div class="link-desc" style="padding-bottom: 8px;">' + post.description + '</div>';
if (post.caption) entry += '<div class="link-caption" style="font-size: 14px; text-transform: uppercase; color: #888;">' + post.caption + '</div></div></a>';
entry += '<div class="clear"></div>';
} else {
var picture = post.picture.split('url=');
var img = new Image();
img.onload = function(){
var height = img.height,
width = img.width;
console.log(decodeURIComponent(decodeURI(picture[1])));
console.log('Width: ' + width);
console.log('Height: ' + height);
if(width > height) {
// wide photo, above details
entry += '<img src="' + decodeURIComponent(decodeURI(picture[1])) + '" style="max-width:576px; margin-bottom: 0;" />';
entry += '<div class="link-details" style="padding: 0 8px 8px 8px; border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; border-right: 1px solid #ccc;"><div class="link-title" style="padding-bottom: 8px; font-weight: bold;">' + title + '</div>';
if (post.description) entry += '<div class="link-desc" style="padding-bottom: 8px;">' + post.description + '</div>';
if (post.caption) entry += '<div class="link-caption" style="font-size: 14px; text-transform: uppercase; color: #888;">' + post.caption + '</div></div></a>';
entry += '<div class="clear"></div>';
} else {
// tall photo, left of details
entry += '<div style="float: left; width: 158px;"><img src="' + decodeURIComponent(decodeURI(picture[1])) + '" style="max-width: 158px;"/></div>';
entry += '<div style="float: left; width: 400px; padding: 8px; border-top: 1px solid #ccc; border-right: 1px solid #ccc; border-bottom: 1px solid #ccc;"><div class="link-title" style="padding-bottom: 8px; font-weight: bold;">' + title + '</div>';
if (post.description) entry += '<div class="link-desc" style="padding-bottom: 8px;">' + post.description + '</div>';
if (post.caption) entry += '<div class="link-caption" style="font-size: 14px; text-transform: uppercase; color: #888;">' + post.caption + '</div></div></a>';
entry += '<div class="clear"></div>';
}
}
img.src = decodeURIComponent(decodeURI(picture[1]));
}
} else {
// no picture
entry += '<div class="link-details" style="width: 558px; padding: 8px; border: 1px solid #ccc;"><div class="link-title" style="padding-bottom: 8px;">' + title + '</div>';
if (post.description) entry += '<div class="link-desc" style="padding-bottom: 8px;">' + post.description + '</div>';
if (post.caption) entry += '<div class="link-caption" style="padding-bottom: 8px;">' + post.caption + '</div></div></a>';
}
}
}
break;
case 'photo' :
if(post.message) {
var message = nl2br(post.message);
if(post.message_tags) {
var message_tags = post.message_tags;
for (var tag in message_tags) {
if (message_tags.hasOwnProperty(tag)) {
var message_tag_id = message_tags[tag][0].id;
message_tag_name = message_tags[tag][0].name;
var link = '<a href="http://www.facebook.com/' + message_tag_id + '">' + message_tag_name + '</a>';
message = message.replace(message_tag_name, link);
}
}
}
entry += '<div class="post-message" style="margin:8px 0;">' + message + '</div>';
}
if(post.attachments) {
var att = post.attachments.data[0];
if(att.subattachments) {
var sub = att.subattachments;
} else {
switch(att.type) {
case 'photo' :
entry += '<a href="' + att.target.url + '" target="_blank"><img class="post-photo" style="max-height: 576px; max-width: 576px; margin: 8px 0;" src="' + att.media.image.src + '"/></a>';
break;
case 'unavailable' :
var att = post.attachments.data[0];
entry += '<div class="status-att" style="border: 1px solid #ccc; padding: 8px;"><div class="status-att-title" style="font-weight: bold;">' + att.title + '</div><div class="status-att-desc">' + att.description + '</div></div>';
break;
}
}
}
break;
case 'video' :
break;
}
$('#feed').append(entry);
}
});
可能有一个或多个图像,但每个图像都是API结果中较大对象的一部分,因此这些图像不会一起处理。
我遇到的问题是,这些图像根本没有显示,当我将它们记录到控制台时,只记录一个图像的信息:例如,如果总共有4个图像,则第一个图像会记录4次。
我该怎么解决这一切?我需要能够以不同的方式显示不同方向的图像!
因为图像加载是异步的,所以您根本无法按照尝试从各种onload
处理程序构建entry
变量的方式编写代码。onload()
处理程序的异步定时会打乱使用entry
变量的编码逻辑,并可能打乱操作的顺序。
要处理这样的异步操作,您必须重新组织收集信息的方式和处理信息的时间。在JavaScript中无法绕过这一点。你需要学习如何做到这一点。
如果您展示了尝试使用entry
字符串的更大上下文,那么我们可以帮助您重组整体逻辑,使其以异步方式工作。我们不能仅仅用你在这里展示的代码来做到这一点,因为它必须涉及到你正在做的事情的更大画面。
如果不能测试如此复杂的代码,我不能保证这是没有错误的,但希望你能在这里看到这个概念。
变更摘要:
- 保留一个名为
imgCntr
的计数器,该计数器告诉我们当前有多少图像在飞行中,以便我们知道最后一张图像何时完成 - 将
imgCntr = 1
初始化为保护,这样在请求所有图像之前,它永远不会变为零。它在最后递减以撤消保护计数 - 因为您试图同步构建
entry
字符串,但图像数据不能同步使用,但它需要放在该字符串中的正确位置,所以我们在字符串中插入一个唯一的占位符,看起来像这个"<<img1>>"
。稍后,当图像数据实际可用时,我们可以用所需的HTML替换该唯一标记 - 为了保护在创建临时图像时使用的变量,使它们不会被其他图像覆盖,我们将它们放入自己的闭包中
- 您需要在异步onload处理程序内部访问的任何外部变量(如
post.description
)也必须传递到闭包中,以便为每个映像唯一地保留它们 - 我们不是只在函数末尾执行
$('#feed').append(entry);
,而是在每个img.onload处理程序的末尾进行检查,看看imgCnt现在是否降为零,这意味着所有图像数据都已检索和处理。在函数的末尾,除非没有未处理的图像,否则我们不会插入entry
数据
以下是带有这些更改的代码(未经测试,因为我没有办法实际运行它):
FB.api('/', 'POST', {
batch: [
{
method : 'GET',
name : 'user',
relative_url : '/me'
},
{
method: 'GET',
name : 'post-ids',
relative_url: '/group-id/feed?fields=id',
omit_response_on_success : false
},
{
method : 'GET',
name : 'post-data',
relative_url : '?ids={result=post-ids:$.data.*.id}&fields=id,actions,application,from,to,message,message_tags,with_tags,picture,place,properties,source,status_type,link,description,caption,attachments,object_id,type,created_time,updated_time,likes.summary(1),comments.summary(1)',
omit_response_on_success : false
},
{
method : 'GET',
name : 'post-likes',
relative_url : '?ids={result=post-ids:$.data.*.id}/likes?limit=5000',
omit_response_on_success : false
},
{
method : 'GET',
name : 'post-comments',
relative_url : '?ids={result=post-ids:$.data.*.id}/comments?fields=id,actions,application,from,to,message,message_tags,with_tags,picture,place,properties,source,status_type,link,description,caption,attachments,object_id,type,created_time,updated_time,likes.summary(1)&limit=5000',
omit_response_on_success : false
}
]
}, function (response) {
// imgCntr is set to 1 as a guard so it won't get to zero until all images are done
var imgCntr = 1;
var membody = JSON.parse(response[0].body);
console.log('Successful login for: ' + membody.name);
var posts = JSON.parse(response[1].body);
//console.log(posts);
//console.log(posts.data[0].id);
var feed = JSON.parse(response[2].body);
for(var x = 0; x < posts.data.length; x++) {
//console.log(posts.data[x].id);
var post = feed[posts.data[x].id];
console.log(post);
var entry = '<div class="post">';
var from_id = post.from.id,
from_name = post.from.name,
post_id = post.id,
type = post.type,
created_time = post.created_time;
entry += '<div class="post-title"><a href="http://www.facebook.com/' + from_id + '">' + from_name + '</a> posted a ' + type + ' - <time>' + relativeTime(created_time);
if(post.application) {
var app_id = post.application.id,
app_name = post.application.name,
app_namespace = post.application.namespace;
entry += ' via ' + app_name + '</time></div>';
} else { entry += '</time></div>'; }
switch(post.type) {
case 'status' :
if(post.actions) {
}
if(post.message) {
var message = nl2br(post.message);
if(post.message_tags) {
var message_tags = post.message_tags;
for (var tag in message_tags) {
if (message_tags.hasOwnProperty(tag)) {
var message_tag_id = message_tags[tag][0].id;
message_tag_length = message_tags[tag][0].length;
message_tag_name = message_tags[tag][0].name;
message_tag_offset = message_tags[tag][0].offset;
message_tag_type = message_tags[tag][0].type;
var link = '<a href="http://www.facebook.com/' + message_tag_id + '">' + message_tag_name + '</a>';
message = message.replace(message_tag_name, link);
}
}
}
entry += '<div class="post-message" style="margin:8px 0;">' + message + '</div>';
}
if(post.attachments) {
var att = post.attachments.data[0];
if(att.description) var att_description = att.description;
if(att.type) var att_type = att.type;
if(att.title) var att_title = att.title;
switch(att.type) {
case 'unavailable' :
entry += '<div class="status-att" style="border: 1px solid #ccc; padding: 8px;"><div class="status-att-title" style="font-weight: bold;">' + att_title + '</div><div class="status-att-desc">' + att_description + '</div></div>';
break;
}
}
if(post.to) {
var to_id = post.to.data[0].id,
to_name = post.to.data[0].name;
}
if(post.updated_time) var updated_time = post.updated_time;
if(post.likes) {
}
if(post.comments) {
}
break;
case 'link' :
console.log(JSON.stringify(post));
if(post.attachments) {
var att = post.attachments.data[0];
if(att.type) var att_type = att.type + 'd';
else var att_type = 'posted';
}
entry += '<div class="post-title"><a href="http://www.facebook.com/' + from_id + '">' + from_name + '</a> ' + ((att.type) ? 'shared' : 'posted') + ' a ' + type + ' - <time>' + relativeTime(created_time);
if(post.application) {
var app_id = post.application.id,
app_name = post.application.name,
app_namespace = post.application.namespace;
entry += ' via ' + app_name + '</time></div>';
} else { entry += '</time></div>'; }
if(post.message) {
var message = nl2br(post.message);
if(post.message_tags) {
var message_tags = post.message_tags;
for (var tag in message_tags) {
if (message_tags.hasOwnProperty(tag)) {
var message_tag_id = message_tags[tag][0].id;
message_tag_name = message_tags[tag][0].name;
var link = '<a href="http://www.facebook.com/' + message_tag_id + '">' + message_tag_name + '</a>';
message = message.replace(message_tag_name, link);
}
}
}
entry += '<div class="post-message" style="margin:8px 0;">' + message + '</div>';
}
if(post.attachments) {
var att = post.attachments.data[0];
if(att.subattachments) {
$(att.subattachments.data).each(function (i, item) {
var sub_img_height = item.media.image.height,
sub_img_width = item.media.image.width,
sub_img_src = item.media.image.src,
sub_target = item.target.url,
sub_type = item.type;
entry += '<img src="' + sub_img_src + '"/><br/>---<br/>' + target + '<br/>---<br/>' + title + '<br/>---<br/>';
});
} else {
var target = att.target.url,
title = att.title;
entry += '<a class="link" href="' + (post.link ? post.link : target) + '" style="color: #000; text-decoration: none;">';
if(post.picture) {
// there's a photo
if(post.picture.indexOf('imdb') > -1) {
entry += '<div style="float: left; width: 158px;"><img src="' + post.picture + '" style="width: 158px;"/></div>';
entry += '<div style="float: left; width: 400px; padding: 8px; border-top: 1px solid #ccc; border-right: 1px solid #ccc; border-bottom: 1px solid #ccc;"><div class="link-title" style="padding-bottom: 8px; font-weight: bold;">' + title + '</div>';
if (post.description) entry += '<div class="link-desc" style="padding-bottom: 8px;">' + post.description + '</div>';
if (post.caption) entry += '<div class="link-caption" style="font-size: 14px; text-transform: uppercase; color: #888;">' + post.caption + '</div></div></a>';
entry += '<div class="clear"></div>';
} else {
// create closure to preserve variables uniquely for each image
// and to pass in any outer variables that we need to preserve uniquely for each image
(function(imgCntr, description, caption, title) {
var placeHolder = "<<img" + imgCntr + ">>";
// insert placeholder in the HTML so we can replace it later
entry += placeHolder;
var picture = post.picture.split('url=');
var img = new Image();
img.onload = function(){
var height = img.height,
width = img.width,
html = "";
console.log(decodeURIComponent(decodeURI(picture[1])));
console.log('Width: ' + width);
console.log('Height: ' + height);
if(width > height) {
// wide photo, above details
html += '<img src="' + decodeURIComponent(decodeURI(picture[1])) + '" style="max-width:576px; margin-bottom: 0;" />';
html += '<div class="link-details" style="padding: 0 8px 8px 8px; border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; border-right: 1px solid #ccc;"><div class="link-title" style="padding-bottom: 8px; font-weight: bold;">' + title + '</div>';
if (description) html += '<div class="link-desc" style="padding-bottom: 8px;">' + description + '</div>';
if (caption) html += '<div class="link-caption" style="font-size: 14px; text-transform: uppercase; color: #888;">' + caption + '</div></div></a>';
html += '<div class="clear"></div>';
} else {
// tall photo, left of details
html += '<div style="float: left; width: 158px;"><img src="' + decodeURIComponent(decodeURI(picture[1])) + '" style="max-width: 158px;"/></div>';
html += '<div style="float: left; width: 400px; padding: 8px; border-top: 1px solid #ccc; border-right: 1px solid #ccc; border-bottom: 1px solid #ccc;"><div class="link-title" style="padding-bottom: 8px; font-weight: bold;">' + title + '</div>';
if (description) html += '<div class="link-desc" style="padding-bottom: 8px;">' + description + '</div>';
if (caption) html += '<div class="link-caption" style="font-size: 14px; text-transform: uppercase; color: #888;">' + caption + '</div></div></a>';
html += '<div class="clear"></div>';
}
// put this HTML into the right place in the entry string
entry = entry.replace(placeHolder, html);
--imgCntr;
// if all images are done
if (imgCntr <= 0) {
$('#feed').append(entry);
}
}
img.src = decodeURIComponent(decodeURI(picture[1]));
})(imgCntr++, post.description, post.caption, title);
}
} else {
// no picture
entry += '<div class="link-details" style="width: 558px; padding: 8px; border: 1px solid #ccc;"><div class="link-title" style="padding-bottom: 8px;">' + title + '</div>';
if (post.description) entry += '<div class="link-desc" style="padding-bottom: 8px;">' + post.description + '</div>';
if (post.caption) entry += '<div class="link-caption" style="padding-bottom: 8px;">' + post.caption + '</div></div></a>';
}
}
}
break;
case 'photo' :
if(post.message) {
var message = nl2br(post.message);
if(post.message_tags) {
var message_tags = post.message_tags;
for (var tag in message_tags) {
if (message_tags.hasOwnProperty(tag)) {
var message_tag_id = message_tags[tag][0].id;
message_tag_name = message_tags[tag][0].name;
var link = '<a href="http://www.facebook.com/' + message_tag_id + '">' + message_tag_name + '</a>';
message = message.replace(message_tag_name, link);
}
}
}
entry += '<div class="post-message" style="margin:8px 0;">' + message + '</div>';
}
if(post.attachments) {
var att = post.attachments.data[0];
if(att.subattachments) {
var sub = att.subattachments;
} else {
switch(att.type) {
case 'photo' :
entry += '<a href="' + att.target.url + '" target="_blank"><img class="post-photo" style="max-height: 576px; max-width: 576px; margin: 8px 0;" src="' + att.media.image.src + '"/></a>';
break;
case 'unavailable' :
var att = post.attachments.data[0];
entry += '<div class="status-att" style="border: 1px solid #ccc; padding: 8px;"><div class="status-att-title" style="font-weight: bold;">' + att.title + '</div><div class="status-att-desc">' + att.description + '</div></div>';
break;
}
}
}
break;
case 'video' :
break;
}
// decrement guard count, since all images have been at least requested now
--imgCntr;
// if there was no async part, then entry is done so it can be directly appended
// if there was an async part, then it will get appended in the async callbacks when the last one of them is done
if (imgCntr <= 0) {
$('#feed').append(entry);
}
}
});
仅供参考,我认为这里使用的技术有点像黑客。如果从头开始,我不会这样写代码,但考虑到代码的数量和我无法测试我写的任何东西,用不同的方式重写对我来说是不现实的。
- firefox扩展可以修改HTML文档的DOM,然后保存为HTML
- 找出两个dom元素的差异,然后使它们相同
- C#WebBrowser控件-使用DOM创建和修改javascript变量,然后使用Applet读取它
- Metor:将html保存为字符串,然后将其转换为DOM节点
- 在一个简单的jquery幻灯片中,我的类到达图像的末尾,然后从DOM的边缘掉下来
- Chrome扩展程序获取DOM文本并在弹出窗口中显示.html然后单击按钮
- JS - 从表单中获取输入并将其放入数组中,然后将新行附加到表中(DOM)
- 如何将元素添加到DOM中,然后在Javascript/JQuery中引用那些添加的元素
- Javascript-从URL中获取多个图像的信息,然后将它们插入DOM
- 单击时将html存储到变量中,从DOM中删除,然后在另一次单击时将其放回
- 在Javascript DOM中,可以将焦点设置为一个项,然后在文档中呈现该项吗
- 遍历DOM,然后连接结果文本值
- 使用jquery添加一个字符串到DOM,然后使用jquery选择器找不到它
- 将XML文件导入HTML页面,然后我想在导入的XML标签上使用DOM
- jQuery -如果一个类出现在DOM上,然后单击包装器再次删除该类
- 高度:自动计算错误,如果元素隐藏时dom加载,然后显示
- 将HTML字符串发送到服务器,然后我可以使用DOM与它交互吗?可以在上面使用jQuery吗?
- Angular的ng-click会在ng-repeat中更新$scope,然后使用$apply来更新dom
- 尝试在window上设置offsetTop.滚动,然后根据被触摸的幻灯片遍历DOM
- 在AngularJS中简单的dom操作——点击一个按钮,然后将焦点设置为输入元素