ES6 - 绑定`this`类后如何访问`this`元素?

时间:2016-11-26 06:32:51

标签: javascript jquery ecmascript-6 this

如何在绑定this类后访问this元素?

例如,没有绑定this

$(".button-open").click(function(event) {
    console.log(this); // <a href="#" class="button-open">Open</a>
    this.openMe();
});

使用绑定this

$(".button-open").click(function(event) {
   console.log(this); // Polygon {windowHeight: 965, scrollNum: 0}
   this.openMe();
}.bind(this));

如何在绑定<a href="#" class="button-open">Open</a>之后再次访问this

完整代码:

class Polygon {
    constructor() {
        this.windowHeight = $(window).height();
        this.scrollNum = 0;
    }

    // Simple class instance methods using short-hand method
    // declaration
    init() {
        var clickMe = this.clickMe.bind(this);
        return clickMe();
    }

    clickMe() {
        $(".button-open").click(function(event) {
            console.log(this);
            this.openMe();
        }.bind(this));


        $(".button-close").click(function(event) {
            this.closeMe();
        }.bind(this));
    }

    openMe() {
        console.log(this.scrollNum); // 0
        this.scrollNum = 200;
        console.log(this.scrollNum); // 200
        return false;

    }

    closeMe() {
        console.log(this.scrollNum); // 200
        return false;
    }
}

export { Polygon as default}

有什么想法吗?

修改

与jQuery animate相同的问题:

$(".element").animate({}, 'fast', 'swing', function(event) {
    console.log(this); // the element
}.bind(this));

绑定后:

$(".element").animate({}, 'fast', 'swing', function(event) {
    console.log(this); // undefined
}.bind(this));

再次获取element全局或防范方式

4 个答案:

答案 0 :(得分:5)

1。最好的选择是将上下文存储在变量中,不要覆盖this

var context = this;
$('.element').on('click', function(event) {
  // context would be the this you need
  // this is the element you need
});

2。如果你只是针对单个元素,你可以从上面反过来将你将处理程序绑定到的变量元素保存到变量中,然后在里面使用变量处理程序:

var el = $('.element');
el.on('click', function(event) {
  // use el here
}.bind(this));

由于您使用ES6标记了问题,因此将上下文与arrow function绑定可能会更好,因为使用bind更加详细并且还会创建一个额外的函数:

var el = $('.element');
el.on('click', (event) => {
  // this is the same as in the outer scope
  // use el here
});

3. 另一种选择是使用事件对象的target属性,但这也可以是元素中的任何子对象(目标是调度事件的元素,而不是你绑定处理程序的元素,因此它可能需要遍历DOM树来找到你需要的元素,效率较低。

var el = $('.element');
el.on('click', ({ target }) => {
  while (target.parentNode && !target.classList.contains('element')) {
    target = target.parentNode;
  }
  // here the target should be the element you need
});

答案 1 :(得分:2)

如果您没有使用this,则没有通用的方法可以访问.bind()的值。 Javascript没有办法取消绑定并取回this本来会有的内容。相反,你必须查看每个单独的情况,看看是否还有其他方法可以找到this的所有内容。

例如,正如我们几个人所说,在点击处理程序中,您可以访问event.target

jQuery animate不会将任何参数传递给它的回调,因此如果覆盖this,则没有通用的方法可以返回触发元素。您必须再次返回选择器或将值保存在包含的闭包中(人们通常使用名为self的变量)。

避免此问题的唯一通用方法是不使用.bind(),因此不会替换this的值。你可以这样做:

clickMe() {
    var self = this;
    $(".button-open").click(function(event) {
        // self is our ES6 object
        // this is the item that triggered the event
        console.log(this);
        self.openMe();
    });

答案 2 :(得分:1)

如果你绑定了你的处理程序,那么你仍然可以通过处理程序中的event.target获取被点击的项目。

https://api.jquery.com/on/

作为替代方案,您可以简单地执行

const self = this;

const me = this;

在您的任何事件侦听器声明之前,并且不绑定任何函数。然后在处理程序中,您可以使用this来引用当前元素,使用selfme来引用父作用域。

答案 3 :(得分:1)

已经回答了,但这里是我经常使用的模式:

如果有单个&#39; .element&#39;,则以下代码将起作用

var el = $('.element');
el.click(function(target, event){
    // target is the original this
    // this is the scope object
}.bind(this, el[0]));

但如果&#39; .element&#39;是指多个元素,然后代码将处理

var clickHandler = function(target, event){
    // target is the original this
    // this is the scope object
}.bind(this);

$('.element').click(function(e) {
    return clickHandler(this, e);
});