2016-11-26 5 views
1

Как я могу получить доступ к элементу this после привязки this класс?ES6 - Как получить доступ к элементу `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} 

Любые идеи?

EDIT:

Та же проблема с 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 снова?

+3

косяк мы получаем доступ через event.tar получить? – Geeky

+0

С помощью селектора jQuery снова? – Li357

+0

@ Geeky да для клика, но не для анимации, см. Мое редактирование выше. – laukok

ответ

4

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 functionbind, потому что использование более громоздкое, а также создает дополнительные функции:

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 
}); 
+0

спасибо за ответ. 'target property' не работает в' animate'. – laukok

+1

Сохранение элемента перед обработчиком событий работает только в том случае, если объект jQuery является одноэлементным и содержит только один объект DOM. Если он содержит несколько элементов, вы все равно не знаете, какой элемент вызвал событие. – jfriend00

1

Если вы связаны обработчик, то вы можете получить элемент, который был щелкнули через event.target внутри обработчика.

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

В качестве альтернативы вы можете просто сделать

const self = this; 

или

const me = this; 

перед любой из ваших заявлений слушателей событий и без привязки каких-либо функций. Затем в обработчиках вы можете использовать this для обращения к текущему элементу и self или me для ссылки на родительскую область.

+0

Как насчет случая для 'animate'? – laukok

+0

спасибо. Я думаю, что это единственное решение после привязки. благодаря! – laukok

2

Нет никакого общего способа получить доступ к значению this, если вы не использовали .bind(). У Javascript нет способа отвязать и вернуть то, что было this. Вместо этого вы должны посмотреть на каждую отдельную ситуацию и посмотреть, есть ли другой способ добраться до того, что было бы this.

Например, как некоторые из нас сказали, в обработчике кликов вы можете получить доступ к event.target.

Анимация jQuery не передает никаких аргументов в свой обратный вызов, поэтому, если вы переопределяете 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(); 
    }); 
1

Он уже ответил, но вот картина, которую я обычно использую:

Если есть сингл «.element», приведенный ниже код будет работать

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

Но если «.element» относится к нескольким элементам, то ниже код будет обрабатывать, что

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); 
}); 
+0

спасибо за советы! – laukok

+0

btw, 'target' - это не то же самое, что' event.target' - это две разные вещи. – laukok

+0

Да, это «el» (объект jquery), который вы передали при привязке –