1

I have some javascript that should print a string to the console, however it also executes another function that is defined elsewhere. The script is:

var run_once = function() {
    console.log("run_once has executed.");
};

var to_print = "This should print.";
run_once();

document.getElementById("test_button").addEventListener("click", console.log(to_print));

HTML:

<!DOCTYPE html>
<html>
    <body>
        <form method="post">
            <button id="test_button">test</button>
        </form>
        <script src="../scripts/drill_creator.js"></script>
    </body>
</html>

When the page is refreshed I get the following printed to the console:

run_once has executed.         drill_creator.js:2
This should print.             drill_creator.js:8 
Navigated to file:///C:/Users/micha/Google%20Drive/k-drills/Source/html/drill_creator.html

Then upon clicking the test_button, the console displays:

run_once has executed.         drill_creator.js:2
This should print.             drill_creator.js:8 
Navigated to file:///C:/Users/micha/Google%20Drive/k-drills/Source/html/drill_creator.html
run_once has executed.         drill_creator.js:2
This should print.             drill_creator.js:8 
Navigated to file:///C:/Users/micha/Google%20Drive/k-drills/Source/html/drill_creator.html

Why does run_once get called when a click occurs? Also, why does "This should print." get printed when the page loads but the button isn't clicked?

Thanks very much

Michael

EDIT: I have changed the last javascript line to:

document.getElementById("test_button").addEventListener("click", function(){console.log(to_print)});

Which solves the problem of the event firing on page load (thanks very much Joshua K) however this still results in run_once being called when the button is clicked. After loading the first two lines below are displayed, then clicking the button, displays the next three:

run_once has executed.         drill_creator.js:2
Navigated to file:///C:/Users/micha/Google%20Drive/k-drills/Source/html/drill_creator.html
This should print.             drill_creator.js:8 
Navigated to file:///C:/Users/micha/Google%20Drive/k-drills/Source/html/drill_creator.html
run_once has executed.         drill_creator.js:2

SECOND EDIT:

As Joshu K mentions in the comments on his answer, the button element acts as a submit by default. To get a button that does not trigger the form's action, but can be used to call additional javascript, one can use:

<input type="button" value="text on the button">

After making the two changes above, the code functions as I'd hoped.

Thank you all for your suggestions.

MichaelCG8
  • 579
  • 2
  • 14

1 Answers1

1

This line is wrong: document.getElementById("test_button").addEventListener("click", console.log(to_print));

you don't define a callback, you call the console.log function.

Correct: document.getElementById("test_button").addEventListener("click", ()=>console.log(to_print));

or

document.getElementById("test_button").addEventListener("click", function() {console.log(to_print)});

Joshua K
  • 2,407
  • 1
  • 10
  • 13
  • or easier: `document.getElementById("test_button").addEventListener("click", console.log.bind(null, to_print));` – quirimmo Sep 25 '17 at 22:14
  • 1
    @quirimmo That is not easier just 1-2 char shorter... – inf3rno Sep 25 '17 at 22:15
  • 1
    @quirimmo why is this easier? Yes it's also a solution, but easier? `()=>console.log()` is pretty easy, or? – Joshua K Sep 25 '17 at 22:16
  • @inf3rno I find that easier, that's one of the reasons cause they invented the `bind` method. Moreover you don't define any other additional not needed function – quirimmo Sep 25 '17 at 22:16
  • 1
    @quirimmo that's not true. This is not a reasion why `bind` was invented and: what's wrong with defining a lambda function? `bind` also defines a _new_ function (in memory). So I cannot see the benefit of using bind over arrow function. – Joshua K Sep 25 '17 at 22:19
  • @quirimmo Because we are answering to somebody who does not understand the difference between a function and a function call (so probably does not even know `bind`) and you are hiding the fact that `addEventListener` requires a function argument. – inf3rno Sep 25 '17 at 22:22
  • The page is also reloading when you click the button, that’s why you’re seeing it twice – Ben Cummins Sep 25 '17 at 22:27
  • This explains why both are printed when the page is loaded. It does not answer "Why does run_once get called when a click occurs?". `console.log` returns `undefined`, so no event listener is registered. Then you have a form with a missing `action`, which defaults to the URL of the current document. So a POST request is sent and reloads the page. – nickie Sep 25 '17 at 22:30
  • Thank you all for your comments, I have changed the argument of addEventListener to ("click", function(){console.log(to_print)}) which solves the problem of it firing right away. @nickie, I'm unsure why the event firing triggers the forms action, shouldn't that only happen when the submit button is clicked? – MichaelCG8 Sep 25 '17 at 22:44
  • @MichaelCG8 a button element is meant to be a submit button! If you need a button without the abbility you can use `` or you have to use `evt.preventDefault()` in your javascript event handler – Joshua K Sep 25 '17 at 22:46
  • @JoshuaK Aaah, I see. I thought you needed to use suggestion. It's working perfectly, thank you very much! – MichaelCG8 Sep 25 '17 at 22:53