最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - JQuery equivalent of MooTools bind(this) - Stack Overflow

programmeradmin1浏览0评论

I'm trying to rewrite a Mootools tooltip class in JQuery using this class plugin. When my class is instantiated I'm attaching an event listener to a target link which will fade out the tooltip.

In event callbacks JQuery assigns the keyword "this" to the target of the event, so to keep a reference to the properties of the class I'm using apply() to set "this" to mean the class instance. This is apparently the counterpart in JQuery of Mootools' handy bind() function.

Unfortunately when I use apply() I lose the callback's event parameter. For example, in this bit I get an "e is undefined" error on the second line.

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

Am I missing a trick here? Does anybody know a way around this issue?

I'm trying to rewrite a Mootools tooltip class in JQuery using this class plugin. When my class is instantiated I'm attaching an event listener to a target link which will fade out the tooltip.

In event callbacks JQuery assigns the keyword "this" to the target of the event, so to keep a reference to the properties of the class I'm using apply() to set "this" to mean the class instance. This is apparently the counterpart in JQuery of Mootools' handy bind() function.

Unfortunately when I use apply() I lose the callback's event parameter. For example, in this bit I get an "e is undefined" error on the second line.

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

Am I missing a trick here? Does anybody know a way around this issue?

Share Improve this question edited Feb 28, 2020 at 10:18 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Jun 12, 2011 at 9:15 And FinallyAnd Finally 5,70414 gold badges73 silver badges112 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 19

TBH, the mootools .bind as you call it is just Function.bind in ES5 - and is available natively in browsers that support the js 1.8.5 + spec. MooTools just enhances browsers that don't have it yet but lets the native implementation remain on the prototype - if available.

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

You can easily implement that as a a Function.prototype.bind decorator if not available natively and use it as the example above says:

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

As you can see, it's a little more involved than a simple .apply / .call

One thing to consider is, if you NEED to use bind or if you can save a reference instead.

eg.

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

this has a smaller footprint than the function binding anyway. it also affords you a correct reference to this as the trigger element (event.target === this). you will find this pattern far more often in mootools-core than the bind one - though bind is often needed when you want to assign events to class methods, eg:

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

In this case, saving a reference won't work though you can rewrite it as

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

A jQuery particular implementation is proxy - http://api.jquery.com/jquery.proxy/

All events, that are made on some element (e.g. 'click' is one of them) should have a target property pointing to that element

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

JSFiddle

发布评论

评论列表(0)

  1. 暂无评论