Вы не можете рассчитывать на addEventListener
, являющийся настоящей функцией Javascript, к сожалению. (Это справедливо для нескольких других функций, предоставляемых хостом, таких как window.alert
). Многие браузеры делают Right Thing (tm) и делают их истинными функциями Javascript, но некоторые браузеры этого не делают (я смотрю на вас, Microsoft). И если это не настоящая функция Javascript, она не будет иметь функции apply
и call
.
Следовательно, вы не можете сделать это в общем случае с предоставленными хостом функциями, потому что вам нужна функция apply
, если вы хотите передать произвольное количество аргументов из вашего прокси-сервера в вашу цель. Вместо этого, вы должны использовать специальные функции для создания оберток, которые знают подпись функции принимающего участия, как это:
// Returns a function that will hook up an event handler to the given
// element.
function proxyAEL(element) {
return function(eventName, handler, phase) {
// This works because this anonymous function is a closure,
// "closing over" the `element` argument
element.addEventListener(eventName, handler, phase);
}
}
Когда вы звоните, что, переходя в элементе, он возвращает функцию, которая будет подключить обработчиков событий к этому элементу через addEventListener
. (Обратите внимание, что IE до IE8 не имеет addEventListener
, но вместо этого он использует attachEvent
.)
Не знаю, подходит ли это для вашего использования или нет (если нет, более подробная информация о прецеденте будет удобна).
Вы использовали бы выше, как это:
// Get a proxy for the addEventListener function on btnGo
var proxy = proxyAEL(document.getElementById('btnGo'));
// Use it to hook the click event
proxy('click', go, false);
Обратите внимание, что мы не передать ссылку элемент в proxy
, когда мы назвали его; он уже встроен в функцию, потому что функция является закрытием. Если вы не знакомы с ними, может оказаться полезным мое сообщение в блоге Closures are not complicated.
Вот полный пример:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
#log p {
margin: 0;
padding: 0;
}
</style>
<script type='text/javascript'>
window.onload = pageInit;
function pageInit() {
var proxy;
// Get a proxy for the addEventListener function on btnGo
proxy = proxyAEL(document.getElementById('btnGo'));
// Use it to hook the click event
proxy('click', go, false);
}
// Returns a function that will hook up an event handler to the given
// element.
function proxyAEL(element) {
return function(eventName, handler, phase) {
// This works because this anonymous function is a closure,
// "closing over" the `element` argument
element.addEventListener(eventName, handler, phase);
}
}
function go() {
log('btnGo was clicked!');
}
function log(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.getElementById('log').appendChild(p);
}
</script>
</head>
<body><div>
<input type='button' id='btnGo' value='Go'>
<hr>
<div id='log'></div>
</div></body>
</html>
Что касается Вашего вопроса ниже примерно func.apply()
VS. func()
, я думаю, вы, вероятно, уже понял, это просто, что мой первоначальный неправильный ответ спутать вопросы. Но на всякий случай: функции apply
вызовов, делая две специальные вещи:
- Устанавливает, что
this
будет в вызове функции.
- Принимает аргументы для предоставления функции как массива (или любой подобной массиву вещи).
Как вы, наверное, знаете, this
в JavaScript, довольно сильно отличается от this
в некоторых других языках, таких как C++, Java или C#. this
в Javascript не имеет ничего общего с тем, где определена функция, она полностью определяется тем, как функция называется.Вы должны установить this
на правильное значение каждый раз, когда вы вызываете функцию. (Подробнее о в Javascript herethis
.) Есть два способа сделать это:
- путем вызова функции через свойство объекта; который устанавливает
this
объекту внутри вызова. например foo.bar()
, this
- foo
и звонки bar
.
- Вызвать функцию через свои собственные
apply
или call
свойства; те устанавливают this
в свой первый аргумент. Например, bar.apply(foo)
или bar.call(foo)
установит this
на номер foo
и позвоните по номеру bar
.
Единственное различие между apply
и call
как они принимают аргументы для перехода к целевой функции: apply
принимает их как массив (или массив, как вещь):
bar.apply(foo, [1, 2, 3]);
тогда call
принимает их как отдельные аргументы:
bar.apply(foo, 1, 2, 3);
Те, как называют bar
, седениями this
т o foo
, и переходя в аргументы 1, 2 и 3.
Возможно, я не могу написать подпись addEvetnListener, поскольку это может произойти во время выполнения. Есть ли обходной путь? – Paul
@Paul: 'addEventListener' имеет определенную, определенную подпись. Для реальных функций * Javascript * в общем случае вы можете делать то, что делали. Просто эти неприятные функции, предоставляемые хостом, которые не могут быть «реальными», что вам нужно работать, и у них будут определенные подписи. –
@ Crowder, Извините, я либо неправильно понял, либо оговорюсь ... Я попытался сказать, что, учитывая ваш примерный код, как узнать элемент? (Я использую Firefox.) Также, что отличает fun.apply() и func() (т. Е. Какая разница между вашим кодом и кодом)? Благодаря! – Paul