J'en ai plusieurs:
function addEventsAndStuff() {
// bla bla
}
addEventsAndStuff();
function sendStuffToServer() {
// send stuff
// get HTML in response
// replace DOM
// add events:
addEventsAndStuff();
}
La réajout des événements est nécessaire car le DOM a changé, donc les événements précédemment attachés ont disparu. Puisqu'ils doivent également être attachés au départ (duh), ils ont une bonne fonction d'être DRY.
Il n'y a rien de mal avec cette configuration (ou y en a-t-il?), Mais puis-je l'adoucir un peu? J'aimerais créer leaddEventsAndStuff()
fonction et l'appeler immédiatement, donc ça n'a pas l'air si amateur.
Les deux suivants répondent avec une erreur de syntaxe:
function addEventsAndStuff() {
alert('oele');
}();
(function addEventsAndStuff() {
alert('oele');
})();
N'importe quels preneurs?
javascript
function
Rudie
la source
la source
Réponses:
Il n'y a rien de mal avec l'exemple que vous avez publié dans votre question. L'autre façon de procéder peut paraître étrange, mais:
var addEventsAndStuff; (addEventsAndStuff = function(){ // add events, and ... stuff })();
Il existe deux façons de définir une fonction en JavaScript. Une déclaration de fonction:
function foo(){ ... }
et une expression de fonction, qui est tout moyen de définir une fonction autre que celle ci-dessus:
var foo = function(){}; (function(){})(); var foo = {bar : function(){}};
...etc
Les expressions de fonction peuvent être nommées, mais leur nom n'est pas propagé à la portée contenant. Signifiant que ce code est valide:
(function foo(){ foo(); // recursion for some reason }());
mais ce n'est pas:
(function foo(){ ... }()); foo(); // foo does not exist
Ainsi, pour nommer votre fonction et l'appeler immédiatement, vous devez définir une variable locale, lui affecter votre fonction en tant qu'expression, puis l'appeler.
la source
call()
méthode à partir d'ici: stackoverflow.com/a/12359154/1231001Il y a un bon raccourci à cela (ne pas avoir besoin de déclarer de variables sauf l'attribution de la fonction):
var func = (function f(a) { console.log(a); return f; })('Blammo')
la source
r
sera la fonction retournée? Lefunction r
ou levar r
? Juste curieux. Bonne solution. N'avait pas à être un loc cependant =)return r
cela aurait été lefunction r
car c'était sa portée. J'ai écrit Scala en permanence pour essayer d'obtenir quelque chose en ligne.Regardez plutôt l'utilisation de la délégation d'événements. C'est là que vous surveillez l'événement sur un conteneur qui ne disparaît pas, puis utilisez
event.target
(ouevent.srcElement
sur IE) pour déterminer où l'événement s'est réellement produit et le gérer correctement.De cette façon, vous n'attachez le ou les gestionnaires qu'une seule fois, et ils continuent de fonctionner même lorsque vous échangez du contenu.
Voici un exemple de délégation d'événements sans utiliser de bibliothèques d'assistance:
(function() { var handlers = {}; if (document.body.addEventListener) { document.body.addEventListener('click', handleBodyClick, false); } else if (document.body.attachEvent) { document.body.attachEvent('onclick', handleBodyClick); } else { document.body.onclick = handleBodyClick; } handlers.button1 = function() { display("Button One clicked"); return false; }; handlers.button2 = function() { display("Button Two clicked"); return false; }; handlers.outerDiv = function() { display("Outer div clicked"); return false; }; handlers.innerDiv1 = function() { display("Inner div 1 clicked, not cancelling event"); }; handlers.innerDiv2 = function() { display("Inner div 2 clicked, cancelling event"); return false; }; function handleBodyClick(event) { var target, handler; event = event || window.event; target = event.target || event.srcElement; while (target && target !== this) { if (target.id) { handler = handlers[target.id]; if (handler) { if (handler.call(this, event) === false) { if (event.preventDefault) { event.preventDefault(); } return false; } } } else if (target.tagName === "P") { display("You clicked the message '" + target.innerHTML + "'"); } target = target.parentNode; } } function display(msg) { var p = document.createElement('p'); p.innerHTML = msg; document.body.appendChild(p); } })();
Exemple en direct
Notez que si vous cliquez sur les messages qui sont ajoutés dynamiquement à la page, votre clic est enregistré et géré même s'il n'y a pas de code pour accrocher les événements sur les nouveaux paragraphes ajoutés. Notez également que vos gestionnaires ne sont que des entrées dans une carte et que vous avez un gestionnaire sur le
document.body
qui s'occupe de toute la répartition. Maintenant, vous enracinez probablement cela dans quelque chose de plus ciblé quedocument.body
, mais vous voyez l'idée. De plus, dans ce qui précède, nous distribuons essentiellement parid
, mais vous pouvez faire des correspondances aussi complexes ou simples que vous le souhaitez.Bibliothèques JavaScript modernes comme jQuery , Prototype , YUI , Closure ou l' un de plusieurs autres devraient offrir des fonctionnalités de délégation d'événements pour lisser les différences de navigateur et gérer proprement les cas de bord. jQuery le fait certainement, avec ses fonctions
live
et sesdelegate
fonctions, qui vous permettent de spécifier des gestionnaires en utilisant une gamme complète de sélecteurs CSS3 (et plus encore).Par exemple, voici le code équivalent utilisant jQuery (sauf que je suis sûr que jQuery gère les cas de bord, la version brute prête à l'emploi ci-dessus ne le fait pas):
(function($) { $("#button1").live('click', function() { display("Button One clicked"); return false; }); $("#button2").live('click', function() { display("Button Two clicked"); return false; }); $("#outerDiv").live('click', function() { display("Outer div clicked"); return false; }); $("#innerDiv1").live('click', function() { display("Inner div 1 clicked, not cancelling event"); }); $("#innerDiv2").live('click', function() { display("Inner div 2 clicked, cancelling event"); return false; }); $("p").live('click', function() { display("You clicked the message '" + this.innerHTML + "'"); }); function display(msg) { $("<p>").html(msg).appendTo(document.body); } })(jQuery);
Copie en direct
la source
Event.target
, car ce n'est pas toujours la bonne cible. C'est vrai. Si vous cliquez sur un à l'IMG
intérieurDIV
et queDIV
l'événement a l'événement, ceEvent.target
sera leIMG
et il n'y a aucun moyen d'obtenir l'DIV
objet correctement. edit Btw I hate.live
'event' de jQueryevent.target
: Ce que vous décrivez n'est pas faux, c'est correct. Si vous cliquez sur un à l'img
intérieurdiv
et que vous regardez lediv
,event.target
est leimg
(etthis
est lediv
). Jetez un autre coup d'œil à ce qui précède. Vous pouvez attacher un gestionnaire à n'importe quel point de la chaîne entre l'élément sur lequelimg
vous avez cliqué (le , par exemple) et l'élément que vous regardez (dans ce qui précède, tout en basdocument.body
). Relive
: Je préfère énormémentdelegate
, la version plus contenue delive
. J'ai utilisélive
ci-dessus parce que c'était le plus proche de ce que j'avais fait dans l'exemple brut. Best,Vous voudrez peut-être créer une fonction d'assistance comme celle-ci:
function defineAndRun(name, func) { window[name] = func; func(); } defineAndRun('addEventsAndStuff', function() { alert('oele'); });
la source
Votre code contient une faute de frappe:
(function addEventsAndStuff() { alert('oele'); )/*typo here, should be }*/)();
donc
(function addEventsAndStuff() { alert('oele'); })();
travaux. À votre santé!
[ modifier ] basé sur le commentaire: et cela devrait exécuter et renvoyer la fonction en une seule fois:
var addEventsAndStuff = ( function(){ var addeventsandstuff = function(){ alert('oele'); }; addeventsandstuff(); return addeventsandstuff; }() );
la source
ReferenceError
Encore plus simple avec ES6:
var result = ((a, b) => `${a} ${b}`)('Hello','World') // result = "Hello World" var result2 = (a => a*2)(5) // result2 = 10 var result3 = (concat_two = (a, b) => `${a} ${b}`)('Hello','World') // result3 = "Hello World" concat_two("My name", "is Foo") // "My name is Foo"
la source
concat_two
fonctionne parfaitement, MAIS il le définit toujours dans la portée globale, donc il ne fonctionnera pas avec"use strict"
. Ce n'est pas important pour moi, mais c'est un petit inconvénient.Si vous souhaitez créer une fonction et l'exécuter immédiatement -
// this will create as well as execute the function a() (a=function a() {alert("test");})(); // this will execute the function a() i.e. alert("test") a();
la source
Essayez de faire comme ça:
var addEventsAndStuff = (function(){ var func = function(){ alert('ole!'); }; func(); return func; })();
la source
var foo = (function() {...})();
appelle la fonction avant l'affectation. La parenthèse doit inclure l'affectation. (Vous voulez attribuer alors appeler.)