Eu tenho alguns destes:
function addEventsAndStuff() {
// bla bla
}
addEventsAndStuff();
function sendStuffToServer() {
// send stuff
// get HTML in response
// replace DOM
// add events:
addEventsAndStuff();
}
É necessário adicionar novamente os eventos porque o DOM foi alterado, então os eventos previamente anexados desapareceram. Uma vez que eles devem ser fixados inicialmente também (duh), eles estão em uma boa função para serem SECOS.
Não há nada de errado com essa configuração (ou há?), Mas posso suavizar um pouco? Gostaria de criar a addEventsAndStuff()
função e chamá-la imediatamente, para que não pareça tão amadorística.
Ambos os seguintes respondem com um erro de sintaxe:
function addEventsAndStuff() {
alert('oele');
}();
(function addEventsAndStuff() {
alert('oele');
})();
Qualquer comprador?
javascript
function
Rudie
fonte
fonte
Respostas:
Não há nada de errado com o exemplo que você postou em sua pergunta. A outra maneira de fazer isso pode parecer estranha, mas:
var addEventsAndStuff; (addEventsAndStuff = function(){ // add events, and ... stuff })();
Existem duas maneiras de definir uma função em JavaScript. Uma declaração de função:
function foo(){ ... }
e uma expressão de função, que é qualquer forma de definir uma função diferente da acima:
var foo = function(){}; (function(){})(); var foo = {bar : function(){}};
... etc
expressões de função podem ser nomeadas, mas seu nome não é propagado para o escopo contido. Significa que este código é válido:
(function foo(){ foo(); // recursion for some reason }());
mas isso não é:
(function foo(){ ... }()); foo(); // foo does not exist
Portanto, para nomear sua função e chamá-la imediatamente, você precisa definir uma variável local, atribuir sua função a ela como uma expressão e chamá-la.
fonte
call()
método aqui: stackoverflow.com/a/12359154/1231001Há um bom atalho para isso (não é necessário declarar nenhuma variável para além da atribuição da função):
var func = (function f(a) { console.log(a); return f; })('Blammo')
fonte
r
será a função de retorno? Ofunction r
ou ovar r
? Apenas curioso. Boa solução. Não precisava ser um loc, embora =)return r
teria sido ofunction r
porque era seu escopo. Tenho escrito Scala tão permanentemente tentando colocar algo online.Considere o uso da delegação de eventos. É onde você realmente observa o evento em um contêiner que não desaparece e, em seguida, usa
event.target
(ouevent.srcElement
no IE) para descobrir onde o evento realmente ocorreu e tratá-lo corretamente.Dessa forma, você anexa o (s) manipulador (es) apenas uma vez e eles continuam funcionando mesmo quando você troca o conteúdo.
Aqui está um exemplo de delegação de evento sem usar nenhuma biblioteca auxiliar:
(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); } })();
Exemplo vivo
Observe como, se você clicar nas mensagens que são adicionadas dinamicamente à página, seu clique é registrado e manipulado, embora não haja nenhum código para conectar eventos nos novos parágrafos que estão sendo adicionados. Observe também como seus manipuladores são apenas entradas em um mapa, e você tem um manipulador no
document.body
que faz todo o despacho. Agora, você provavelmente enraíza em algo mais direcionado do quedocument.body
, mas essa é a ideia. Além disso, no exemplo acima, basicamente estamos enviando porid
, mas você pode fazer correspondências tão complexas ou simples quanto desejar.Bibliotecas JavaScript modernas como jQuery , Prototype , YUI , Closure ou qualquer uma das várias outras devem oferecer recursos de delegação de eventos para amenizar as diferenças do navegador e lidar com casos extremos de forma limpa. jQuery certamente o faz, com suas funções
live
edelegate
, que permitem especificar manipuladores usando uma gama completa de seletores CSS3 (e mais alguns).Por exemplo, aqui está o código equivalente usando jQuery (exceto que tenho certeza de que jQuery lida com casos extremos que a versão bruta improvisada acima não):
(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);
Cópia ao vivo
fonte
Event.target
, porque esse nem sempre é o alvo certo. Está certo. Se você clicar em umIMG
dentro de aDIV
eDIV
tiver o evento,Event.target
será oIMG
e não há como obter oDIV
objeto de maneira adequada. editar Btw eu odeio o.live
'evento' do jQueryevent.target
: O que você descreve não está errado, está correto. Se você clicar em umimg
dentro de adiv
e estiver assistindo adiv
,event.target
é oimg
(ethis
é odiv
). Dê uma outra olhada no acima. Você pode anexar um manipulador em qualquer ponto da cadeia entre o elemento que foi clicado (oimg
, por exemplo) e o elemento que você está observando (acima, até abaixodocument.body
). Relive
: Eu prefiro muitodelegate
a versão mais contida delive
. Useilive
acima porque era o mais próximo do que fiz no exemplo bruto. Best,Você pode querer criar uma função auxiliar como esta:
function defineAndRun(name, func) { window[name] = func; func(); } defineAndRun('addEventsAndStuff', function() { alert('oele'); });
fonte
Seu código contém um erro de digitação:
(function addEventsAndStuff() { alert('oele'); )/*typo here, should be }*/)();
então
(function addEventsAndStuff() { alert('oele'); })();
trabalho. Felicidades!
[ editar ] com base no comentário: e isso deve ser executado e retornar a função de uma vez:
var addEventsAndStuff = ( function(){ var addeventsandstuff = function(){ alert('oele'); }; addeventsandstuff(); return addeventsandstuff; }() );
fonte
ReferenceError
Ainda mais simples com 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"
fonte
concat_two
funciona perfeitamente, MAS sempre o define no âmbito global, então não vai funcionar"use strict"
. Isso não é importante para mim, mas é uma pequena desvantagem.Se você deseja criar uma função e executá-la imediatamente -
// 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();
fonte
Tente fazer assim:
var addEventsAndStuff = (function(){ var func = function(){ alert('ole!'); }; func(); return func; })();
fonte
var foo = (function() {...})();
chama a função antes da atribuição. O parêntese deve incluir a atribuição. (Você deseja atribuir, em seguida, ligue.)