2017-02-18 1 views
2

私は画像の平均色を取り、imgがある親クラスの背景として表示するプログラムを作成しようとしています。Javascript imgの平均色は複数の背景に表示されます

各画像は別々のクラスに格納されている:「sqr1」、「sqr2」など

問題は、最後の画像要素の平均色は、すべての親クラス・タグの背景(のように表示されていることです'sqr1'、 'sqr2'など)。

これら2つを分ける方法はありますか?

これを行う方が良いですか?

<html> 

<head> 
    <title>getting average color</title> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
    <script src="js/color-thief.js"></script> 
</head> 

<body> 
    <p id="bob">...</p> 

    <div class="sqr1"> 
    <img src="memes/apple.jpg" width="400" height="400"> 
    </div> 

    <p></p> 

    <div class="sqr2"> 
    <img src="memes/pie.jpg" width="400" height="400"> 
    </div> 

    <script type="text/javascript"> 
    var x; 
    var allimgs = document.getElementsByTagName("img"); 
    var imglen = 2; 

    let change = function(color,img){ 
     for (var i = 0; i < imglen; i++) { 
      if (allimgs[i].src == img){ 
      allimgs[i].parentElement.style.backgroundColor = 'rgb('+color[0]+','+color[1]+','+color[2]+')'; 
      } 
     } 
    let colormix = function(){ 
     for(x = 0; x<imglen; x++){ 
     var colorThief = new ColorThief(); 
     colorThief.getColorFromUrl(allimgs[x].src, change,1); 
     console.log(); 
     } 
    } 
    colormix(); 
    </script> 
</body> 

</html> 

答えて

1

ああ、単純な論理エラー。あなたはループバックして、毎回のすべての画像の色をに設定しています。 changeのループを削除する必要があります。インデックスを渡す必要があります。そうしないと、最終的な色として常に終了します。これを行う1つの方法は、関数にインデックスパラメータを結合することにより、次のとおりです。

var x; 
var allimgs = document.getElementsByTagName("img"); 
var imglen = allimgs.length; 
let change = function(index, color, img){ 
    if (allimgs[index].src == img){ 
     allimgs[index].parentElement.style.backgroundColor = 'rgb('+color[0]+','+color[1]+','+color[2]+')'; 
    } 
} 
let colormix = function(){ 
    for(x = 0; x<imglen; x++){ 
    var colorThief = new ColorThief(); 
    colorThief.getColorFromUrl(allimgs[x].src, change.bind(null, x),1); 
    console.log(); 
    } 
} 

私はまた、動的にその長さを得るためにあなたのimglenを切り替えます。
私はそれを証明するために私が使用したjsfiddleです:https://jsfiddle.net/9L3ofjba/
これがあなたの問題を解決するなら、私は他の答えを削除します。

1

あなたの問題は、JavaScriptプログラミングに古典的なものです:あなたは、ループ内のオブジェクト参照を修正して、うっかり同じ値を参照するために、あなたのすべてのオブジェクトを設定しています。この問題にはいくつかの解決策があります。私はほとんどのように、この問題に対するこの解決策を見つける

let change = function(color,img){ 
    for (var i = 0; i < imglen; i++) { 
     (function (index) { 
     if (allimgs[index].src == img){ 
      allimgs[index].parentElement.style.backgroundColor = 'rgb('+color[0]+','+color[1]+','+color[2]+')'; 
     } 
     })(i) 
    } 
} 
let colormix = function(){ 
    for(x = 0; x<imglen; x++){ 
    (function (index) { 
     var colorThief = new ColorThief(); 
     colorThief.getColorFromUrl(allimgs[index].src, change,1); 
     console.log(); 
    })(x) 
    } 
} 

:私の好適な解決策はすぐにあなたの変数のための閉鎖範囲を形成するために、機能発現(生命維持)を呼び出したのループのためにあなたのインテリアをラップすることです便利ですが、ループの内部を関数に単純に引き込み、ループ内の関数を呼び出す方が好きな人もいます。結果は同じになります。ここで何が起こっているかのより完全な説明については

、この質問を参照してください。JavaScriptのスコープとクロージャをよく読んで、将来的にはこのような問題を回避するためにJavaScript closure inside loops – simple practical example

を:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

+0

この回答にあなたのコードをコピーし、 "インデックス"をiとxに置き換えても効果がありません。 2つの色は別々ではなく、最後の色を表示します。 – AtomiCookiez

+0

なぜ内側のインデックス変数を外側のiとxに置き換えますか?クロージャー内のインデックス変数は問題を解決するものです。 – MaxPRafferty

+0

私はforループの変数に対応していると思いました。一方、これはまだ問題を解決しません。 – AtomiCookiez

関連する問題