Simon_Weaver
Simon_Weaver

Reputation: 146228

How to change onClick handler dynamically?

I'm sure there are a million posts about this out there, but surprisingly I'm having trouble finding something.

I have a simple script where I want to set the onClick handler for an <A> link on initialization of the page.

When I run this I immediately get a 'foo' alert box where I expected to only get an alert when I click on the link.

What stupid thing am I doing wrong? (I've tried click= and onClick=)...

<script language="javascript">

    function init(){

        document.getElementById("foo").click = new function() { alert('foo'); };
    }

</script>

<body onload="init()">
    <a id="foo" href=#>Click to run foo</a>
</body>

Edit: I changed my accepted answer to a jQuery answer. The answer by 'Már Örlygsson' is technically the correct answer to my original question (click should be onclick and new should be removed) but I strongly discourage anyone from using 'document.getElementById(...) directly in their code - and to use jQuery instead.

Upvotes: 55

Views: 165788

Answers (11)

Selin Ebeci
Selin Ebeci

Reputation: 151

I tried more or less all of the other solutions the other day, but none of them worked for me until I tried this one:

var submitButton = document.getElementById('submitButton');
submitButton.setAttribute('onclick',  'alert("hello");');

As far as I can tell, it works perfectly.

Upvotes: 15

Eric
Eric

Reputation: 141

OMG... It's not only a problem of "jQuery Library" and "getElementById".

Sure, jQuery helps us to put cross-browser problems aside, but using the traditional way without libraries can still work well, if you really understand JavaScript ENOUGH!!!

Both @Már Örlygsson and @Darryl Hein gave you good ALTARNATIVES(I'd say, they're just altarnatives, not anwsers), where the former used the traditional way, and the latter jQuery way. But do you really know the answer to your problem? What is wrong with your code?

First, .click is a jQuery way. If you want to use traditional way, use .onclick instead. Or I recommend you concentrating on learning to use jQuery only, in case of confusing. jQuery is a good tool to use without knowing DOM enough.

The second problem, also the critical one, new function(){} is a very bad syntax, or say it is a wrong syntax.

No matter whether you want to go with jQuery or without it, you need to clarify it.

There are 3 basic ways declaring function:

function name () {code}

... = function() {code} // known as anonymous function or function literal

... = new Function("code") // Function Object

Note that javascript is case-sensitive, so new function() is not a standard syntax of javascript. Browsers may misunderstand the meaning.

Thus your code can be modified using the second way as

 = function(){alert();}

Or using the third way as

 = new Function("alert();");

Elaborating on it, the second way works almost the same as the third way, and the second way is very common, while the third is rare. Both of your best answers use the second way.

However, the third way can do something that the second can't do, because of "runtime" and "compile time". I just hope you know new Function() can be useful sometimes. One day you meet problems using function(){}, don't forget new Function().

To understand more, you are recommended read << JavaScript: The Definitive Guide, 6th Edition >>, O'Reilly.

Upvotes: 5

Web Development Guy
Web Development Guy

Reputation: 1

The YUI example above should really be:

<script>
  YAHOO.util.Event.onDOMReady(function() {   
     Dom.get("foo").onclick =  function (){alert('foo');};
  });
</script>

Upvotes: 0

Steven Lu
Steven Lu

Reputation: 43547

Nobody addressed the actual problem which was happening, to explain why the alert was issued.

This code: document.getElementById("foo").click = new function() { alert('foo'); }; assigns the click property of the #foo element to an empty object. The anonymous function in here is meant to initialize the object. I like to think of this type of function as a constructor. You put the alert in there, so it gets called because the function gets called immediately.

See this question.

Upvotes: 0

lamarant
lamarant

Reputation: 3400

I think you want to use jQuery's .bind and .unBind methods. In my testing, changing the click event using .click and .onclick actually called the newly assigned event, resulting in a never-ending loop.

For example, if the events you are toggling between are hide() and unHide(), and clicking one switches the click event to the other, you would end up in a continuous loop. A better way would be to do this:

$(element).unbind().bind( 'click' , function(){ alert('!') } ); 

Upvotes: 0

yuttadhammo
yuttadhammo

Reputation: 5199

If you want to pass variables from the current function, another way to do this is, for example:

document.getElementById("space1").onclick = new Function("lrgWithInfo('"+myVar+"')");

If you don't need to pass information from this function, it's just:

document.getElementById("space1").onclick = new Function("lrgWithInfo('13')");

Upvotes: 11

Darryl Hein
Darryl Hein

Reputation: 145137

jQuery:

$('#foo').click(function() { alert('foo'); });

Or if you don't want it to follow the link href:

$('#foo').click(function() { alert('foo'); return false; });

Upvotes: 23

blak3r
blak3r

Reputation: 16546

Here is the YUI counterpart to the jQuery posts above.

<script>
  YAHOO.util.Event.onDOMReady(function() {   
    document.getElementById("foo").onclick =  function (){alert('foo');};
  });
</script>

Upvotes: 1

kgiannakakis
kgiannakakis

Reputation: 104196

I agree that using jQuery is the best option. You should also avoid using body's onload function and use jQuery's ready function instead. As for the event listeners, they should be functions that take one argument:

document.getElementById("foo").onclick = function (event){alert('foo');};

or in jQuery:

$('#foo').click(function(event) { alert('foo'); }

Upvotes: 2

M&#225;r &#214;rlygsson
M&#225;r &#214;rlygsson

Reputation: 14606

Use .onclick (all lowercase). Like so:

document.getElementById("foo").onclick = function () {
  alert('foo'); // do your stuff
  return false; // <-- to suppress the default link behaviour
};

Actually, you'll probably find yourself way better off using some good library (I recommend jQuery for several reasons) to get you up and running, and writing clean javascript.

Cross-browser (in)compatibilities are a right hell to deal with for anyone - let alone someone who's just starting.

Upvotes: 37

Christian C. Salvad&#243;
Christian C. Salvad&#243;

Reputation: 828170

Try:

document.getElementById("foo").onclick = function (){alert('foo');};

Upvotes: 73

Related Questions