2017-04-15 9 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", ...)を呼び出したときに画像がすでにロードされている場合は、loadイベントハンドラが起動されません。 this answerに示唆されているように、pic.completeが真であればそれを呼び出す必要があります。

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

を思い付いた、あなたのソリューションは、もう少しエレガントなので、私はおそらくよしかし思えますそれを使用してください。

関連する問題