addEventListener en utilisant apply ()
-
04-10-2019 - |
Question
Je suis en train d'invoquer la méthode addEventListener () à l'aide apply (). Le code est comme:
function rewrite(old){ return function(){ console.log( 'add something to ' + old.name ); old.apply(this, arguments); } } addEventListener=rewrite(addEventListener);
Il ne fonctionne pas. Le code fonctionne pour la méthode normale JavaScript, par exemple,
function hello_1(){ console.log("hello world 1!"); } hello_1=rewrite(hello_1);
Besoin d'aide!
Merci!
La solution
Vous ne pouvez pas compter sur addEventListener
étant une fonction réelle Javascript, malheureusement. (Cela est vrai de plusieurs autres fonctions proposées par l'hôte, comme window.alert
). De nombreux navigateurs font la bonne chose (tm) et les rendre vraies fonctions Javascript, mais certains navigateurs ne sont pas (je vous regarde, Microsoft). Et si ce n'est pas une vraie fonction Javascript, il ne sera pas les fonctions de apply
et call
comme sur les propriétés.
Par conséquent, vous ne pouvez pas vraiment faire génériquement avec des fonctions proposées par l'hôte, car vous avez besoin de la fonction apply
si vous voulez passer un nombre arbitraire d'arguments de votre proxy à votre cible. , Vous avez au lieu d'utiliser des fonctions spécifiques pour créer les emballages qui connaissent la signature de la fonction hôte impliqué, comme ceci:
// 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);
}
}
Lorsque vous appelez ça, en passant dans un élément, il retourne une fonction qui accrochera des gestionnaires d'événements à cet élément via addEventListener
. (Notez que IE avant IE8 ne pas addEventListener
, mais,. Il utilise à la place attachEvent
)
Je ne sais pas si cela convient à votre utilisation cas ou non (sinon, plus de détails sur le cas d'utilisation serait à portée de main).
Vous userait ci-dessus comme ceci:
// 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);
Notez que nous ne passons la référence de l'élément en proxy
lorsque nous l'avons appelé; il est déjà intégré dans la fonction, car la fonction est une fermeture. Si vous n'êtes pas familier avec eux, mon blog bouclages ne sont pas compliquées peut être utile.
Voici un exemple complet:
<!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>
En ce qui concerne votre question ci-dessous à propos func.apply()
vs func()
, je pense que vous avez probablement déjà compris, il est juste que mon original mauvaise réponse fait qu'embrouiller les choses. Mais juste au cas où: apply
appels de fonction, faire deux choses spéciales:
- Permet de définir le
this
sera dans l'appel de fonction. - Accepte les arguments pour donner à la fonction comme un tableau (ou quelque chose semblable à un tableau).
Comme vous le savez probablement, this
en Javascript est tout à fait différent de this
dans d'autres langages comme le C ++, Java ou C #. this
en Javascript n'a rien à voir avec où une fonction est définie, il est mis entièrement par la façon dont la fonction est appelé . Vous devez définir this
à la valeur correcte à chaque fois que vous appelez une fonction. (En savoir plus sur this
en Javascript .) Il y a deux façons de le faire:
- En appelant la fonction via une propriété d'objet; que les ensembles
this
à l'objet dans l'appel. par exemple, des ensembles defoo.bar()
this
àfoo
et appellebar
. - En appelant la fonction via ses propres propriétés
apply
oucall
; ceuxthis
ensemble à leur premier argument. Par exemple,bar.apply(foo)
oubar.call(foo)
fixerontthis
àfoo
et appelbar
.
La seule différence entre apply
et call
est de savoir comment ils acceptent les arguments pour passer à la fonction cible: apply
les accepte comme un tableau (ou une chose semblable à un tableau):
bar.apply(foo, [1, 2, 3]);
alors que call
les accepte comme arguments individuels:
bar.apply(foo, 1, 2, 3);
Les deux bar
d'appel, seting this
à foo
, et passant dans les arguments 1, 2 et 3.