Javascript-从URL中获取多个图像的信息,然后将它们插入DOM

Javascript - Get info for multiple images from their URL, then insert them into DOM

本文关键字:然后 DOM 插入 信息 URL 获取 图像 Javascript-      更新时间:2023-09-26

我需要从图像的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字符串的更大上下文,那么我们可以帮助您重组整体逻辑,使其以异步方式工作。我们不能仅仅用你在这里展示的代码来做到这一点,因为它必须涉及到你正在做的事情的更大画面。


如果不能测试如此复杂的代码,我不能保证这是没有错误的,但希望你能在这里看到这个概念。

变更摘要:

  1. 保留一个名为imgCntr的计数器,该计数器告诉我们当前有多少图像在飞行中,以便我们知道最后一张图像何时完成
  2. imgCntr = 1初始化为保护,这样在请求所有图像之前,它永远不会变为零。它在最后递减以撤消保护计数
  3. 因为您试图同步构建entry字符串,但图像数据不能同步使用,但它需要放在该字符串中的正确位置,所以我们在字符串中插入一个唯一的占位符,看起来像这个"<<img1>>"。稍后,当图像数据实际可用时,我们可以用所需的HTML替换该唯一标记
  4. 为了保护在创建临时图像时使用的变量,使它们不会被其他图像覆盖,我们将它们放入自己的闭包中
  5. 您需要在异步onload处理程序内部访问的任何外部变量(如post.description)也必须传递到闭包中,以便为每个映像唯一地保留它们
  6. 我们不是只在函数末尾执行$('#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);
    }
  }
});

仅供参考,我认为这里使用的技术有点像黑客。如果从头开始,我不会这样写代码,但考虑到代码的数量和我无法测试我写的任何东西,用不同的方式重写对我来说是不现实的。

相关文章: