Могу ли я назвать функцию javascript и выполнить ее немедленно?

У меня их довольно много:

function addEventsAndStuff() {
  // bla bla
}
addEventsAndStuff();

function sendStuffToServer() {
  // send stuff
  // get HTML in response
  // replace DOM
  // add events:
  addEventsAndStuff();
}

Повторное добавление событий необходимо, потому что DOM изменился, поэтому ранее прикрепленные события исчезли. Поскольку они также должны быть прикреплены первоначально (duh), у них хорошая функция быть сухими.

Нет ничего плохого в этой настройке (или есть?), но могу ли я немного ее сгладить? Я хотел бы создать функцию addEventsAndStuff и сразу вызвать ее, поэтому она не выглядит так дилетантистской.

Оба ответа отвечают на синтаксическую ошибку:

function addEventsAndStuff() {
  alert('oele');
}();

(function addEventsAndStuff() {
  alert('oele');
})();

Любые участники?

Ответ 1

Нет ничего плохого в примере, который вы опубликовали в своем вопросе. Другой способ сделать это может выглядеть странно, но:

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

Итак, чтобы назвать вашу функцию и сразу вызвать ее, вам нужно определить локальную переменную, назначить ей функцию как выражение, а затем вызвать ее.

Ответ 2

Нет ничего плохого в этой настройке (или есть?), но могу ли я немного ее сгладить?

Посмотрите на использование делегирования событий вместо этого. То, что вы фактически наблюдаете за событием в контейнере, который не уходит, а затем используйте 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 обрабатывает граничные случаи, если выше версия raw-off-off-off не работает):

(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);

Живая копия

Ответ 3

В вашем коде есть опечатка:

(function addEventsAndStuff() {
  alert('oele');
)/*typo here, should be }*/)();

так

(function addEventsAndStuff() {
  alert('oele');
 })();

работает. Ура!

[ изменить] на основе комментария: и это должно выполняться и возвращать функцию за один раз:

var addEventsAndStuff = (
 function(){
  var addeventsandstuff =  function(){
    alert('oele');
  };
  addeventsandstuff();
  return addeventsandstuff;
 }()
);

Ответ 4

Существует хорошая стенограмма этого (не нужно объявлять какие-либо переменные bar назначением функции):

var func = (function f(a) { console.log(a); return f; })('Blammo')

Ответ 5

Возможно, вы захотите создать вспомогательную функцию следующим образом:

function defineAndRun(name, func) {
    window[name] = func;
    func();
}

defineAndRun('addEventsAndStuff', function() {
    alert('oele');
});

Ответ 6

Попробуйте сделать так:

var addEventsAndStuff = (function(){
    var func = function(){
        alert('ole!');
    };
    func();
    return func;
})();

Ответ 7

Если вы хотите создать функцию и выполнить ее немедленно -

// 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();