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

Javascript 在匿名函数中更改$(此)上下文,javascript,jquery,proxy,Javascript,Jquery,Proxy,这是我用来绑定移动设备上的“点击”事件的函数。基本上是一个正常的函数 bindTapEvent: function(container, selector, run, bindClickAlso){ var startX, startY, currentX, currentY = 0; var moved = false; var self; if(touchDevice){ container.on({ click: f

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

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();
});
唯一的问题是,我不能(显然)在这样的somtheing中使用$(this)。我已经读过关于jQuery$.proxy的文章,它改变了上下文,但是我无法理解它,所以我可以使用它。在我的例子中,当我使用$时,是否可以将tt.BindTapeEvent中使用的匿名函数的上下文更改为该上下文(这)它只在BindTapeEvent函数中“存储”和“使用”?

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


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

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

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();
            });
        }
    }
}
在选择的函数上直接调用bind,将返回一个新函数

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

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

如果您知道,我希望您也知道方法和方法:-)

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

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

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

它是否与同样具有“bind”的jQuery冲突?不-这个绑定是在函数上调用的-我想jQuery的绑定是在jQuery对象本身上定义的。我理解。对未来来说似乎很棒,但移动Safari目前缺乏支持。我觉得这是迄今为止最好的方式。