2013-07-07 2 views
1

Добрый день!Как передать локальную переменную из функции в функцию прослушивания событий в JavaScript?

Я начал писать свою собственную базовую библиотеку JavaScript для личного использования и распространения несколько дней назад, но у меня возникли проблемы с одним из методов, в частности bind().

Внутри самого метода этот относится к библиотеке объекта.

Я отправился в Google и нашел function.call(), но это не получилось так, как я его планировал - он просто выполнил функцию.

Если вы посмотрите на другой метод, каждый(), вы увидите, что он использует вызова() передавать значение.

Я также попытался следующие:

f.arguments[0]=this; 

Моя консоль выдает ошибку, заявив, что не может читать «0» из «не определено».

Я хотел был бы проголосовать (ссылаясь на библиотеку - НЕ ОКНО), чтобы использовать ее в прослушивателе событий.

Вы можете увидеть его, начиная с строки 195 JavaScript this JSFiddle.

Здесь так же:

bind:function(e,f){ 
    if(e.indexOf("on")==0){ 
     e=e.replace("on",""); 
    } 
    if(typeof f==='function'){ 
      /*Right now, 'this' refers to the library 
      How can I pass the library to the upcoming eventListener? 
      */ 
      //f=f(this); doesn't work 
      //f.call(this); //doesn't work 

      //this.target refers to the HTMLElement Object itself, which we are adding the eventListener to 
     //the outcome I'm looking for is something like this: 
     /*$('h3').which(0).bind(function({ 
      this.css("color:red"); 
     });*/ 
     //(which() defines which H3 element we're dealing with 
     //bind is to add an event listener 
      this.target.addEventListener(e,f,false) 
    } 
    return this; 
}, 

Большое вам спасибо за вашу помощь, авторы!

+0

Не могли бы вы поставить соответствующий код на этом посту здесь? Скрипка хороша для демонстрации, но мы не собираемся туда ехать и сканировать лоток 200+ loc только для понимания проблемы – Bergi

+0

Отредактировано.(Хорошая идея, lol) –

+1

Вы видели [JavaScript '.bind()'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) метод, который «[c] создает новую функцию, которая при вызове имеет свое ключевое слово« this', установленное на предоставленное значение »? Альтернативно, ваша библиотека '.bind()' могла передать свою собственную прокси-функцию в 'addEventListener()', а затем эта функция могла бы вызвать 'f', используя' .call() 'или' .apply() '. – nnnnnn

ответ

1

Если, согласно вашим комментариям, вы не хотите использовать .bind(), а не непосредственно проходя f к addEventListener() вы могли бы пройти еще одну функцию, которая в свою очередь, вызывает f с .call() или .apply():

if(typeof f==='function'){ 
    var _this = this; 
    this.target.addEventListener(e,function(event){ 
     f.call(_this, event); 
    },false) 
} 

Doing это также позволяет вашей библиотеке делать дополнительный администратор событий, например, предварительную обработку объекта event для нормализации свойств, которые отличаются для разных браузеров.

+0

Это, кажется, отлично работает. Большое спасибо! –

+0

Обратите внимание, что тест * typeof * может не уместиться, поскольку функция может быть методом хоста. В этом случае * typeof * может не возвращать * функцию *, хотя она может быть вызвана. – RobG

+0

@RobG: Я только [оператор 'typof'] (http://es5.github.io/#x11.4.3) был единственным, что ES5 дало нам определить, является ли объект вызываемым? (Не считая IE jScript, конечно) – Bergi

1

Итак, в этом конкретном случае вы действительно хотите позвонить JavaScript's built in bind method, что и все функции.

f = f.bind(this);

f будет новая функция это this аргумент установить все, что вы перешли в него.

+0

Я понятия не имел, что bind() был фактическим методом, но поскольку я смотрю на совместимость с ним, есть ли другой способ сделать это для поддержки более старых версий браузеров (в частности, Opera 9.5 или новее). –

+0

@RickyYoder - вам нужно будет сделать то, что [nnnnnn] (http://stackoverflow.com/a/17517005/11702) сказал в своем ответе. Это, по сути, такие библиотеки, как jQuery. – Josh

+0

Gotcha! Спасибо за новые знания, хотя! –

0

Заменить f=f(this); с f.apply(this);

Посмотрите на подчеркивание кода, здесь: https://github.com/jashkenas/underscore/blob/master/underscore.js#L596

+0

Это не сработает, потому что в любом случае он сразу же вызывает функцию 'f' - это необходимо сделать в сочетании с другими изменениями. Код подчеркивания, с которым вы связаны, имеет другую цель для OP. – nnnnnn

+0

mmm вы правы ... мой плохой. Фактически, это то, что он ищет: https://github.com/jquery/jquery/blob/master/src/core.js#L693 – neiker

Смежные вопросы