Reputation: 1653
I have one function inside another and I would like to call inner function from html document.
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="style.css">
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<input id="start" value="start" type="button" onclick="start()">
</body>
And JS.
function first()
{
alert("First")
function start()
{
alert("start");
}
}
Why in this case button doesn't work? Thank you
Upvotes: 1
Views: 193
Reputation: 2967
You have to readup on Javascript function/variable scoping.
Your start
function is defined inside your first
function, so it is seen as local to that function. In order for it to be available/callable from anywhere within your script, it has to belong to the global, or for browers, the window object.
There are a couple of ways you can achieve this.
1) Define the start
variable as a property of the window object, outside of the first function. Then, inside the first function, assign a function reference to it.
var start = null; //defined variable outside of any function, and so has global scope
function first()
{
alert("First")
//assign a function to global variable `start`
start = function()
{
alert("start");
}
}
first(); //when you invoke first, it creates the inner function and assigns its reference to the global `start` variable, which can then be invoked
start();
2) Using closure, return a named function from the outer function:
function first()
{
alert("First");
var start = function()
{
alert("start");
}
return start;
}
3) A slight variation on the above, return an anonymous function from the outer function:
function first()
{
alert("First");
return function()
{
alert("start");
}
}
In (2) and (3) above, when you call the function the first time, it will alert First
, then it will return a function which you can execute immediately or assign to a variable for deferred execution. For example:
first()(); //alerts `First`, which returns a function reference, which reference is executed right away, to the alert `start`
//alerts `First`, then assigns returned function to the variable `start`
var start = first(); //`start` now holds a function reference which you can execute anytime, like so:
start(); //alerts `start`
Finally, as a quick reminder, it is strongly advised that you use event-listeners to assign events to your elements, rather than using the onclick
or onwhatever
attribute directly within the element. This also falls in line with the principle of separation of concerns.
Following from that, the updated code should look something like below:
HTML
<input id="start" value="start" type="button"><!-- notice no `onclick` attribute attached to it -->
Attach the click event listener to button using Javascript:
var startBtn = document.getElementById("start");
if (typeof startBtn.addEventListener === "function")
{
startBtn.addEventListener("click", function(){first()()}, false);
}
else if (typeof startBtn.attachEvent === "function")
{
startBtn.attachEvent("onclick", function(){first()()});
}
else
{
startBtn.onclick = function(){first()()}
}
Upvotes: 1
Reputation: 161
why don't you make start a global function to call it from anywhere, even from you first function:
var start = function(){
alert("start");
},
first = function(){
alert("first");
start();
};
Upvotes: 0
Reputation: 782508
The function
keyword makes the name local to the function that it was defined in. Functions called from HTML attributes have to be global.
Then you have to call first()
before you can call start()
.
var start;
function first() {
alert("First");
start = function() {
alert("Start");
};
}
first();
<input id="start" value="start" type="button" onclick="start()">
Upvotes: 1
Reputation: 206618
That's cause your start
function is encapsulated inside the first
function scope.
One way is to expose your start
to the global window
object by assignment:
function first() {
alert("First");
window.start = function() { // encapsulated but available to the global window object
alert("start");
};
}
first(); // Still needed in order to execute it and expose `start`
A similar way exposing the start
variable outside of the function scope:
var start = null; // (Says hello to window)
function first() {
alert("First");
start = function() {
alert("start");
};
}
// Here `start` is still null
first(); // Now `start` is a function
Upvotes: 1