Federico
Federico

Reputation: 135

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

Given the following example code I want to set the onclick event to a function which I declare in the same method (no function in global scope):

<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>

If I use the code as is I only get the following error when the event is fired:

Uncaught SyntaxError: Unexpected token (

If instead I take the string of the function and remove the function part of it, the script works as expected:

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

Why is that so? Is there a better way? Obviously I can't declare the function without the function part, so what's the point in removing it again?

Upvotes: 2

Views: 1575

Answers (1)

GitaarLAB
GitaarLAB

Reputation: 14645

You were setting the actual textual element's attribute string using setAttribute, which in turn is auto-wrapped in a function!
Also, if it would have worked, there would be no body to click on once the image had disappeared.

Here is a working example you should not use, just intended to explain above statement:

Here is a function func which is converted to string (and where a string is expected, javascript usually calls the .toString() method automatically, I put it in to clearly show what happened).
Then, to prevent a quoting problem (you used double-quotes in html and for some (in my opinion, insane) reason some browsers replace single quotes in javascript to double quotes (and I've even witnessed some pre-compiling in some browsers)), I naively (because it was safe for this particular function) replaced all double quotes to single quotes.
Then we still need to remove function(){ and trailing }.
Now we arrived at the function string, which we can pass.
Finally the browser sets the actual textual attribute and wraps the code again inside a function so that it works.

<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>

Solution is obviously to document.body.onclick=func directly (as gillesc already commented), or use document.body.addEventListener('click',func,false) (which is what you are probably confused with).

Note that for backward compatibility (notably < IE9) you'd need attachEvent, here is a basic workaround:

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

Upvotes: 2

Related Questions