我有很多这些:
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');
})();
任何参赛者?
答案 0 :(得分:104)
你在问题中发布的例子没有任何问题。另一种做法可能看起来很奇怪,但是:
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
因此,为了命名你的函数并立即调用它,你需要定义一个局部变量,将你的函数作为一个表达式赋值给它,然后调用它。
答案 1 :(得分:11)
这有一个很好的简写(不需要声明任何变量来阻止函数的赋值):
var func = (function f(a) { console.log(a); return f; })('Blammo')
答案 2 :(得分:5)
这个设置没有问题(或者有吗?),但是我可以稍微平滑一下吗?
请注意使用事件委派。这就是你真正在没有消失的容器上观察事件的地方,然后在IE上使用event.target
(或event.srcElement
)来确定事件的实际位置发生并正确处理。
这样,您只需附加一次处理程序,即使您更换内容,它们也会继续工作。
以下是不使用任何帮助程序库的事件委派示例:
(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
进行调度,但您可以根据需要进行复杂或简单的匹配。
jQuery,Prototype,YUI,Closure或any of several others等现代JavaScript库应提供事件委派功能,以平滑浏览器差异并处理边缘案件干净利落。 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);
答案 3 :(得分:4)
您的代码包含拼写错误:
(function addEventsAndStuff() {
alert('oele');
)/*typo here, should be }*/)();
所以
(function addEventsAndStuff() {
alert('oele');
})();
的工作原理。干杯!
[编辑]基于评论:这应该运行并一次性返回该功能:
var addEventsAndStuff = (
function(){
var addeventsandstuff = function(){
alert('oele');
};
addeventsandstuff();
return addeventsandstuff;
}()
);
答案 4 :(得分:3)
您可能想要创建一个这样的辅助函数:
function defineAndRun(name, func) {
window[name] = func;
func();
}
defineAndRun('addEventsAndStuff', function() {
alert('oele');
});
答案 5 :(得分:1)
使用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"
答案 6 :(得分:0)
尝试这样做:
var addEventsAndStuff = (function(){
var func = function(){
alert('ole!');
};
func();
return func;
})();
答案 7 :(得分:0)
如果你想创建一个函数并立即执行 -
// 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();