[英]How to set an event listener callback to a member function
我正在圍繞畫布對象編寫一個小的面向對象的包裝器,我想為實際的函數成員設置一些按鈕回調,而不是全局范圍內的函數(通過這種方式,我可以將上下文對象稱為成員)。
function CanvasManager(canvasId) {
this.canvas = document.getElementById(canvasId);
this.ctx = this.canvas.getContext('2d');
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', this.handleImage, false);
var lineNumberField = document.getElementById('linenumber');
lineNumberField.addEventListener('change', this.onLineNumberChange, false);
}
function handleImage = function(e) {
var reader = new FileReader();
var that = this;
reader.onload = function(event){
var img = new Image();
img.onload = function(){
that.canvas.width = img.width;
that.canvas.height = img.height;
that.ctx.drawImage(img,0,0);
};
img.src = event.target.result;
};
reader.readAsDataURL(e.target.files[0]);
};
這是在html的內聯腳本中調用的:
<div id="canvas-container" style="display:none;">
<canvas id="imageCanvas"></canvas>
</div>
...
<script lang="javascript">new CanvasManager('imageCanvas');</script>
這是行不通的,因為在handleImage
回調中,“ this”不是引用CanvasManager
實例,而是imageLoader
實例,這令我非常困惑。
我在這里做錯了什么?
抱歉,您的評論-實際上,如果問題在第二種方法之內,則您對它的解釋不正確。
正如其他人所暗示的那樣,事件偵聽器將以window
作為this
對象來調用函數。 不用擔心,即使作為JS專家,我也認為這沒有任何意義。
雖然你可以簡單地把在關閉一切,把this
變成一個恆定的var
(即me
或self
)我喜歡的是自定義調用該函數總是有特定的this
參考。 您可以這樣做:
imageLoader.addEventListener('change', this.handleImage.bind(this), false);
bind()是一個相對較新的JavaScript函數,它為您提供了一個新方法,該方法代表原始方法,但使用特定的this
上下文進行調用。 一些JavaScript庫具有與舊版瀏覽器兼容的等效項,例如Dojo的“ hitch”。 但是,由於您的代碼無論如何都涉及<canvas>
,因此您應該基本上可以兼容。
嘗試這個
function CanvasManager(canvasId) {
this.canvas = document.getElementById(canvasId);
this.ctx = this.canvas.getContext('2d');
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', this.handleImage, false);
var lineNumberField = document.getElementById('linenumber');
lineNumberField.addEventListener('change', this.onLineNumberChange, false);
var self = this; // keep CanvasManager instance
this.onLineNumberChange = function(){
};
this.handleImage = function(){
console.log(self); // use CanvasManager instance
}
}
看起來您的函數handleImage在您要使用的主函數(或類)之外。 我將更新代碼如下:
function CanvasManager(canvasId) {
var me = this;
me.canvas = document.getElementById(canvasId);
me.ctx = me.canvas.getContext('2d');
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', me.handleImage, false);
var lineNumberField = document.getElementById('linenumber');
lineNumberField.addEventListener('change', me.onLineNumberChange, false);
me.handleImage = function(e) {
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
me.canvas.width = img.width;
me.canvas.height = img.height;
me.ctx.drawImage(img, 0, 0);
};
img.src = event.target.result;
};
reader.readAsDataURL(e.target.files[0]);
}
}
通過將handleImage移動到函數內部,它現在處於類的范圍內。 同樣通過在方法開始時使用me = this來始終可以訪問它的類實例,因為默認情況下,這將引用事件觸發它的對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.