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!

Était-ce utile?

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:

  1. Permet de définir le this sera dans l'appel de fonction.
  2. 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 de foo.bar() this à foo et appelle bar.
  • En appelant la fonction via ses propres propriétés apply ou call; ceux this ensemble à leur premier argument. Par exemple, bar.apply(foo) ou bar.call(foo) fixeront this à foo et appel bar.

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top