2015-01-02 2 views
1

그래서 자바 스크립트 코드를 분류하려고합니다.자바 스크립트 클래스 및 마우스 클릭 문제

나는 간단하게 정수를 포함하는 node라는 클래스, 정수를 표시하는 label 요소 및 정수를 증가시키는 button 요소를 가지고 있습니다.

코드를 통해 incrementInteger 함수를 호출하면 모든 것이 예상대로 작동합니다. 그러나 마우스 클릭 이벤트 리스너를 사용하여 incrementInteger 함수를 호출하려고하면 작동하지 않습니다. 당신의 incrementInteger 함수 내에서

$(document).ready(function() { 
    var firstNode = new Node(); 
    firstNode.incrementInteger(); 
    var secondNode = new Node(); 
}); 

function Node() { 
    this.integer = 0; 
    this.incrementInteger = function() { 
     this.integer++; 
     this.label.innerHTML = this.integer; 
    } 
    this.addButton = document.createElement("button"); 
    this.addButton.addEventListener("mousedown", this.incrementInteger); 
    this.container = document.createElement("div"); 
    this.label = document.createElement("div"); 
    this.label.innerHTML = this.integer; 

    var bodyElement = document.getElementsByTagName("body")[0]; 
    this.container.appendChild(this.label); 
    this.container.appendChild(this.addButton); 
    bodyElement.appendChild(this.container); 
} 
+1

당신이 jQuery를 사용하는 경우, 왜 바닐라 JS 함께 물건을 관련된 모든 DOM을합니까? – prodigitalson

+0

아래의 두 답변 중 하나가 작동합니다 (이 둘은 서로 다르므로 다른 것보다 효과적 일 수 있습니다). [이 링크] (https://developer.mozilla.org/en-US/docs/Web/)를 참조하십시오. JavaScript/Reference/Operators/this)를 참조하십시오. 짧은 버전은 'this'가 호출 컨텍스트를 기반으로 설정된다는 것입니다. – peterjb

+0

고맙습니다. 필자는 솔루션을 본 후에 왜 작동하는지 궁금해서 제 것이 아니었고 귀하의 의견은 저의 혼란을 해결하는 데 도움이되었습니다. –

답변

1

this 개체에 속성을 참조하지 않습니다

여기 내 코드입니다.

var self = this; 
this.integer = 0; 
this.incrementInteger = function() { 
    self.integer++; 
    self.label.innerHTML = self.integer; 
} 

데모 : http://jsfiddle.net/0bgjpp4w

+0

빠른 응답과 jsfiddle에 대해 감사드립니다. 이것으로 내 문제가 해결되었습니다. –

0
당신은 바인딩해야

this 당신의 incrementInteger이 같은 : 컨텍스트 참조를 만듭니다

this.incrementInteger = function() { 
    this.integer++; 
    this.label.innerHTML = this.integer; 
}.bind(this); 
+0

감사합니다. 그가 처음에 대답했기 때문에 나는 tymeJV를주었습니다. 그러나 당신도 도움이되었습니다. 나는 upvote에 충분한 담당자가 아직 없지만, 내가 할 때, 나는 이것을 upvote하게 될 것이다. –

0

당신의 incrementInteger()는 각각의 모든 '노드'에 대해 동일한 경우 -object가 'Node'생성자로 생성되면 prototype이어야합니다! 그렇지 않으면 (일반 바닐라 자바 ​​스크립트) 메서드 및 속성을 공유하지 않았을 것입니다. 사용

addEventListener 당신 거의 바로 그것을 가지고, 아직 객체의 로컬 기능 대신 개체 자체 (다른 답변에서 설명하여 this에 대한 올바른 참조 손실)을 통과시켰다.

아이디어는 addEventListenerhandleEvent과 전화라는 방법을 찾을 것이다 두번째 인자 같은 객체를 취할 수 있다는 것입니다!
바인딩 필요 없음 this; 컨텍스트를 올바르게 전달합니다. 컨텍스트는 방금 이벤트 리스너 콜백으로 설정 한 객체입니다.

handleEvent 함수를 포함하여 incrementInteger 함수를 생성자 prototype에 (다른 방식으로 반복적으로 복제 된) 이동하는 방법을 제공합니다. NICE!

function Node(){ 
 
    this.integer = 0; 
 
    this.addButton = document.createElement('button'); 
 
    this.addButton.addEventListener('mousedown', this); 
 
    this.container = document.createElement('div'); 
 
    this.label = document.createElement('div'); 
 
    this.label.innerHTML = this.integer; 
 
    this.container.appendChild(this.label); 
 
    this.container.appendChild(this.addButton); 
 
    document.getElementsByTagName('body')[0].appendChild(this.container); 
 
} 
 

 
Node.prototype={ 
 
    incrementInteger: function(){ 
 
    this.integer++; 
 
    this.label.innerHTML = this.integer; 
 
    }, 
 
    handleEvent: function(){ // track event source-element to overload functionality. 
 
    this.incrementInteger(); 
 
    } 
 
}; 
 

 
// avoiding the html jquery script load line for this snippet 
 
window.onload=function(){   // $(document).ready(function() { 
 
    var firstNode = new Node(); 
 
    firstNode.incrementInteger(); 
 
    var secondNode = new Node(); 
 
};         // });


편집 : 또는

(예를 들어)이 쓸 수 단순히 :

(window.Node = function(){ 
 
    var d=document; 
 
    this.container = d.createElement('div'); 
 
    (this.label  = this.container.appendChild(d.createElement('div')) 
 
).innerHTML  = this.integer = 0; 
 
    (this.addButton = this.container.appendChild(d.createElement('button')) 
 
).addEventListener('mousedown', this); 
 
    d.getElementsByTagName('body')[0].appendChild(this.container); 
 
}).prototype={ 
 
    incrementInteger: function(){ 
 
    this.label.innerHTML = ++this.integer; 
 
    } 
 
, handleEvent: function(){ 
 
    this.incrementInteger(); 
 
    } 
 
}; 
 

 

 
window.onload=function(){ 
 
    var firstNode = new Node(); 
 
    firstNode.incrementInteger(); 
 
    var secondNode = new Node(); 
 
};

위 코드에서는 식별자 Node을 한 번만 사용 했으므로 식별자의 이름을 바꾸는 데 한 곳만 있습니다.
(생성자가 생성 한) 객체가 모두 prototype 아래에 쉽게 표시 될 수있는 모든 메서드 또는 속성입니다.
ES6 클래스 외에도 이것은 순수한 자바 스크립트에서 사용자가 의도 한대로 구현할 수있는 가장 가까운 것입니다. 하나의 식별자가 이고 다른 하나는이고 개의 '클래스'('공통'자바 스크립트에는 클래스가 없으므로!). 개인 물건을 사용할 수 있도록

또는은 (예를 들어) (공유) 폐쇄를 사용하여 생성자 만 (세 번째 섹션)에 :
(도 다시 고려 생성자 코드에 대한 모든 기능을 유지하면서 단 2 줄 의도 원래 코드에서.)

(function(ns){ 
 
var b = document, d = b.createElement('div'); 
 
(b = b.createElement('button')).innerHTML = 'Click me'; 
 
    
 
(ns.Node = function(){ 
 
    (this.label  = (this.container = d.cloneNode(false) 
 
        ).appendChild(d.cloneNode(false)) 
 
    ).innerHTML  = this.integer = 0; 
 
    (this.addButton = document.getElementsByTagName('body')[0] 
 
          .appendChild(this.container) 
 
          .appendChild(b.cloneNode(true)) 
 
    ).addEventListener('mousedown', this); 
 
}).prototype={ 
 
    incrementInteger: function(){ this.label.innerHTML = ++this.integer; } 
 
,  handleEvent: function(){ this.incrementInteger(); } 
 
}; 
 
})(window); // pass namespace to hook object-creator 'Node' to. 
 

 

 
window.onload=function(){ 
 
    var firstNode = new Node(); 
 
    firstNode.incrementInteger(); 
 
    var secondNode = new Node(); 
 
};

관련 문제