【问题标题】:Change $(this) context in anonymous function在匿名函数中更改 $(this) 上下文
【发布时间】:2012-06-06 20:53:20
【问题描述】:

这是我用来在移动设备上绑定“tap”事件的函数。基本上是一个正常的功能。

bindTapEvent: function(container, selector, run, bindClickAlso){
    var startX, startY, currentX, currentY = 0;
    var moved = false;
    var self;

    if(touchDevice){
        container.on({
            click: function(e){
                e.preventDefault();
            },
            touchstart: function(e){
                e.preventDefault();
                self = $(this);
                startX = e.originalEvent.touches[0].pageX;
                startY = e.originalEvent.touches[0].pageY;
            },
            touchmove: function(e){
                currentX = e.originalEvent.touches[0].pageX;
                currentY = e.originalEvent.touches[0].pageY;
                if(Math.abs(startX - currentX) > 10 || Math.abs(startY - currentY) > 10){
                    moved = true;
                }
            },
            touchend: function(e){
                e.preventDefault();
                run();
            }
        }, 
        selector
        )
    } else {
        if(bindClickAlso != false){
            container.on('click', selector, function(){
                run();
            });
        }
    }
}

我是这样使用它的:

tt.bindTapEvent(container, '.showColumns', function(){
    container.find('.column').addClass('visible');
    $(this).doSomething();
});

唯一的问题是我不能(显然)在这样的东西中使用 $(this)。我已经阅读了有关更改上下文的 jQuery $.proxy 的信息,但我无法理解它,因此我可以使用它。是否可以(在我的情况下)将 tt.bindTapEvent 中使用的匿名函数的上下文更改为当我使用 $(this) 时它仅在 bindTapEvent 函数中“存储”和“使用”?

【问题讨论】:

    标签: javascript jquery proxy


    【解决方案1】:

    看看 .call() 和 .apply() ,它们可以让您将所需的上下文作为第一个参数传递。

    http://odetocode.com/blogs/scott/archive/2007/07/05/function-apply-and-function-call-in-javascript.aspx

    所以在您的示例中,您可以使用 run.call(this); 而不是 run(),因此您将其作为回调函数的上下文传递。

    【讨论】:

      【解决方案2】:

      有一个由 ES5 标准定义的绑定函数,所有现代浏览器都支持(以及 shimmable 用于 IE8 及更低版本)

      你在你选择的函数上调用bind,一个新的函数将被返回。

      传递给bind 的第一个参数是您希望在结果函数内部设置为this 的对象,随后的参数将被柯里化。因此,对于您的情况,只需将 .bind(this) 添加到匿名函数即可。

      tt.bindTapEvent(container, '.showColumns', function(){
          container.find('.column').addClass('visible');
          $(this).doSomething(); //should work now
      }.bind(this));
      

      More info on MDN

      【讨论】:

      • 它不会和同样有'bind'的jQuery发生冲突吗?
      • 否 - 这个绑定是在函数上调用的 - 我假设 jQuery 的绑定是在 jQuery 对象本身上定义的。
      • 我明白了。未来看起来很棒,但移动版 Safari 目前缺乏支持。
      • 我觉得这是迄今为止最好的方法。
      【解决方案3】:

      如果您了解this issue,我希望您也了解.call.apply 方法:-)

      您需要在容器上下文中调用run-函数,分别在侦听器函数中调用this

      e.preventDefault();
      run.call(this, e);
      

      顺便说一句:您似乎声明并初始化了var self,但没有在任何地方使用它?

      【讨论】:

        猜你喜欢
        • 2012-03-22
        • 2011-06-21
        • 2014-11-08
        • 1970-01-01
        • 1970-01-01
        • 2012-05-10
        • 2020-07-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多