縦横比の異なる画像を、高さを等しく横に並べるJS

ギャラリーページなどで使える、アスペクト比のバラバラな画像たちを高さを揃えて横並びに配置できるJavaScriptコードのご紹介。
ちなみに、メインビジュアルは実家で飼ってたうさぎです。
目次
サンプル
高さが等しくなるようにJSで配置しています。これ1つ1つ画像です。
(検証で見てみてね)
5カラムなどにも対応。
CSSはFlexboxでもfloatでもどちらでも良くて、上記はFlex、下記はfloatを使用。
また、このレイアウトを実際に使ってるページがこちら
HTML
親要素を.galleryheight、子要素を.colとし、その中にimgタグを入れます。
<ul class="galleryheight">
<li class="col"><img src="img/img_240_480.png"></li>
<li class="col"><img src="img/img_680_240.png"></li>
<li class="col"><img src="img/img_360_360.png"></li>
<li class="col"><img src="img/img_800_120.png"></li>
<li class="col"><img src="img/img_680_240.png"></li>
<li class="col"><img src="img/img_240_480.png"></li>
<li class="col"><img src="img/img_360_360.png"></li>
<li class="col"><img src="img/img_240_480.png"></li>
<li class="col"><img src="img/img_360_360.png"></li>
</ul>
CSS
ごくごく普通のFlexレイアウトです。
というか、ごくごく普通のカラムレイアウトを作成してください。
たぶん何カラムでも大丈夫です。
.galleryheight {
display: flex;
flex-wrap: wrap;
margin: 0 0 -2%;
padding: 0;
list-style: none;
}
.galleryheight .col {
width: 32%;
margin: 0 2% 2% 0;
}
.galleryheight .col:nth-child(3n) {
margin-right: 0;
}
.galleryheight .col img {
width: 100%;
}
JS
JSはjQueryバージョンとネイティブJavaScriptバージョンを紹介していきます。
画像が1000枚くらいになると、0.1~0.05秒程度の差が生まれました。
jQueryとJavaScriptの処理速度比較デモ
jQueryバージョン
$(function(){
//親要素の幅
let parentWidth = $(".galleryheight").width();
//子要素
let elm = $(".galleryheight .col");
//小要素の数だけwhile文 (forではうまく作れず)
let elmLen = elm.length;
let i = 0;
while(i < elmLen){
//初めの(左端の)offset (四捨五入)
let offset = Math.round(elm.eq(i).offset().top);
//計算用
let colWidth = 0;
let imgWidth = 0;
//その行の配列
let arr=[];
//左端と同じoffsetが続く間while文
while(i < elmLen && offset == Math.round(elm.eq(i).offset().top)){
//該当の子要素
let target = elm.eq(i);
let targetWidth = target.width();
let targetImg = target.find("img");
//imgの幅
let width = targetImg.width();
//幅が0の場合はスルー
if(width > 0){
let height = targetImg.height();
//試しに高さを1にしてみたときの幅 (以降 テスト幅)
let testWidth = width / height;
//配列に追加
arr.push([target, testWidth]);
//子要素の幅を加算
colWidth += targetWidth;
//テスト幅を加算
imgWidth += testWidth;
}
++i;
}
//その行の数(カラム数)だけfor文
let arrLen = arr.length;
for(var j = 0; j < arrLen; j++){
//該当要素のテスト幅 ÷ テスト幅の合計 × 100%で割合を出せるが
//子要素の幅の合計 ÷ 親要素の幅の合計を掛け、少数第二位で切り捨てにし調整
let newWidth = Math.floor((arr[j][1] / imgWidth * 100 * colWidth / parentWidth) * 100) / 100;
//セット
arr[j][0].css("width", newWidth + "%");
}
}
});
JavaScriptバージョン
//親要素の幅
let parentWidth = document.querySelector(".galleryheight").clientWidth;
//子要素
let elm = document.querySelectorAll(".galleryheight .col");
//offset取得用
let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
//小要素の数だけwhile文
let elmLen = elm.length;
let i = 0;
while(i < elmLen){
//初めの(左端の)offset (四捨五入)
let offset = Math.round(elm[i].getBoundingClientRect().top + scrollTop);
//計算用
let colWidth = 0;
let imgWidth = 0;
//その行の配列
let arr=[];
//左端と同じoffsetが続く間while文
while(i < elmLen && offset == Math.round(elm[i].getBoundingClientRect().top + scrollTop)){
//該当の子要素
let target = elm[i];
let targetWidth = target.clientWidth;
let targetImg = target.getElementsByTagName("img")[0];
//imgの幅
let width = targetImg.clientWidth;
//幅が0の場合はスルー
if(width > 0){
let height = targetImg.clientHeight;
//試しに高さを1にしてみたときの幅 (以降 テスト幅)
let testWidth = width / height;
//配列に追加
arr.push([target, testWidth]);
//子要素の幅を加算
colWidth += targetWidth;
//テスト幅を加算
imgWidth += testWidth;
}
++i;
}
//その行の数(カラム数)だけfor文
let arrLen = arr.length;
for(var j = 0; j < arrLen; j++){
//該当要素のテスト幅 ÷ テスト幅の合計 × 100%で割合を出せるが
//子要素の幅の合計 ÷ 親要素の幅の合計を掛け、少数第二位で切り捨てにし調整
let newWidth = Math.floor((arr[j][1] / imgWidth * 100 * colWidth / parentWidth) * 100) / 100;
//セット
arr[j][0].style.width = newWidth + "%";
}
}
参考になれば幸いです。
カスタマイズなどもできますので、お気軽にコメントください。
お役に立てましたら応援をお待ちしております!
頂いた応援は子育てに活用させていただきます。
または以下のボタンからなにか買って応援 (PR)