admin管理员组文章数量:1328567
I'm trying to find a way to detect the orientation of images (landscape or portrait).
The HTML simply contains a few img tags with source already filled in. The script should then detect the orientation and add the images to dynamically created divs acting as thumbnails.
The script I've been using is this (found it on here somewhere)
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")
}
})
}
Now this usually works fine when first loading the page. When refreshing however, it behaves erratically, adding the right class to some images and not adding any class at all to others.
I also tried this
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")
}
}
Which also works unpredictably. All images get a class added to them, but some get the wrong one.
I'm guessing the problems might e from the images not pletely loading before the script runs and thus the script not being able to measure them correctly, but I'm not sure. Anyhow, I don't really know how to fix it either.
To give an idea of what I'm going for, here's a link to the page: /
Any ideas much appreciated.
I'm trying to find a way to detect the orientation of images (landscape or portrait).
The HTML simply contains a few img tags with source already filled in. The script should then detect the orientation and add the images to dynamically created divs acting as thumbnails.
The script I've been using is this (found it on here somewhere)
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")
}
})
}
Now this usually works fine when first loading the page. When refreshing however, it behaves erratically, adding the right class to some images and not adding any class at all to others.
I also tried this
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")
}
}
Which also works unpredictably. All images get a class added to them, but some get the wrong one.
I'm guessing the problems might e from the images not pletely loading before the script runs and thus the script not being able to measure them correctly, but I'm not sure. Anyhow, I don't really know how to fix it either.
To give an idea of what I'm going for, here's a link to the page: http://pieterwouters.tumblr./
Any ideas much appreciated.
Share Improve this question asked Apr 15, 2017 at 19:40 Pieter WoutersPieter Wouters 451 silver badge4 bronze badges 3- Is your script at the top or bottom of the page? – inarilo Commented Apr 15, 2017 at 19:48
- This scrip should be executed adter the page has finished loading. How do you execute it now? – Mr Zach Commented Apr 15, 2017 at 20:11
- It's at the bottom of the page, or at least as far down as tumblr will allow (since it adds some automatic script of its own), so in theory the images should load before the script. – Pieter Wouters Commented Apr 15, 2017 at 20:29
3 Answers
Reset to default 4If the image is already loaded when you call pic.addEventListener("load", ...)
, the load event handler will not be triggered. You should call it if pic.plete
is true, as suggested in this answer.
var pics = document.querySelectorAll("img");
var pic;
for (i = 0; i < pics.length; i++) {
pic = pics[i];
if (pic.plete) {
// 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")
}
}
img {
border: 1px solid;
}
.landscape {
border-color: red;
}
.portrait {
border-color: blue;
}
<img src="//placehold.it/50x100">
<img src="//placehold.it/200x100">
Thanks to Ricky. I borrowed the image links and the style attributes from his answer.
For a safer but more expensive approach you could duplicate the images in memory and add the corresponding class.
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">
Thanks for the help!
ConnorsFan, based on your earlier ment I added a part to take into account already loaded images and came up with this
// 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].plete) {
if (pics[i].naturalHeight > pics[i].naturalWidth) {
pics[i].classList.add("portrait")
} else {
pics[i].classList.add("landscape")
}
}
}
Which works, your solution seems a bit more elegant though so I'll probably use that one.
本文标签: cssDetecting orientation of images with JavascriptStack Overflow
版权声明:本文标题:css - Detecting orientation of images with Javascript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742259254a2442204.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论