У меня их довольно много:
function addEventsAndStuff() {
// bla bla
}
addEventsAndStuff();
function sendStuffToServer() {
// send stuff
// get HTML in response
// replace DOM
// add events:
addEventsAndStuff();
}
Повторное добавление событий необходимо, так как DOM изменилась, поэтому ранее прикрепленные события исчезли. Поскольку они тоже должны быть прикреплены изначально (да), они могут быть СУХИМИ.
В этой настройке нет ничего плохого (или есть?), Но можно ли немного сгладить? Я бы хотел создать addEventsAndStuff()
функцию и сразу вызвать ее, чтобы она не выглядела такой дилетантской.
Оба следующих ответа дают синтаксическую ошибку:
function addEventsAndStuff() {
alert('oele');
}();
(function addEventsAndStuff() {
alert('oele');
})();
Есть берущие?
javascript
function
Руди
источник
источник
Ответы:
Нет ничего плохого в примере, который вы разместили в своем вопросе. Другой способ сделать это может показаться странным, но:
var addEventsAndStuff; (addEventsAndStuff = function(){ // add events, and ... stuff })();
Есть два способа определить функцию в JavaScript. Объявление функции:
function foo(){ ... }
и выражение функции, которое является любым способом определения функции, кроме указанного выше:
var foo = function(){}; (function(){})(); var foo = {bar : function(){}};
...так далее
функциональные выражения могут иметь имя, но их имя не распространяется на содержащую область. Это означает, что этот код действителен:
(function foo(){ foo(); // recursion for some reason }());
но это не так:
(function foo(){ ... }()); foo(); // foo does not exist
Итак, чтобы назвать свою функцию и сразу вызвать ее, вам нужно определить локальную переменную, назначить ей свою функцию как выражение, а затем вызвать ее.
источник
call()
метод отсюда: stackoverflow.com/a/12359154/1231001Для этого есть хорошее сокращение (не нужно объявлять какие-либо переменные, запрещающие назначение функции):
var func = (function f(a) { console.log(a); return f; })('Blammo')
источник
r
вернет функция?function r
Илиvar r
? Просто любопытно. Хорошее решение. Хотя не обязательно быть одним местом =)return r
было быfunction r
так, как это было. Я писал Scala так постоянно, пытаясь получить что-то онлайн.Вместо этого посмотрите на использование делегирования событий. Вот где вы на самом деле наблюдаете за событием в контейнере, который не исчезает, а затем используете
event.target
(илиevent.srcElement
в IE), чтобы выяснить, где на самом деле произошло событие, и правильно его обработать.Таким образом, вы прикрепляете обработчик (-ы) только один раз, и они продолжают работать, даже когда вы меняете контент.
Вот пример делегирования событий без использования вспомогательных библиотек:
(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); } })();
Живой пример
Обратите внимание, как если вы щелкаете сообщения, которые динамически добавляются на страницу, ваш щелчок регистрируется и обрабатывается, даже если нет кода для привязки событий к добавляемым новым абзацам. Также обратите внимание, что ваши обработчики - это просто записи на карте, и у вас есть один обработчик,
document.body
который выполняет всю отправку. Теперь вы, вероятно, укорените это в чем-то более целенаправленномdocument.body
, но вы поняли идею. Кроме того, в приведенном выше примере мы в основном осуществляем рассылкуid
, но вы можете выполнить сопоставление настолько сложным или простым, насколько захотите.Современные библиотеки JavaScript, такие как jQuery , Prototype , YUI , Closure или любые другие, должны предлагать функции делегирования событий, чтобы сгладить различия браузеров и аккуратно обрабатывать крайние случаи. JQuery , конечно же, с обеих его
live
иdelegate
функций, которые позволяют Вам определять обработчики , используя полный спектр CSS3 селекторов (и затем некоторые).Например, вот эквивалентный код с использованием jQuery (за исключением того, что я уверен, что jQuery обрабатывает крайние случаи, а необработанная исходная версия выше не работает):
(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);
Живая копия
источник
Event.target
, потому что это не всегда правильная цель. Вот так. Если вы нажмете наIMG
внутри aDIV
и уDIV
негоEvent.target
будет событие, будетIMG
и нет никакого способа получитьDIV
объект красиво. edit Btw I hate jQuery's.live
'event'event.target
: То, что вы описываете, не является неправильным, это правильно. Если щелкнутьimg
внутриdiv
и вы смотритеdiv
,event.target
этоimg
(иthis
естьdiv
). Взгляните еще раз на вышеизложенное. Вы можете прикрепить обработчик в любой точке цепочки между элементом, который был нажат (img
например,), и элементом, который вы наблюдаете (в приведенном выше примере, полностью внизdocument.body
). Relive
: Я предпочитаюdelegate
более содержательную версиюlive
. Я использовалlive
выше, потому что это было ближе всего к тому, что я сделал в необработанном примере. Best,Возможно, вы захотите создать вспомогательную функцию, подобную этой:
function defineAndRun(name, func) { window[name] = func; func(); } defineAndRun('addEventsAndStuff', function() { alert('oele'); });
источник
Ваш код содержит опечатку:
(function addEventsAndStuff() { alert('oele'); )/*typo here, should be }*/)();
так
(function addEventsAndStuff() { alert('oele'); })();
работает. Ура!
[ править ] на основе комментария: и это должно запускаться и возвращать функцию за один раз:
var addEventsAndStuff = ( function(){ var addeventsandstuff = function(){ alert('oele'); }; addeventsandstuff(); return addeventsandstuff; }() );
источник
ReferenceError
С 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"
источник
concat_two
работает отлично, НО он всегда определяет его в глобальной области, поэтому он не будет работать с"use strict"
. Для меня это не важно, но это крошечный недостаток.Если вы хотите создать функцию и немедленно выполнить -
// 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();
источник
Попробуйте сделать так:
var addEventsAndStuff = (function(){ var func = function(){ alert('ole!'); }; func(); return func; })();
источник
var foo = (function() {...})();
вызывает функцию перед назначением. В скобках должно быть указано присвоение. (Вы хотите назначить, тогда звоните.)