将onclick事件设置为自定义函数导致语法错误

Setting the onclick event to a custom function results in syntax error

鉴于以下示例代码,我想将 onclick 事件设置为我在同一方法中声明的函数(全局范围内没有函数):

<HTML>
<HEAD>
<Title>Title</Title>
</HEAD>
<body>
<img id="img" class="std" src="http://www.free-animated-pictures.com/bug_crawls_on_screen.gif"/>
<script type='text/javascript'>
var i = document.getElementById("img");
var func = function(){
    var i = document.getElementById("img");
    if(i.className === "std"){
        i.className = "hid";
        i.style.display = "none";
    }
    else if(i.className === "hid"){
        i.className = "std";
        i.style.display = "block";
    }
};
//func = func.toString();
//func = func.replace("function ()", "")
document.body.setAttribute("onclick", func);
</script>
</body>
</HTML>

如果我按原样使用代码,我只会在触发事件时收到以下错误:

Uncaught SyntaxError: Unexpected token (

如果我改为获取函数的字符串并删除其中的 function 部分,脚本将按预期工作:

func = func.toString();
func = func.replace("function ()", "")

为什么会这样?有没有更好的办法?显然我不能在没有 function 部分的情况下声明函数,那么再次删除它有什么意义呢?

您正在使用 setAttribute 设置实际文本元素的属性 string,然后自动包装在一个函数中!
此外,如果它可行,一旦图像消失,就没有可点击的主体。

这是一个工作示例你不应该使用,只是为了解释上面的语句

这里有一个函数func转换成字符串(需要字符串的地方,javascript一般会自动调用.toString()方法,我放进去是为了清楚显示发生了什么事)。
然后,为了防止引用问题(您在 html 中使用了双引号,并且出于某些原因(在我看来,这是疯狂的)某些浏览器将 javascript 中的单引号替换为双引号(我什至在某些浏览器中目睹了一些预编译)),我 天真地 (因为它对这个特定函数是安全的)将所有双引号替换为单引号。
然后我们仍然需要删除 function(){ 和尾随 }.
现在我们到达了可以传递的函数字符串。
最后,浏览器设置实际的文本属性并将代码再次包装在一个函数中,这样它就可以工作了。

<img id="img" class="std" src="http://www.free-animated-pictures.com/bug_crawls_on_screen.gif" />
intentional text filler, otherwise body shrinks to 0*0 px leaving nothing to click on...
<script type='text/javascript'>
var func = function(){ 
    var i = document.getElementById('img');
    if(i.className === 'std'){
        i.className = 'hid';
        i.style.display = 'none';
    }
    else if(i.className === 'hid'){
        i.className = 'std';
        i.style.display = 'block';
    }
};

document.body.setAttribute( 'onclick'
                          , func.toString()
                                .replace(/\"/g,'\'')
                                .replace(/^function *\( *\) *{/,'')
                                .replace(/} *$/,'')
                          );
</script>

解决方案 显然是直接 document.body.onclick=func (正如 gillesc 已经评论过的那样),或者使用 document.body.addEventListener('click',func,false) (您可能对此感到困惑)。

请注意,为了向后兼容(尤其是 < IE9),您需要 attachEvent,这是基本的 workaround:

function addEventHandler(elem, eventType, handler) {
 if (elem.addEventListener)
     elem.addEventListener (eventType,handler,false);
 else if (elem.attachEvent)
     elem.attachEvent ('on'+eventType,handler); 
}