全局命名空间和点击函数的污染



假设代码

//(function() {
function addItem() {
alert("item added!");
}
//})();
<button onclick="addItem()">add item</button>

如果我注意不污染全局命名空间,并取消注释注释的代码,我的功能将被破坏......

对于此类问题,通常的解决方法是什么,使 html 内联"打开..."事件处理程序?


作为乞丐读者的注意事项

有经验的开发人员可能会建议避免内联onclick属性。不使用它们的众多原因包括:

  • 表现和行为之间的紧密耦合;
  • 代码(通常(在全局范围内运行;
  • 使测试和调试变得困难;
  • 无视渐进式增强;
  • 很快变得难以维护;
  • 此外,它还将取消绑定任何以前分配的点击处理程序,这可能是不必要的副作用;

你想要在这里关闭:

var myGlobalClosure = (function(){
var myPrivateVariable = "item added from inside closure!";
function addItem() {
alert(myPrivateVariable);
}

return {addItem:addItem};
})();
//if I have variable collisions they don't affect my closed over code.
//so this illustrates one of the big advantages of this pattern
var myPrivateVariable = "this is in the global scope and won't do anything";
<button onclick="myGlobalClosure.addItem()">add item</button>

上面的闭包是揭示模块模式的示例。这是一种常见的 JS 结构设计模式。

最终,某些内容需要在全局范围内,否则您将无法引用它。这里的想法是组织您的全局对象,以便它们具有结构。这也将防止标准函数/对象名称(如click等(发生冲突。

这就是大多数库构建代码的方式,例如jQuery/$是在 jQuery 函数和对象上关闭的闭包。

不是内联事件,而是使用EventTarget.addEventListener()通过JS使用事件绑定。

(function() {
var add_btn = document.getElementById('add_btn');
function addItem() {
alert("item added!");
}
add_btn.addEventListener('click', addItem);
})();
<button id="add_btn">add item</button>

如果您确实需要保留内联onclick属性,另一种解决方案是将整个事件处理程序代码放在那里:

<button onclick="
void function () {
function addItem() {
alert('item added');
}
addItem();
}()
">add item</button>


您还可以将函数存储在按钮元素本身中,然后在onclick处理程序中查找它:

document.getElementById('add_butt').addItem = function () {
alert("item added");
};
<button id="add_butt" onclick="this.addItem()">add item</button>

最新更新