2017-02-18 84 views
2

正如您在下面看到的,我正在嘗試編寫一個程序,該程序將採用圖像的平均顏色,然後將其顯示爲img所在的父類的背景。在多色背景上顯示的img的平均顏色

每個圖像被存儲在一個單獨的類:「sqr1」,「SQR2」等

的問題是,正在被顯示在最後的圖像元素的平均顏色,因爲所有的父類標籤的背景( 'sqr1','sqr2'等)。

有沒有辦法將這兩個分開?

有沒有更好的做這件事?

<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中的循環傳遞索引,否則它們將始終以最終顏色結束。一種方法是將index參數綁定到函數上:

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編程:您正在修改一個循環對象引用,並在不經意間設置你所有的物體引用相同的值。這個問題有很多解決方案;我的首選解決方案是來包裝你的內部,在一個循環立即以形成對你的變量封閉範圍內調用該函數表達式(iife):

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 closure inside loops – simple practical example

爲了避免這樣的問題,在未來,JavaScript的作用域和封鎖讀了起來:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

+0

我在這個答案中複製了你的代碼,並用i和x代替了「索引」,結果無效。這兩種顏色不是分開的,仍然顯示最後一個顏色。 – AtomiCookiez

+0

你爲什麼要用外部的i和x替換內部的索引變量?閉包中的索引變量解決了問題。 – MaxPRafferty

+0

我認爲是對應於for循環中的變量。另一方面,這仍然不能解決問題。 – AtomiCookiez