Tất cả các câu trả lời khác là một số phiên bản của "làm một đóng cửa ". OK, nó hoạt động. Tôi cho rằng các bao đóng là tuyệt vời và các ngôn ngữ hỗ trợ chúng rất tuyệt ...
Tuy nhiên: có cách làm sạch hơn, IMO. Đơn giản chỉ cần sử dụng đối tượng hình ảnh để lưu trữ những gì bạn cần, và truy cập nó trong xử lý tải qua "this
":
imageObj = new Image();
imageObj.x = 1;
imageObj.y = 2;
imageObj.onload = function() {
context.drawImage(this, this.x, this.y);
};
imageObj.src = ".....";
Đây là một kỹ thuật rất chung chung, và tôi sử dụng nó mọi lúc trong nhiều đối tượng trong DOM . (Tôi đặc biệt sử dụng nó khi tôi có, nói, bốn nút và tôi muốn tất cả họ chia sẻ một "onclick" xử lý; tôi có xử lý kéo một chút dữ liệu tùy chỉnh ra khỏi nút để làm hành động cụ thể của nút đó.)
Một cảnh báo: bạn phải cẩn thận không sử dụng thuộc tính của đối tượng mà chính lớp đối tượng đó có ý nghĩa hoặc sử dụng đặc biệt. (Ví dụ: bạn không thể sử dụng imageObj.src
cho bất kỳ mục đích sử dụng tùy chỉnh nào cũ; bạn phải để nó cho URL nguồn.) Nhưng, trong trường hợp chung, làm thế nào bạn biết được một đối tượng đã cho sử dụng tất cả các thuộc tính của nó như thế nào? Nói đúng ra, bạn không thể. Vì vậy, để thực hiện phương pháp này là an toàn càng tốt:
- Tổng kết tất cả các dữ liệu tùy chỉnh của bạn trong một đối tượng duy nhất
- Gán rằng phản đối một tài sản đó là không bình thường/khó có khả năng được sử dụng bởi các đối tượng chính nó.
Về vấn đề đó, việc sử dụng "x" và "y" hơi rủi ro vì một số triển khai Javascript trong một số trình duyệt có thể sử dụng các thuộc tính đó khi xử lý đối tượng Hình ảnh. Nhưng điều này có lẽ là an toàn:
imageObj = new Image();
imageObj.myCustomData = {x: 1, y: 2};
imageObj.onload = function() {
context.drawImage(this, this.myCustomData.x, this.myCustomData.y);
};
imageObj.src = ".....";
Một ưu điểm khác để tiếp cận này: nó có thể tiết kiệm rất nhiều bộ nhớ nếu bạn đang tạo rất nhiều của một đối tượng nhất định - vì bây giờ bạn có thể chia sẻ một trường hợp duy nhất của trình xử lý onload .Xem xét việc này, sử dụng đóng cửa:
// 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 = ".....";
}
Hãy so sánh để chia sẻ-onload chức năng, với dữ liệu tùy chỉnh của bạn giấu đi trong đối tượng hình ảnh:
// 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 = ".....";
}
Phần lớn bộ nhớ lưu lại và có thể chạy một skosh nhanh hơn kể từ khi bạn aren không tạo ra tất cả các chức năng ẩn danh đó. (Trong ví dụ này, hàm onload là một lớp lót .... nhưng tôi đã có các hàm tải 100 dòng, và 1000 trong số chúng chắc chắn sẽ được coi là dành nhiều bộ nhớ không có lý do chính đáng.)
cách khác: imageObj.coords = {x: x, y: y}; ... drawImage (imageObj, imageObj.coords.x, imageObj.coords.y); – dandavis
COMP SCI TECHIE STUFF: Vấn đề ở trên là hàm onload tham chiếu đến các biến GLOBAL x và y ... và sẽ sử dụng giá trị hiện tại khi thực thi. Để sử dụng đúng cách đóng - và có các giá trị biến "được lưu" từ thời gian tạo (của đóng) và được sử dụng khi được thực hiện - bạn cần sử dụng khai báo 'var' để cung cấp cho chúng một phạm vi INSIDE đóng. (Điều này ngầm xảy ra nếu các biến là các tham số chính thức cho một hàm, đó là lý do tại sao các câu trả lời dựa trên đóng cửa ở đây "hoạt động".) –