Klick
Klick

Reputation: 1653

How to call a function in other function from html document - JavaScript.

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

Answers (4)

NaijaProgrammer
NaijaProgrammer

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

DDA
DDA

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

Barmar
Barmar

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

Roko C. Buljan
Roko C. Buljan

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

Related Questions