2008-10-23 29 views
19

Có cách nào thực hành hay phổ biến nhất trong JavaScript để có các thành viên lớp học là trình xử lý sự kiện không?Các phương thức lớp như trình xử lý sự kiện trong JavaScript?

xem xét ví dụ đơn giản sau:

<head> 
    <script language="javascript" type="text/javascript"> 

     ClickCounter = function(buttonId) { 
      this._clickCount = 0; 
      document.getElementById(buttonId).onclick = this.buttonClicked; 
     } 

     ClickCounter.prototype = { 
      buttonClicked: function() { 
       this._clickCount++; 
       alert('the button was clicked ' + this._clickCount + ' times'); 
      } 
     } 

    </script> 
</head> 
<body> 
    <input type="button" id="btn1" value="Click me" /> 
    <script language="javascript" type="text/javascript"> 
     var btn1counter = new ClickCounter('btn1'); 
    </script> 
</body> 

Các xử lý sự kiện buttonClicked được gọi, nhưng các thành viên _clickCount là không thể tiếp cận, hoặc này điểm đối với một số đối tượng khác.

Bất kỳ mẹo/bài viết/tài nguyên hay nào về loại sự cố này?

Trả lời

17
ClickCounter = function(buttonId) { 
    this._clickCount = 0; 
    var that = this; 
    document.getElementById(buttonId).onclick = function(){ that.buttonClicked() }; 
} 

ClickCounter.prototype = { 
    buttonClicked: function() { 
     this._clickCount++; 
     alert('the button was clicked ' + this._clickCount + ' times'); 
    } 
} 
+0

Cảm ơn giải pháp của bạn. Tôi cũng đang cố hiểu hình ảnh lớn hơn - các mẫu, thực hành, v.v. Bất kỳ bài viết hay nào bạn biết? – JacobE

+5

điều này là rất tốt: http://ejohn.org/apps/learn/ – pawel

+8

Đây là một ví dụ tốt, nhưng câu trả lời này có thể tốt hơn với một số giải thích là tại sao nó là một giải pháp tốt cho những người mới ở đây. –

5

Hàm được đính kèm trực tiếp vào thuộc tính onclick sẽ có ngữ cảnh thực thi là this thuộc tính trỏ tới phần tử.

Khi bạn cần một sự kiện yếu tố để hoạt động chống lại một trường hợp cụ thể của một đối tượng (a la một đại biểu trong .NET) sau đó bạn sẽ cần một đóng cửa: -

function MyClass() {this.count = 0;} 
MyClass.prototype.onclickHandler = function(target) 
{ 
    // use target when you need values from the object that had the handler attached 
    this.count++; 
} 
MyClass.prototype.attachOnclick = function(elem) 
{ 
    var self = this; 
    elem.onclick = function() {self.onclickHandler(this); } 
    elem = null; //prevents memleak 
} 

var o = new MyClass(); 
o.attachOnclick(document.getElementById('divThing')) 
+0

Đây chính xác là những gì tôi đang tìm kiếm! Cảm ơn bạn! – Jeremy

0

Tôi không biết tại sao Function.prototype.bind chưa được đề cập ở đây. Vì vậy, tôi sẽ chỉ để lại này đây;)

ClickCounter = function(buttonId) { 
    this._clickCount = 0; 
    document.getElementById(buttonId).onclick = this.buttonClicked.bind(this); 
} 

ClickCounter.prototype = { 
    buttonClicked: function() { 
     this._clickCount++; 
     alert('the button was clicked ' + this._clickCount + ' times'); 
    } 
} 
1

Bạn có thể sử dụng cú pháp béo mũi tên, mà liên kết với phạm vi từ vựng của hàm

function doIt() { 
    this.f =() => { 
    console.log("f called ok"); 
    this.g(); 
    } 
    this.g =() => { 
    console.log("g called ok"); 
    } 
} 

Sau đó bạn có thể thử

var n = new doIt(); 
setTimeout(n.f,1000); 

Bạn có thể dùng thử trên babel hoặc nếu trình duyệt của bạn hỗ trợ ES6 trên jsFiddle.

Thật không may là lớp học-Thần kinh lớp ES6 dường như không cho phép tạo hàm được liên kết từ từ theo cách này. Cá nhân tôi nghĩ rằng nó cũng có thể làm điều đó. EDIT: Có vẻ là experimental ES7 feature to allow it.

Các vấn đề liên quan