116

I can't find out what is the problem with this JSFiddle.

HTML:

<input type="button" value="test" onclick="test()">

JavaScript:

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

And when I click on button - nothing happened. The console says "test not defined"

I've read the JSFiddle documentation - there it says that JS code is added to <head> and HTML code is added to <body> (so this JS code is earlier than html and should work).

3
  • Removing the parentheses would also work under normal non fiddle circumstances though it is definitely good advice to separate js from HTML as much as possible. I only allow myself the style =" display:none" CSS inline no-no. Commented Dec 11, 2012 at 19:45
  • related: JavaScript not running on jsfiddle.net Commented Mar 11, 2013 at 16:06
  • If you’re looking for the opposite problem — i.e. the code works in JSFiddle, but not locally — see Using document.getElementById() inside object, works in JSFiddle, TypeError in actual. Why?. Both behaviors have the same cause: JSFiddle automatically wraps JS code in a function that is executed as soon as the DOM is ready, which also causes onclick to be out of scope. Commented Dec 3, 2022 at 23:10

7 Answers 7

101

If you do not specify the wrap setting it defaults to "onLoad". This results with all JavaScript being wrapped in a function run after result has been loaded. All variables are local to this function thus unavailable in the global scope.

Change the wrapping setting to "no wrap" and it'll work:

http://jsfiddle.net/zalun/Yazpj/1/

I switched the framework to "No Library" as you don't use any.

Sign up to request clarification or add additional context in comments.

Comments

60

The function is being defined inside a load handler and thus is in a different scope. As @ellisbben notes in the comments, you can fix this by explicitly defining it on the window object. Better, yet, change it to apply the handler to the object unobtrusively: http://jsfiddle.net/pUeue/

$('input[type=button]').click( function() {
   alert("test");   
});

Note applying the handler this way, instead of inline, keeps your HTML clean. I'm using jQuery, but you could do it with or without a framework or using a different framework, if you like.

4 Comments

@Innuendo - jsFiddle uses separate frames for code/html/style sheets. you'd need to reference the frame in the function call, but there isn't really an easy way to do that since the frame doesn't have a name. It's really a problem because of the way jsfiddle works, but it's still a good idea to keep your javascript completely separate.
@tvanfosson- your solution works, but jsfiddle doesn't use separate frames to show the result; see jsfiddle.net/Yazpj/show. The reason it didn't work initially is that test was defined inside of an onLoad function; using window.test = function(){/*...*/} makes it work perfectly well.
@ellisbben - if I use Firebug to inspect the DOM, each of the 4 separate panes exists in a separate iframe.
Yes, but if you examine the single iframe used to show the example, you'll see that it puts all of the code in a single page that does not use frames, hence those frames cannot break your example. Append show to any jsfiddle URL to see what I'm talking about: jsfiddle.net/Yazpj/show
22

There is another way, declare your function into a variable like this :

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

jsFiddle


Details

EDIT (based on the comments of @nnnnnn)

@nnnnnn :

why saying test = (without var) would fix it ?

When you define a function like this :

var test = function(){};

The function is defined locally, but when you define your function without var :

test = function(){};

test is defined on the window object which is at the top level scope.

why does this work?

Like @zalun say :

If you do not specify the wrap setting it defaults to "onLoad". This results with all JavaScript being wrapped in a function run after result has been loaded. All variables are local to this function thus unavailable in the global scope.

But if you use this syntax :

test = function(){};

You have an access to the function test because it's defined globally


References :

6 Comments

This is really the simplest approach is you're just testing a tiny bit of code in JSFiddle.
But why does this work? The "More information" link you provided doesn't explain that the problem is related to scope, or why saying test = (without var) would fix it.
@R3tep well your first link which is : jsfiddle.net/R3tep/Yazpj/1406 alert doesn't do anything for me. I'm on chrome.
@R3tep yeah it works with console.log. I'll post a question on SO because I believe the fact that I've no alert box is linked to another problem I've with iframes.
@R3tep I think you misunderstood me but I'm not sure. Your code is/was good. There is an issue with how JSFiddle is coded (missing value in sandbox attribute of the iframe they are using to display the result). That makes it such it won't work on some version of chrome. I sent an issue report on their github. I was that much interested in it because I thought the issue I'm having on my website was the same but no. Cheers.
|
3

Change wrap setting in the Frameworks & Extensions panel, to "No wrap-in <body>"

Comments

-1

There is no problem with your code.Just choose the extension onLoad() from right side.

Comments

-2
<script> 
function test(){
 alert("test");   
}
</script>

<input type="button" value="test" onclick="test()">

Comments

-4
Select OnDomready

HTML:

<input id="dButton" type="button" value="test"/>

JavaScript:

addEventListener('load', init, false);

function init()
{
  oInput = document.getElementById('dButton');
  oInput.onclick = test;
}

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.