2014-09-03 46 views
0

我試圖在加載時將函數應用於頁面上的每個圖像。 image.onload函數中的變量似乎是全局變量,這會導致圖像跳過並出現意想不到的效果(如圖像不符合應用width)。在循環中調用圖像會創建重疊變量

這裏是我的整個JS:

var imgList = document.getElementsByTagName('img'); 
$('img').after('<canvas></canvas>'); 

for (var j = 0; j < imgList.length; j++){ 
    var image = document.getElementsByTagName('img')[j]; 
    var canvas = document.getElementsByTagName('canvas')[j]; 

    image.onload = function(){ 
     console.log(canvas); 
     var ctx = canvas.getContext('2d'); 

     canvas.width = image.width; 
     canvas.height = image.height; 

     ctx.drawImage(image, 0, 0, canvas.width, canvas.height); 
     var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); 
     var pixelNum = imgData.data.length; 

     //initialize brightness for levels 
     var redMax = 0; 
     var redMin = 255; 
     var greenMax = 0; 
     var greenMin = 255; 
     var blueMax = 0; 
     var blueMin = 255; 

     for(var i = 0; i < pixelNum; i += 4){ 
      //set min and max values for each color 
      if (imgData.data[i] > redMax) { redMax = imgData.data[i] }; 
      if (imgData.data[i] < redMin) { redMin = imgData.data[i] }; 
      if (imgData.data[i+1] > greenMax) { greenMax = imgData.data[i+1] }; 
      if (imgData.data[i+1] < greenMin) { greenMin = imgData.data[i+1] }; 
      if (imgData.data[i+2] > blueMax) { blueMax = imgData.data[i+2] }; 
      if (imgData.data[i+2] < blueMin) { blueMin = imgData.data[i+2] }; 
     } 
     console.log(redMin+" "+redMax+" "+blueMin+" "+blueMax+" "+greenMin+" "+greenMax); 

     for(var i = 0; i < pixelNum; i += 4){ 
      //map colors to 0 - 255 range 
      imgData.data[i] = (imgData.data[i] - redMin) * (255/(redMax - redMin)); 
      imgData.data[i+1] = (imgData.data[i+1] - greenMin) * (255/(greenMax - greenMin)); 
      imgData.data[i+2] = (imgData.data[i+2] - blueMin) * (255/(blueMax - blueMin)); 
     } 
     ctx.putImageData(imgData, 0, 0); 

     //remove original img tag 
     $(image).remove(); 
     console.log(image); 

    }; 
}; 

這是我的控制檯輸出(下面解說):

<canvas> (line 20) 
0 0 0 0 0 0 (line 47) 
<img src="images/cimg1836.jpg"> (line 59) 

<canvas width="400" height="268"> (line 20) 
29 255 18 255 23 255 (line 47) 
<img src="images/cimg1836.jpg"> (line 59) 

-canvas標記都如預期增加。 - 亮度最大值和最小值不應都爲零,因爲min設置爲255,最大值爲0(圖像正在以完全黑色像素讀取)。 - 列出的圖像是標記中的兩幅圖像中的第二幅。

- 第一個畫布標記正在輸出到控制檯 - 第二個畫布忽略img{ width:400px; }樣式,該樣式應該從img繼承。如預期的那樣, 。如預期的那樣, 。

我怎樣才能保持圖像不同,也就是說,讓他們運行所有的代碼,只有一次?

回答

1

JavaScript沒有塊範圍,所以你的循環中的變量確實是「全局」的。

我將整個循環體移入一個函數,該函數將j作爲參數。通過這樣做,imagecanvas對每個單獨函數調用的範圍都是唯一的,因此不會「重疊」並導致您所看到的效果。

function doMyThing(image_n) { 
    var image = document.getElementsByTagName('img')[image_n]; 
    var canvas = document.getElementsByTagName('canvas')[image_n]; 

    image.onload = function() { /* ... */ }; 
} 

for (var j = 0; j < imgList.length; j++) { 
    doMyThing(j); 
} 

需要這樣黑客(即,引入功能範圍,你不一定會直覺他們)是JavaScript的一個特點,你應該保持它在你的腦海裏,你繼續編程用這種語言。

+0

謝謝了。我以前嘗試創建一個函數並在一個循環中調用它,但不知何故沒有調用j作爲參數。你救了我的理智。 – AJFarkas 2014-09-04 01:15:50