我希望所有按钮在其正常的 onclick 事件之前和之后执行一个 Action 。因此,我想出了循环遍历所有这些元素并创建包装函数的“绝妙”想法。
当我测试它时,它似乎工作得很好,但当我将它集成到我们的应用程序中时,它就崩溃了。我追踪到“这个”值被我的包装器改变了。示例代码说明了这一点;在包装事件处理程序之前,每个按钮都会在您单击时显示按钮 ID,但在包装之后显示的名称在此示例中为“未定义”,或者如果您从表单中运行它则为“Form1”。
有人知道做同样事情的更好方法吗?还是保持最初预期的“this”值的好方法?
如您所想,我不想修改目标按钮中的任何现有事件处理程序代码。
提前致谢。
PS-目标浏览器为 IE6 及以上,不需要跨浏览器功能
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<script language="javascript" type="text/javascript">
function btnWrap_onClick()
{
var btns = document.getElementsByTagName("button");
for( var i = 0; i < btns.length; i++)
{
var btn = btns[i];
// handle wrap button differerntly
if( "btnWrap" == btn.id)
{
btn.disabled = true;
continue; // skip this button
}
// wrap it
var originalEventHandler = btn.onclick;
btn.onclick = function()
{
alert("Starting event handler");
originalEventHandler();
alert("Finished event handler");
}
}
alert("Buttons wrapped successfully");
}
</script>
<body>
<p>
<button id="TestButton1" onclick="alert(this.id);">TestButton1</button>
<button id="TestButton2" onclick="alert(this.id);">TestButton2</button>
</p>
<button id="btnWrap" onclick="btnWrap_onClick();">Wrap Event Handlers</button>
</body>
</html>
最佳答案
您可以使用 call解决绑定(bind)的方法,例如originalEventHandler.call(btn);
或者,像原型(prototype)这样的库可以提供帮助 - 它的 bind方法允许您构建绑定(bind)到指定对象的新函数,因此您已将 originalEventHandler 声明为 var originalEventHandler = btn.onclick.bind(btn);
最后,有关绑定(bind)问题的良好背景资料,另请参阅 Getting Out of Binding Situations in JavaScript
关于javascript - 当我包装一个函数时,有没有办法防止 'this' 发生变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/400968/