views:

389

answers:

2

I have the following code:

function sdefaults()
{
   alert("test");
}

var btnpos, sbtn;
btnpos = document.getElementsByName('somePosition')[0];
sbtn = document.createElement('input');
btnpos.parentNode.insertBefore(sbtn, btnpos.nextSibling);
sbtn.type = "button";
sbtn.name = "social";
sbtn.value = "Defaults";
sbtn.onClick = sdefaults();

The button appears where I want it to and the name/value are set correctly. However when I load the page, the sdefaults() function is run and then if I click the button, nothing happens. Could anyone provide any insight into how to prevent the function from running on load and force it to only run onclick?

Thanks

+4  A: 

Change:

sbtn.onClick = sdefaults();

to:

sbtn.onClick = sdefaults;

sbtn.onClick = sdefaults(); means: "Run the sdefaults function and store the result in sbtn.onClick.

btn.onClick = sdefaults; means: "Set sbtn.onClick to the function sdefaults", which is what you're looking for.

Josh
Thanks for the tip, I try that and it stops the function from running on page load, however clicking the button continues to do nothing.
cd
@cd: try `onclick` instead of `onClick`?
Josh
Thanks for the response Josh. onclick exhibits the same behaviour.btn.onclick = sdefaults;
cd
Then my recommendation would be to use a framework like jQuery or Prototype. I know this can be done easily in Prototype with `$(btn).observe('click',sdefaults);` -- I haven't actually used `btn.onclick` in years.
Josh
Thanks for the assistance Josh. because this is a greasemonkey script I don't think I can use Prototype.Cheers
cd
@cd: I think you're right. I'm not sure why it's not working...
Josh
@cd: Just a thought, does `btn.onClick = 'sdefaults';` work?
Josh
@cd, for what it's worth, you definitely can use jQuery with Greasemonkey, either by using `@require` or by inserting the `<script>` element into the page itself (e.g. http://joanpiedra.com/jquery/greasemonkey/).
npdoty
+2  A: 

You have to understand the difference between function referencing, and function invocation.

Consider the following function

function foo()
{
  alert( 'Hello World' );
}

Now, lets look at some samples of referencing this function. To reference a function, we use its symbol name, just like any other variable.

// Alert contents of foo
alert( foo );

// Set foo as the click handler for the body
document.body.onclick = foo;

// Assign a new function to foo
foo = function(){ alert( 'Goodbye!' ); }

Now we'll consider function invocation. This means the function executes and its return value is sent back to the calling scope.

// Invoke foo simply
foo();

// Invoke foo with a specific scope
foo.apply( this ); // or foo.call( this );

Now, it's entirely possible to modify your code snippet just by changing the code of sdefaults(). Here's how that would look.

function sdefaults()
{
  return function()
  {
    alert("test");
  }
}

Now, when you execute sbtn.onClick = sdefaults(); what happens is the onClick property receives what its expecting, a function, since we've modified sdefaults to not actually alert "test", but to return an anonymous function which itself will alert "test". (As a side note, this specific technique is commonly called a lambda or delegate function)

Hope that clears it up.

Peter Bailey
This is an excellent explanation... except you never told him to change his code to `btn.onClick = sdefaults;` which ultimately fixes the issue he's having... Instead you told him how to make `btn.onClick = sdefaults();` work, which is a little backwards in my opinion...
Josh
Well, I felt I didn't need to since your answer already does that.
Peter Bailey
@Peter Bailey: Fair enough. Your answer was much more in depth than mine. I'll give you +1 tomorrow, I'm at my vote limit for the day :-)
Josh