2011-06-12 3 views
10

class plugin을 사용하여 JQuery에서 Mootools 툴팁 클래스를 다시 작성하려고합니다. 내 클래스가 인스턴스화 될 때 도구 설명을 페이드 아웃하는 대상 링크에 이벤트 수신기를 연결합니다.MooTools와 동등한 JQuery 바인드 (this)

이벤트 콜백에서 JQuery는 이벤트의 대상에 키워드 "this"를 할당하므로 apply()를 사용하여 클래스 인스턴스를 의미하도록 클래스의 속성에 대한 참조를 유지합니다. 이것은 분명히 JQuery에서 Mootools의 편리한 bind() 함수에 해당하는 것입니다.

불행히도 apply()를 사용할 때 콜백의 이벤트 매개 변수가 손실됩니다. 예를 들어,이 비트에서 두 번째 줄에 "e is undefined"오류가 발생합니다.

this.target.bind('click', function(e){ 
    e.preventDefault(); 
    var tip = this.opts.tip; 
    tip.fadeOut(500, function(){ 
     tip.bind('click', function(){ 
      showing = false; 
     }) 
    }); 
}.apply(this)) 

여기에 트릭이 누락 되었습니까? 아무도이 문제를 해결할 방법을 알고 있습니까?

감사 프레드

답변

18
가리키는 대상 속성을 가져야한다

TBH, mootools.bind은 ES5에서 단지 Function.bind이며, js 1.8.5 + 스펙을 지원하는 브라우저에서 기본적으로 사용할 수 있습니다. MooTools는 아직 가지고 있지 않은 브라우저를 향상 시키지만 원시 구현은 프로토 타입에 남아 있습니다 (사용 가능한 경우).

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

쉽게 경우 사용할 수 없습니다 기본적으로 AA Function.prototype.bind 장식으로 그것을 구현하고 사용할 수 위의 예는 말한대로 : 당신이 볼 수 있듯이

// Function.prototype.bind polyfill 
if (!Function.prototype.bind) { 

    Function.prototype.bind = function(obj) { 
    if(typeof this !== 'function') // closest thing possible to the ECMAScript 5 internal IsCallable function 
     throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); 

    var slice = [].slice, 
     args = slice.call(arguments, 1), 
     self = this, 
     nop = function() {}, 
     bound = function() { 
      return self.apply(this instanceof nop ? this : (obj || {}), 
           args.concat(slice.call(arguments)));  
     }; 

    bound.prototype = this.prototype; 

    return bound; 
    }; 
} 

은, 그것은보다 조금 더 복잡입니다 단순 .apply/.call

바인딩을 사용해야하거나 대신 참조를 저장할 수 있다면 고려해야 할 한 가지 사항이 있습니다.

예 :

var self = this; 
this.target.bind("click", function(e) { 
    var tip = self.opts.tip; 
}); 

어쨌든이 기능은 바인딩보다 작습니다. 또한 this을 트리거 요소 (event.target === this)로 올바르게 참조 할 수 있습니다. 당신은 바인드보다 Mootools의 코어에서 훨씬 더 자주이 패턴을 발견 할 것이다 - 바인드가 종종 필요하지만 당신은 클래스 메소드 예에 이벤트 할당 할 때이 경우

this.element.addEvents({ 
    click: this.showTip.bind(this), 
    mouseleave: this.hideTip.bind(this) 
}); 

을, 참조를 '원 절약 http://api.jquery.com/jquery.proxy/

+0

당신은 JS의 걷는 백과 사전이야! 자세한 설명 주셔서 감사합니다.이 상황에서 참조에 대한 귀하의 제안이 가장 좋을 것 같습니다. '\t var self = this; \t this.target.bind() 함수 (예를 들어 '클릭') { \t \t e.preventDefault을 (; \t \t self.toggleTip();} \t)'내 init 메소드에 toggleTip ()는 별도의 클릭 콜백입니다. 큰 충고, 고마워! –

+0

@Dimitar : 대단히 훌륭하게 작동합니다. thnx. (at) all :이 함수형 프로그래밍 기술은 currying (http://www.dustindiaz.com/javascript-curry/)이라고합니다. jQuery는 메서드 이름 'bind'의 프로토 타입 확장이 비슷하기 때문에 이벤트 처리 및 비 함수 선언을 위해 다소 혼란 스럽습니다. jQuery에서는 비슷한 목적으로 $ .ajax에 컨텍스트를 사용합니다. –

0

몇 가지 요소에 만들어진 모든 이벤트를 (예를 들어, 그 중 하나는 '클릭') 그 요소

var $this = $(e.target); // $this will be the clicked element 

JSFiddle

+0

감사 mkilmanas - - 당신이

var self = this; this.element.addEvents({ click: function(e) { self.showTip(e); } }); 

같이 jQuery를 특정 구현을 다시 작성할 수 있지만 t 작업은 proxy입니다 내가 사용하는 바라고 재산입니다. 불행히도 내 function의 끝에 apply()를 추가했을 때 나는 그것에 대한 접근을 잃었다. –