2017-04-15 126 views
2

我试图找到一种方法来检测图像(风景或人像)的方向。使用Javascript检测图像的方向

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/

任何想法非常赞赏。

+0

您的脚本位于页面顶部还是底部? – inarilo

+0

这个脚本应该在页面加载完成后执行。你现在怎么执行它? –

+0

它位于页面的底部,或者至少在tumblr允许的范围内(因为它添加了一些自己的自动脚本),因此理论上应该在脚本之前加载图像。 –

回答

2

如果当你调用pic.addEventListener("load", ...)图像已被加载,加载事件处理程序将不会被触发。如果pic.complete为真,则应该调用它,如this answer中所建议的那样。

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") 
 
    } 
 
}
img { 
 
    border: 1px solid; 
 
} 
 

 
.landscape { 
 
    border-color: red; 
 
} 
 

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

多亏了瑞奇。我从他的答案中借用了图像链接和样式属性。

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">

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") 
     } 
    } 
} 

哪些工作来了,你的解决方案似乎更优雅,虽然,所以我可能会有点使用那个。