使用Javascript

时间:2017-04-15 19:40:30

标签: javascript css

我正试图找到一种方法来检测图像的方向(横向或纵向)。

HTML只包含一些已经填充了源的img标签。然后脚本应该检测方向并将图像添加到动态创建的div作为缩略图。

我一直在使用的脚本就是这个(在这里找到它)

    for (i = 0; i < pics.length; i++) {
      pics[i].addEventListener("load", function() {
        if (this.naturalHeight > this.naturalWidth) {
          this.classList.add("portrait")
        } else {
          this.classList.add("landscape")
        }
     })
    }

现在,这在首次加载页面时通常可以正常工作。但是,当刷新时,它表现不正常,为某些图像添加正确的类,而不向其他图像添加任何类。

我也试过这个

for (i = 0; i < pics.length; i++) {
  var img = pics[i];
  var width = img.naturalWidth;
  var height = img.naturalHeight;
  if (height > width) {
    img.classList.add("portrait")
  } else {
    img.classList.add("landscape")
  }
}

这也无法预测。所有图像都会添加一个类,但有些图像会出错。

我猜测问题可能来自图片未在脚本运行之前完全加载,因此脚本无法正确测量它们,但我不确定。无论如何,我真的不知道如何修复它。

为了了解我的目标,这里是该页面的链接: http://pieterwouters.tumblr.com/

任何想法都非常感激。

3 个答案:

答案 0 :(得分:2)

如果在调用pic.addEventListener("load", ...)时图像已加载,则不会触发加载事件处理程序。如this answer中所述,pic.complete为真时,您应该调用它。

&#13;
&#13;
var pics = document.querySelectorAll("img");
var pic;

for (i = 0; i < pics.length; i++) {
  pic = pics[i];
  if (pic.complete) {
    // The image is already loaded, call handler
    checkImage(pic);
  } else {
    // The image is not loaded yet, set load event handler
    pic.addEventListener("load", function() {
      checkImage(this);
    })
  }
}

function checkImage(img) {
  if (img.naturalHeight > img.naturalWidth) {
    img.classList.add("portrait")
  } else {
    img.classList.add("landscape")
  }
}
&#13;
img {
  border: 1px solid;
}

.landscape {
  border-color: red;
}

.portrait {
  border-color: blue;
}
&#13;
<img src="//placehold.it/50x100">
<img src="//placehold.it/200x100">
&#13;
&#13;
&#13;

感谢Ricky。我从他的回答中借用了图像链接和样式属性。

答案 1 :(得分:1)

为了更安全但更昂贵的方法,您可以复制内存中的图像并添加相应的类。

const images = [...document.querySelectorAll('img')].map(el => {
  return new Promise((resolve, reject) => {
    let img = new Image();
    img.addEventListener('load', function() {
      const {
        naturalHeight,
        naturalWidth
      } = img;
      if (naturalHeight > naturalWidth) el.classList.add("portrait");
      else el.classList.add("landscape");
      img = null; //GC
      resolve();
    });
    img.src = el.src;
  });
});
img {
  border: 1px solid;
}

.landscape {
  border-color: red;
}

.portrait {
  border-color: blue;
}
<img src="//placehold.it/50">
<img src="//placehold.it/50x100">
<img src="//placehold.it/200x100">
<img src="//placehold.it/50x60">
<img src="//placehold.it/10x30">
<img src="//placehold.it/50x20">

答案 2 :(得分:0)

感谢您的帮助!

ConnorsFan,根据你之前的评论我添加了一个部分来考虑已经加载的图像并提出了这个

// forgot to mention this part in my original post
var pics = document.getElementsByTagName("img");

for (i = 0; i < pics.length; i++) {
    pics[i].addEventListener("load", function() {
        if (this.naturalHeight > this.naturalWidth) {
            this.classList.add("portrait")
        } else {
            this.classList.add("landscape")
        }
     })  
     if (pics[i].complete) {
         if (pics[i].naturalHeight > pics[i].naturalWidth) {
             pics[i].classList.add("portrait")
         } else {
             pics[i].classList.add("landscape")
         }
     }
 }

哪个有效,你的解决方案似乎更优雅,所以我可能会使用那个。