Saya punya beberapa di antaranya:
function addEventsAndStuff() {
// bla bla
}
addEventsAndStuff();
function sendStuffToServer() {
// send stuff
// get HTML in response
// replace DOM
// add events:
addEventsAndStuff();
}
Penambahan kembali peristiwa diperlukan karena DOM telah berubah, sehingga peristiwa yang dilampirkan sebelumnya akan hilang. Karena mereka harus dipasang pada awalnya juga (ya), mereka dalam fungsi yang bagus untuk menjadi KERING.
Tidak ada yang salah dengan pengaturan ini (atau apakah ada?), Tetapi bisakah saya menghaluskannya sedikit? Saya ingin membuat addEventsAndStuff()
fungsi dan segera memanggilnya, jadi tidak terlihat begitu amatir.
Keduanya menanggapi berikut dengan kesalahan sintaks:
function addEventsAndStuff() {
alert('oele');
}();
(function addEventsAndStuff() {
alert('oele');
})();
Ada yang mau?
javascript
function
Rudie
sumber
sumber
Jawaban:
Tidak ada yang salah dengan contoh yang Anda posting di pertanyaan Anda .. Cara lain melakukannya mungkin terlihat aneh, tetapi:
var addEventsAndStuff; (addEventsAndStuff = function(){ // add events, and ... stuff })();
Ada dua cara untuk mendefinisikan fungsi di JavaScript. Deklarasi fungsi:
function foo(){ ... }
dan ekspresi fungsi, yang merupakan cara apa pun untuk mendefinisikan fungsi selain di atas:
var foo = function(){}; (function(){})(); var foo = {bar : function(){}};
... dll
ekspresi fungsi bisa diberi nama, tapi namanya tidak disebarkan ke lingkup yang mengandung. Artinya kode ini valid:
(function foo(){ foo(); // recursion for some reason }());
tapi ini bukan:
(function foo(){ ... }()); foo(); // foo does not exist
Jadi untuk menamai fungsi Anda dan segera memanggilnya, Anda perlu mendefinisikan variabel lokal, menetapkan fungsi Anda sebagai ekspresi, lalu memanggilnya.
sumber
call()
metode dari sini: stackoverflow.com/a/12359154/1231001Ada cara singkat yang bagus untuk ini (tidak perlu mendeklarasikan variabel apa pun untuk menetapkan fungsi):
var func = (function f(a) { console.log(a); return f; })('Blammo')
sumber
r
Fungsi mana yang akan dikembalikan? Thefunction r
atauvar r
? Hanya penasaran. Solusi bagus. Tidak harus menjadi satu lokasi =)return r
akan menjadifunction r
seperti itu ruang lingkupnya. Telah menulis Scala secara permanen mencoba untuk mendapatkan sesuatu secara online.Lihat menggunakan delegasi acara sebagai gantinya. Di situlah Anda benar-benar menonton acara di wadah yang tidak hilang, dan kemudian menggunakan
event.target
(atauevent.srcElement
di IE) untuk mencari tahu di mana peristiwa sebenarnya terjadi dan menanganinya dengan benar.Dengan begitu, Anda hanya memasang penangan satu kali, dan penangan tetap berfungsi bahkan saat Anda menukar konten.
Berikut adalah contoh delegasi acara tanpa menggunakan lib helper:
(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); } })();
Contoh langsung
Perhatikan bagaimana jika Anda mengklik pesan yang secara dinamis ditambahkan ke halaman, klik Anda didaftarkan dan ditangani meskipun tidak ada kode untuk menghubungkan peristiwa pada paragraf baru yang ditambahkan. Perhatikan juga bagaimana penangan Anda hanyalah entri di peta, dan Anda memiliki satu penangan di atasnya
document.body
yang melakukan semua pengiriman. Sekarang, Anda mungkin mengakar ini pada sesuatu yang lebih bertarget daripadadocument.body
, tetapi Anda mengerti. Selain itu, di atas pada dasarnya kami mengirimid
, tetapi Anda dapat melakukan pencocokan sesulit atau sesederhana yang Anda suka.Library JavaScript modern seperti jQuery , Prototype , YUI , Closure , atau beberapa lainnya harus menawarkan fitur delegasi acara untuk memperhalus perbedaan browser dan menangani kasus edge dengan rapi. jQuery tentu melakukannya, dengan its
live
dandelegate
fungsinya, yang memungkinkan Anda menentukan penangan menggunakan berbagai selektor CSS3 (dan kemudian beberapa).Misalnya, inilah kode yang setara menggunakan jQuery (kecuali saya yakin jQuery menangani kasus tepi versi mentah off-the-cuff di atas tidak):
(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);
Salinan langsung
sumber
Event.target
, karena itu bukan alwaus target yang tepat. Betul sekali. Jika Anda mengklik diIMG
dalam aDIV
danDIV
memiliki acara,Event.target
akan menjadiIMG
dan tidak ada cara untuk mendapatkanDIV
objek dengan baik. edit Btw Aku benci.live
'acara' jQueryevent.target
: Apa yang Anda gambarkan tidak salah, itu benar. Jika Anda mengklik bagianimg
dalam adiv
dan Anda menontondiv
,event.target
is theimg
(andthis
is thediv
). Coba lihat lagi di atas. Anda dapat memasang penangan di titik mana pun dalam rantai antara elemen yang diklik (img
misalnya) dan elemen yang Anda tonton (di atas, di bawahdocument.body
). Relive
: Saya sangat sukadelegate
, versi yang lebih berisilive
. Saya menggunakan dilive
atas karena itu paling dekat dengan apa yang telah saya lakukan dalam contoh mentah. Hormat kami,Anda mungkin ingin membuat fungsi pembantu seperti ini:
function defineAndRun(name, func) { window[name] = func; func(); } defineAndRun('addEventsAndStuff', function() { alert('oele'); });
sumber
Kode Anda mengandung kesalahan ketik:
(function addEventsAndStuff() { alert('oele'); )/*typo here, should be }*/)();
begitu
(function addEventsAndStuff() { alert('oele'); })();
bekerja. Bersulang!
[ edit ] berdasarkan komentar: dan ini harus menjalankan dan mengembalikan fungsi sekaligus:
var addEventsAndStuff = ( function(){ var addeventsandstuff = function(){ alert('oele'); }; addeventsandstuff(); return addeventsandstuff; }() );
sumber
ReferenceError
Lebih sederhana lagi dengan 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"
sumber
concat_two
bekerja dengan sempurna, TAPI selalu mendefinisikannya dalam lingkup global, jadi itu tidak akan berfungsi"use strict"
. Itu tidak penting bagi saya, tapi itu kerugian kecil.Jika Anda ingin membuat fungsi dan segera menjalankan -
// 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();
sumber
Coba lakukan seperti itu:
var addEventsAndStuff = (function(){ var func = function(){ alert('ole!'); }; func(); return func; })();
sumber
var foo = (function() {...})();
memanggil fungsi sebelum tugas. Tanda kurung perlu menyertakan tugas. (Anda ingin menetapkan kemudian menelepon.)