This is the most frustrating error I have probably ever had while coding. I'm trying to click a button and have it pop up "hello" in an alert box. If I remove the document ready it works. If I remove the function and just have the alert box in the document.ready, it also works but obviously without a click. However, that JS doesn't work all together and I have no idea why.
HTML
<button id="signup-box-button" type="button" onclick="signupSubmit()">sign up</button>
JS
$(document).ready(function(){
function signupSubmit(){
alert("hello");
}
});
When you put a function or variable inside a function its scope is limited to that function, this means that it will be visible only when inside that function.
To solve this, just move the function that is used outside of "ready function" to be visible outside.
$(document).ready(function(){
// code here
});
function signupSubmit(){
alert("hello");
}
Or, better yet. Leave Javascript code to Javascript file only, and let the HTML with HTML only.
HTML
<button id="signup-box-button" type="button">sign up</button>
Javascript
$(document).ready(function(){
$('#signup-box-button').click(function(){
alert("hello");
}
});
This is because of scoping in javaScript as explained by Skarllot
Please refer to know how this keyword works with inline event handlers.
You can use the below code snippet
$(document).ready(function(){
this.signupSubmit = function(){
alert("hello");
}
});
Refer JSFIDDLE
By adding this keyword the function will be registered in global scope. And the above solution may pollute the global namespace.
To better understand the above functionality:
Inline event handlers are evaluated in global scope. In your first example, signupSubmit is not defined in global scope, it is defined inside the function you pass to $(document).ready. Hence the inline event handler cannot find the function.
Here is a simplified example:
function ready() {
function signupSubmit() { }
}
ready();
signupSubmit(); // ReferenceError because signupSubmit is not defined in this scope
Note that there is no reason to put function definitions inside a $(document).ready callback, except for explicitly not putting them in global scope by using this keyword as mentioned in my first example.
Related
An oversimplified sample of my code:
<head>
<script type="text/javascript">
main();
function main() {
if(document.readyState == 'complete') {
function a() { /*do stuff*/ }
function b() { /*do stuff*/ }
} else {
setTimeout(function() { main(); }, 1000);
}
}
</script>
</head>
<body onload="javascript: main();">
<div onclick="javascript: a();"></div>
<div onclick="javascript: b();"></div>
</body>
I am wondering if there is a way for onclick events for a() and b() to be recognised without putting the <script> tag at the end of the document. I know I could do that relatively easily by making variables and functions global, but it's hardly good practice. I could probably utilise closures, but my original code has more functions than 2, and it would be quite a pain.
I know I could do that relatively easily by making variables and functions global, but it's hardly good practice.
If you're going to use onxyz-attribute-style event handlers, you have to make those functions accessible globally.
Which is one of the many reasons not to use them.
...without putting the tag at the end of the document.
That's an odd requirement, as that's where the script tag should go.
But you can do it in a couple of ways:
Using the DOMContentLoaded event, and hooking up your handlers using addEventListener within your event handler for it.
Using a setTimeout loop to wait for the elements to appear (usually this is a backstop for environments that don't have DOMContentLoaded, if there are any left).
Using event delegation, where you hook the event on document or document.body, then check whether the event travelled through the elements you're interested by looking at event.target and its parent elements (or using the relatively-new closest method).
Barring a really good reason for keeping the script in head, your best bet here is:
<head>
</head>
<body>
<div id="divA">divA</div>
<div id="divB">divB</div>
<script type="text/javascript">
main();
function main() {
document.getElementById("divA").addEventListener("click", function a() {
console.log("a click");
});
document.getElementById("divB").addEventListener("click", function b() {
console.log("b click");
});
}
</script>
</body>
...where using ids is just an example. In practice, you can often identify the relevant elements via a CSS selector you can use with document.querySelector or document.querySelectorAll.
Side note: You don't use the javascript: pseudo-protocol on onxyz-attribute-style event handlers. (You use it where a URL is expected, such as an href or a bookmark.)
Moving the script element won't help.
The a and b functions exist in the scope of the main function and are not accessible outside it.
The onclick functions depend on a and b being globals.
Either make them globals or transform the onclick attributes into JavaScript addEventListener calls (inside the main function).
I don't understand why this is not working.
I'm sticking to the reference on w3schools.
Here the code :
HTML:
<button onclick="click()">Test</button>
Javascript:
function click() {
alert("Hello !");
}
It doesn't work because you have configured JSFiddle to wrap the JavaScript in a function and call it onload. This stops your function being a global so it isn't in scope for your intrinsic event handler attribute.
Additionally, after you fix that, the weird scoping rules for intrinsic event attributes (I have no idea where these are documented) means that click is resolved as the button's click property before the scope is searched far enough to find the global click function.
The quick and dirty solution is:
Rename the function to something that doesn't clash with existing property names
Pick a no wrap option from the menu on the left of JSFiddle
The proper solution is to attach your event handlers with JavaScript. This isn't the 1990s and we should avoid using the techniques of that era that fail to separate concerns. Keep your JS in one place and your HTML in another.
<button>Test</button>
<script>
document.querySelector('button').addEventListener('click', click);
function click(evt) {
alert("Hello !");
}
</script>
This code doesn't work because there's already a click native method and shadowing it prevents the normal click event handling. Give it another name and it will work.
A way to see that is to define your button as
<button onclick="console.log(click)">Test</button>
I think you cann't give a function name as click. Change your function name & it should work.
click seems to be reserved.
Try renaming the method: http://jsfiddle.net/qeCE5/1/
function clickMe() {
alert("Hello !");
}
you need to change the function name. 'click' might be a reserved keyword, so it wont recognize when you call it. rename it to other names eg. 'democlick()'. also don't forget to save your code with '.html. extension. please tell me if any issue exists. thanks.
Why is this simple code not working? Can someone explain it to me?
JSFiddle
I have called the cc() function in onclick attribute.
HTML
<div> hey </div>
<button onclick="cc()"> click me to change color</button>
Javascript
$(document).ready(function () {
function cc() {
$('div').css('color', 'red');
};
});
cc is not a global function.
It is defined with a function declaration, so it is scoped to the function it is defined in.
That function is the anonymous one that you pass to the ready method. (And you do that inside a function that you run onload due to your jQuery configuration).
Globals are (in general) something to be avoided as much as possible, and intrinsic event attributes usually depend on them.
Don't use intrinsic event attributes. Bind your JavaScript event handlers using JavaScript. Since you are using jQuery, use the on method.
$(document).ready(function(){
function cc(){
$('div').css('color','red');
};
$('button').on('click', cc);
});
demo
The code in the onclick attribute only has access to global functions/variables. The function cc is local to the function it is defined in. You'll want to either define it outside of that function (so it is automatically global) or assign it to window.cc to explicitly make it global (I suggest the second option).
You should attach the handler inside the document.ready something like
html
<div> hey <div>
<button id="mybutton"> click me to change color</button>
javaScript
$(document).ready(function(){
//attach the function here
$("#mybutton").click(
function (){
$('div').css('color','red');
}
);
});
DEMO
As said by Quentin, cc isn't a global function.
But also, the function needs to be declared before it is called. So in fiddle, you should wrap the function in head.
Updated demo:http://jsfiddle.net/zWtZ2/3/
CC is a global
I have updated you fiddle with a working example
Html
<div> hey <div>
<button> click me to change color</button>
Javascript
$('button').click(function()
{
$('div').css('color','red');
});
http://jsfiddle.net/zWtZ2/4/
I wouldn't normally do this but I wanted to give you minimal changes to your code. As you are selecting every single button on div.
I have a sample code:
<input width="50" type="text" value="" name="application_id" id="text_input">
Test Name
And javascript
function addSelect(id, title) {
document.getElementById('text_input').value = title;
}
When I run code, result error is addSelect is not defined ? demo here , how to fit it ?
Your script has been defined to run onLoad, which means your function is not available in the global scope like you expect. It will be defined in a local scope of some onLoad method (whichever jsFiddle uses). With this setting, I think jsFiddle puts your code into this or something similar to:
window.onload = function () {
// Your code
};
(which is similar to onDomReady option)
This is so you don't have to worry about binding the right event and you can just test your script (making sure the page has loaded).
When you try to call the function, which you expect to be in the global scope, it won't work. Just change the setting on the left to no wrap (head) (or no wrap (body))
http://jsfiddle.net/TmLut/3/
And as mplungjan has pointed out, and I somehow didn't realize at all, when using the onclick of the anchor element, you'd probably want to prevent default behavior of the link (even if it's just to go to "#"), and can be achieved in several ways, but one is:
Text
Although at the same time, one might argue you shouldn't have inline handlers at all, and would want to be binding the event with Javascript completely. Depending on that case, you have options to prevent the default behavior still. In any case, you can still grab ahold of the event object (normalized per browsers...which jQuery does, by the way) and call event.preventDefault(); in the method.
Here its http://jsfiddle.net/TmLut/4/
I changed onload to head on the left side select box
$(function(){
function f1(){}
function f2(){}
}
<Input type = radio Name = radiobutton Value = "something" checked=checked onClick= //here call f1()//>
I try to get access to f1 function in OnClick
code like this doesn't work:
$.function.f1()
$.function().f1()
That's because you should be doing it something like this:
$(function () {
function foo () { }
function bar () { }
// bind
$('input').on('click', foo);
});
... instead of putting an onclick= attribute on your HTML markup.
EDIT
As requested, some quick notes on why you should do the jQuery bind instead of the onclick markup thing.
You're already using jQuery, plain and simple. Use it.
There should be significant effort made to separate your HTML, CSS and JS. HTML in HTML files, JS in JS files, blah. Putting in onclick=do_backflips() in your HTML markup violates that, and will lead to nightmarish maintenance issues in the future, among other things.
DOM0 onclick= syntax is inherently 1:1. Which means that naturally, for each event of each element, you only get to attach one single event handler. That definitely sucks balls.
By defining your f1 and f2 functions inside the document.ready handler function, you're limiting their scope within that function. This means that they can't be referenced outside that scope, which means that the script interpreter won't know about f1 where your HTML markup is. You have to attach event handlers where the handlers are known, and that's inside document.ready (if that makes sense).
The point of using $( function(){ ... } ) is that whatever inside is run only after the DOM has finished loading. There's no benefit to defining functions there unless the goal is to keep the namespace clean and use the functions in the local scope.
In this case you need the functions outside the scope so just move them outside the anonymous function or bind the event to the radio button inside the scope.