3

So, I'm trying to make a dice roller that can, you guessed it!, roll dice. I want to call a javascript function within a HTML button click. I know this is very easy with angular, but I am not using Angular. I am using jQuery, but I don't want to make the whole thing jQuery, however, if I have to, I will. Anyway, I am trying to make a button that adds a die, one that removes a die, one that adds a side to the dice, and one that removes a side from the dice. Oh, and one that rolls the dice, but I've already coded that in.
Here's my HTML (note: I am using jQuery so it might look a little weird):

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">
      $("#button0").click(function(){
        diceRoll = 0
        for (i=diceAmt;i>0;i--) {
          diceRoll += rand(1, diceSides)
        }
        document.getElementById("dieRoll").innerHTML = diceRoll;
      })
    </script>
  </head>
  <body>
    <div class="screen">
      <div class="top">
        <div class="text">
          <span id="dieRoll"></span>
        </div>
        &nbsp;
        <button class="button1" id="button0"></button>
      </div>
      <div class="bottom">
        <button class="button2">Add die</button>
        &nbsp;
        <button class="button3">Remove die</button>
        <br/>
        <button class="button2">Add side</button>
        &nbsp;
        <button class="button3">Remove side</button>
      </div>
    </div>
  </body>
</html>

Here's my JavaScript (again might look a little weird):

var diceAmt = 2
var diceSides = 6
var diceRoll
var xDx = diceAmt+"d"+diceSides
function floor(num){let n1=Math.round(num);let n2=n1-1;if(n1>num){return n2}else{return n1}}
function rand(num1,num2){let n1=num2+1-num1;let n2=floor(Math.random()*n1)+num2;return n2}
function addDie () {
  diceAmt += 1
  xDx = diceAmt+"d"+diceSides
  document.getElementById("button0").innerHTML = "Roll "+xDx
}
function rmoveDie () {
  diceAmt -= 1
  xDx = diceAmt+"d"+diceSides
  document.getElementById("button0").innerHTML = "Roll "+xDx
}
function addSide () {
  diceSides += 1
  xDx = diceAmt+"d"+diceSides
  document.getElementById("button0").innerHTML = "Roll "+xDx
}
function rmoveSide () {
  diceSides -= 1
  xDx = diceAmt+"d"+diceSides
  document.getElementById("button0").innerHTML = "Roll "+xDx
}

Now, I would normally show you my CSS here, but the CSS doesn't matter.
Oh, I almost forgot to show you the libraries I'm using. Here they are:
jquery.js

I would really like it if you could help me out here.

Thank you!

(Note: I would normally do that part in code but I figured it would be cooler if it was an actual h1.)
12
  • And... what is your question? Commented Jun 25, 2020 at 15:44
  • 1
    Try the HTML onclick="" attribute and pass your function Commented Jun 25, 2020 at 15:44
  • @TEK okay, I will. Commented Jun 25, 2020 at 15:47
  • 1
    How are you going to make a XSS attack with the code he has shown us? Commented Jun 25, 2020 at 15:54
  • 1
    @TEK: Not right now. But it's a general point. We don't want to teach people bad practices just because they are not that bad that one time. Commented Jun 25, 2020 at 15:59

2 Answers 2

8

Whenever a button is triggered a click event is fired. To handle that event there are 3 ways in vanilla javascript:

1. Specifying the function to be called in an HTML tag.

<button class="button2" onclick="addDie()">Add die</button>

2. Adding a handler in the button onclick property in JS.

const button = document.getElementById("your_button_id");
button.onclick = function(event) {
// do something
}
// or in your case
button.onclick = addDie

3. Adding an event listener

With this approach, you can add any number of handler for your event in the button.

button.addEventListener("click", addDie);
button.addEventListener("click", dieRoll);

These three are the possible ways to handle the events using vanilla JS.

Since you are using jquery you can simply do,

$("#button2").click(addDie)

To make sure the events are attached safely you would need to wait till the document is loaded.

1. In Jquery

$( document ).ready(function() {
...
$("#button2").click(addDie)
...
}

2. In Vanilla JS

document.addEventListener("DOMContentLoaded", function(){
...
 button.addEventListener("click", addDie);
 button.addEventListener("click", dieRoll);
...
});

Knowing the above three ways will help you understand the ways events can be handled with vanilla js.

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

3 Comments

The jQuery response is the exact issue he is facing. He needs to use $(function()... or $(document.ready()... to defer execution.
This is an answer to the stated question, but not to the actual underlying problem the OP had. It's sort of an XY problem, the OP thought that it was an incorrect way to attach a listener, but in fact it was just too early to attach a listener. (Thus they asked the wrong question.) So unfortunately even though it is a good answer, it doesn't solve their issue.
Oops, my bad I only focused on the part for How do you call a javascript function with an HTML button click? so I only pointed out how you can call a function. I will add that part as well.
2

Based on the code you showed, I think the issue is that your script is in the head part, before the body (including the buttons) is even loaded.

That means that when you do $("#button0"), you get a collection of zero elements (the buttons don't exist yet), and then you attach a click handler to zero elements, so you are doing nothing.

The solution is simple: jQuery allows you in a very simple way to defer the execution of some code until the DOM has finished loading. That is done by calling $ as a function and passing a callback, i.e. $(...) (or, more verbosely, by writing $(document).ready(...)):

  $(function () {
      $("#button0").click(function(){
        diceRoll = 0
        for (i=diceAmt;i>0;i--) {
          diceRoll += rand(1, diceSides)
        }
        document.getElementById("dieRoll").innerHTML = diceRoll;
      })
  })

That should fix the issue.

4 Comments

They are defined, but in the other JS he posted. I was running it in JSFiddle, if you include that script as well, it works with your answer.
Oops, I overlooked the second part of the code, since the HTML didn't include any other <script>s. Removed that part from my answer.
I had a separate script containing jQuery v3.5.1. Is that OK?
Yes don't worry about it, I was just confused because the HTML itself didn't load any other JavaScript, but if (at the moment) it's part of a JSFiddle that is fine.

Your Answer

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