2011-06-12 17 views
10

Bu class plugin kullanarak JQuery'de bir Mootools tooltip sınıfını yeniden yazmaya çalışıyorum. Sınıfım başlatıldığında, araç ipucunu sönecek bir hedef dinleyiciye bir etkinlik dinleyicisi ekliyorum.JQuery eşdeğeri MooTools bind (this)

Geri arama durumunda JQuery, "this" anahtar sözcüğünü olayın hedefine atar, böylece sınıfın özelliklerine bir başvuru tutmak için sınıf örneğini ifade etmek üzere "this" öğesini ayarlamak için apply() kullanıyorum). Bu, Mootools'un kullanışlı bind() işlevinin JQuery'deki karşılığıdır.

Uyguladığım zaman ne yazık ki apply() işlevini kullandığımda geri arama parametresini kaybediyorum. Örneğin, bu satırda ikinci satırda bir "e tanımsız" hatası alıyorum.

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)) 

Burada bir numara eksik mi? Herkes bu konuda bir yol biliyor mu?

Teşekkür Fred

cevap

18
işaret eden bir hedef özelliğine sahip olmalıdır

TBH, aradığınız gibi mootools.bind, ES5'te sadece Function.bind'dur ve doğal olarak js 1.8.5 + spesifikasyonunu destekleyen tarayıcılarda kullanılabilir. MooTools, henüz sahip olmayan tarayıcıları geliştirir, ancak yerel uygulamaların prototip üzerinde kalmasını sağlar - eğer mevcutsa.

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

kolaylıkla değilse mevcut doğal aa Function.prototype.bind dekoratör olarak bu uygulamaya ve kullanabilirsiniz Yukarıdaki örnekte söylediği gibi: Gördüğünüz gibi

// 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; 
    }; 
} 

, bir biraz daha işin içinde basit .apply/.call

Göz önüne alınması gereken bir yöntem yoksa veya bunun yerine bir başvuru kaydedebilirsiniz. Örn.,

örn. Her neyse, bu fonksiyonun bağlayıcısından daha küçük bir alanı vardır. aynı zamanda tetikleme elemanı olarak (event.target === this) this'a doğru bir referans verir. Eğer bağlama birden Mootools-çekirdek çok daha sık bu modeli bulacaksınız - bağlama sıklıkla ihtiyaç vardır gerçi sınıf yöntemlerine, örneğin olayları atamak istediğinizde: Bu durumda

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

bir referans 'kazandı tasarrufu http://api.jquery.com/jquery.proxy/

+0

Dimitar, JS'nin bir yürüyüş ansiklopedisi! Detaylı açıklama için teşekkürler.Bu durumda bir referans önerisi en iyisi gibi görünüyor, bu yüzden şöyle yaparım: '\t var self = this; \t this.target.bind() işlev (e 'klik' {) \t \t e.preventDefault (; \t \t self.toggleTip(); \t}) 'benim init yönteminde toggleTip () ayrı bir tıklama geri aramadır. Büyük tavsiye, teşekkürler! –

+0

@Dimitar: Gerçekten harika çalışıyor. thnx. (at) all: Bu fonksiyonel programlama tekniğinin körelme olarak adlandırıldığına dikkat edin (http://www.dustindiaz.com/javascript-curry/). jQuery, 'bind' yöntem adının benzer prototip uzantısına sahiptir, bu da bir şekilde kafa karıştırıcı olabilir, çünkü bunlar olayları işlemek için kullanılmaz ve işlevsiz olarak bildirilir. JQuery'de benzer amaçlar için $ .ajax'ta bir bağlam kullanımı da vardır. –

0

bazı elemanı üzerinde yapılan tüm olayları, (örneğin bunlardan biridir 'klik') o elementin

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

JSFiddle

+0

Teşekkür mkilmanas - - Eğer

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

gibi bir jQuery belirli uygulanmasını bunu yazabiliriz ama çalışamam proxy olduğunu kullandığım umuyordum mülkü. Ne yazık ki, apply() fonksiyonumun sonuna eklediğimde, ona erişimi kaybettim. –