在匿名函数中更改$(this)上下文

时间:2012-06-06 20:53:21

标签: javascript jquery proxy

这是我用来在移动设备上绑定'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();
});

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

3 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:2)

有一个由ES5标准定义的绑定功能,并且得到所有现代浏览器的支持(以及IE8及以下的可调整

您可以在您选择的函数上调用bind,并返回一个新函数。

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

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

More info on MDN

答案 2 :(得分:0)

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

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

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

顺便说一句:您似乎声明并初始化var self,但无处使用它?