2013-07-10 21 views
18

Bir görüntü nesnesinin src'sini ayarladığımda, bir yükleme işlevi tetiklenir. Buna nasıl parametre ekleyebilirim? BurayaGörüntü yükleme olayına parametreler nasıl iletilir?

x = 1; 
y = 2; 
imageObj = new Image(); 
imageObj.src = "....."; 
imageObj.onload = function() { 
    context.drawImage(imageObj, x, y); 
}; 
x = 3; 
y = 4; 

, I resmin src ayarlamak zamanda ayarlanmış x ve y değerleri kullanmak isteyen (yani 1 ve 2). Yukarıdaki kodda, yükleme fonksiyonu sona erdiğinde x ve y 3 ve 4 olabilir.

Değerleri, yükleme işlevine iletebilmemin bir yolu var mı, yoksa otomatik olarak 1 ve 2?

Teşekkürler

+2

başka bir yol: imageObj.coords = {x: x, y: y}; ... drawImage (imageObj, imageObj.coords.x, imageObj.coords.y); – dandavis

+1

COMP SCI TECHIE STUFF: Yukarıdaki problem, yük fonksiyonunun GLOBAL değişkenlerine x ve y ... atıfta bulunması ve çalıştırıldığında o andaki akım değerini kullanmasıdır. Bir kapamayı doğru şekilde kullanmak için - ve oluşturma değerlerinden (kapanışın) "kaydedilen" değişken değerlerine sahip olmak ve yürütülürken kullanıldığında, "var" beyanını, kapağın İÇERİĞİ kapsamına almak için kullanmanız gerekir. (Bu, eğer değişkenler bir işleve resmî parametrelerse, dolaylı olarak gerçekleşir, işte bu yüzden buradaki "burada" kapanış-temelli cevaplar budur.) –

cevap

7

Bunu işleyen küçük bir işlev oluşturun. Yerel değişkenler doğru kapsamı tutacaktır.

function loadImage(src, x, y) { 

    var imageObj = new Image(); 
    imageObj.src = src; 
    imageObj.onload = function() { 
     context.drawImage(imageObj, x, y); 
    }; 

} 

var x = 1, 
    y = 2; 

loadImage("foo.png", x, y); 
x = 3; 
y = 4; 
4

Sen x & y değerlerini depolar özel kapsam kapatma olun isimsiz işlev

x = 1; 
y = 2; 
(function(xValue, yValue){ 
    imageObj = new Image(); 
    imageObj.src = "....."; 
    imageObj.onload = function() { 
     context.drawImage(imageObj, xValue, yValue); 
    }; 
})(x,y); 
x = 3; 
y = 4; 
8

kullanabilirsiniz:

imageObj.onload = (function(x,y){ 
     return function() { 
      context.drawImage(imageObj, x, y); 
    }; 
})(x,y); 
+0

Niçin downvote? – gdoron

30

Diğer tüm cevaplar bazıları versiyonu olan "make bir kapatma ". Tamam, işe yarıyor. Ancak ...

Ben kapanışları serin düşünüyorum ve onları destekleyen diller serin şunlardır: IMO, bunu yapmanın bir daha temiz bir yolu yoktur. Basitçe neye ihtiyacınız depolamak için görüntü nesnesini kullanın ve "this" üzerinden yük işleyicisinde erişmek:

imageObj = new Image(); 
imageObj.x = 1; 
imageObj.y = 2; 
imageObj.onload = function() { 
    context.drawImage(this, this.x, this.y); 
}; 
imageObj.src = "....."; 

Bu çok genel bir tekniktir ve ben DOM birçok nesnelerde o her zaman kullandıkları . (I varken Özellikle, diyelim ki, dört düğmeyi kullanmak ve tüm paylaşımına bir "onclick" işleyici onları istiyorum;. Ben işleyicisi var OLDUĞUNU düğmenin belirli eylem yapmak için düğmeye dışına özel verileri biraz çekin)

Tek uyarı: Nesne sınıfının kendisinin özel bir anlamı veya kullanımının bulunduğu bir özelliği kullanmamaya dikkat etmelisiniz. (Örneğin: herhangi bir eski özel kullanım için imageObj.src kullanamazsınız; kaynak URL için onu bırakmak zorundasınız.) Ancak, genel durumda, belirli bir nesnenin tüm özelliklerini nasıl kullandığını nasıl bileceksiniz? Kesinlikle konuşamazsın. Yani mümkün olduğunca bu yaklaşım kadar güvenli hale getirmek için:

  • nesnenin kendisi tarafından kullanılmak üzere/olağandışı olası değildir bir özellik itiraz tek bir nesne
  • Ata tüm özel veriler paketle.

Bu bağlamda, bazı tarayıcılarda bazı Javascript uygulamalarının Image nesnesini kullanırken bu özellikleri kullanabileceğinden "x" ve "y" kullanımı biraz risklidir. Ama bu muhtemelen güvenlidir:

imageObj = new Image(); 
imageObj.myCustomData = {x: 1, y: 2}; 
imageObj.onload = function() { 
    context.drawImage(this, this.myCustomData.x, this.myCustomData.y); 
}; 
imageObj.src = "....."; 

Bu yaklaşıma diğer avantajı Sayısı: Belirli bir nesnenin bir sürü oluştururken eğer çok fazla bellek kaydedebilirsiniz - Şimdi Onload işleyicisi tek bir örneğini paylaşabileceğinden .

// closure based solution -- creates 1000 anonymous functions for "onload" 
for (var i=0; i<1000; i++) { 
    var imageObj = new Image(); 
    var x = i*20; 
    var y = i*10; 
    imageObj.onload = function() { 
     context.drawImage(imageObj, x, y); 
    }; 
    imageObj.src = "....."; 
} 

Görüntü nesnesi gizlenmiş özel verilerinizin, paylaşılan-onload işleve karşılaştırın:: kapanışları kullanarak, bu düşünün

// custom data in the object -- creates A SINGLE "onload" function 
function myImageOnload() { 
    context.drawImage(this, this.myCustomData.x, this.myCustomData.y); 
} 
for (var i=0; i<1000; i++) { 
    imageObj = new Image(); 
    imageObj.myCustomData = {x: i*20, y: i*10}; 
    imageObj.onload = myImageOnload; 
    imageObj.src = "....."; 
} 

Çok bellek kaydedilir ve değiller çünkü daha hızlı bir skosh çalıştırabilir tüm bu anonim işlevleri yaratmıyor. (Bu örnekte, onload fonksiyonu bir tek liner .... ama 100-line onload fonksiyonları vardı ve bunların 1000 tanesi kesinlikle iyi bir sebepten dolayı çok fazla bellek harcamayı düşünebilirdi.)

+3

Vay. Nesne çözümü hakkında kaç yıl düşünmediğim şaşırtıcı. Bu çok hoş Dan, thx –

+1

Mükemmel yaklaşım, teşekkürler. –

+0

havalı! imageObj.myCustomData' yerine imageObj.this = this işlevini kullandım, daha sonra this.this ile adlandırdım. – Jason

İlgili konular