0

I am using bootstrap to style my button in HTML file by:

<button type="button" class="btn btn-primary">Start</button>

And I want to access the class in js file by

var buttonStart = document.getElementsByClassName('btn btn-primary');

And I got the error in the console. Is there any problem with my code?

VM131:1 Uncaught ReferenceError: buttonStart is not defined at <anonymous>:1:1
        <p><span id="seconds">00</span>:<span id="tens">00</span></p>
        <button type="button" class="btn btn-primary">Start</button>
        <button type="button" class="btn btn-secondary">Stop</button>
        <button type="button" class="btn btn-secondary">Reset</button>
window.onload = function(){
    var seconds = 00;
    var tens = 00;
    var appendTens = document.getElementById("tens");
    var appendSeconds = document.getElementById("seconds");
    var buttonStart = document.getElementsByClassName('btn btn-primary');
    var buttonStop = document.getElementsByClassName("btn btn-secondary");
    var buttonReset = document.getElementsByClassName("btn btn-secondary");
    var interval;

    buttonStart.onclick = function(){

        clearInterval(interval);
        interval = setInterval(startTimer, 10);
    }
    buttonStop.onclick = function() {
        clearInterval(interval);
    }


   buttonReset.onclick = function() {
      clearInterval(interval);
     tens = "00";
       seconds = "00";
     appendTens.innerHTML = tens;
       appendSeconds.innerHTML = seconds;
   }

   function startTimer () {
    tens++; 

    if(tens < 9){
      appendTens.innerHTML = "0" + tens;
    }

    if (tens > 9){
      appendTens.innerHTML = tens;

    } 

    if (tens > 99) {
      console.log("seconds");
      seconds++;
      appendSeconds.innerHTML = "0" + seconds;
      tens = 0;
      appendTens.innerHTML = "0" + 0;
    }

    if (seconds > 9){
      appendSeconds.innerHTML = seconds;
    }

  }
}
Hoai Dang
  • 1
  • 3
  • At first, I used different id for different buttons (start, stop, reset) and .getElementById() and the program works perfectly – Hoai Dang Apr 06 '20 at 18:20
  • Are you using `buttonStart` anywhere else in the code too, which you haven't shown? – Anurag Srivastava Apr 06 '20 at 18:25
  • @AnuragSrivastava That's all the code I have – Hoai Dang Apr 06 '20 at 18:27
  • @AnuragSrivastava it works when I use different id for different buttons(start, stop, reset). However, when I tried to use bootstrap by changing from id to class, it is not working – Hoai Dang Apr 06 '20 at 18:28
  • Most likely you're loading the script in the `` before the content located in the `` loads. See [this answer](https://stackoverflow.com/questions/436411/where-should-i-put-script-tags-in-html-markup) for details. – Juan Marco Apr 06 '20 at 18:38
  • @JuanMarco I put the script before the closing body tag – Hoai Dang Apr 06 '20 at 18:42
  • `getElementsByClassName()` returns an HTMLCollection, you can't attach events directly to it. You will need to loop through and attach them individually. – EternalHour Apr 06 '20 at 18:47
  • 1
    Does this answer your question? [What do querySelectorAll and getElementsBy\* methods return?](https://stackoverflow.com/questions/10693845/what-do-queryselectorall-and-getelementsby-methods-return) – Heretic Monkey Apr 06 '20 at 18:48
  • `var buttonStart = document.getElementsByClassName('btn btn-primary')[0]` @HereticMonkey Thank you! .getElementsByClassName() will return an array – Hoai Dang Apr 06 '20 at 18:51
  • But can anyone explain why OP gets `Uncaught ReferenceError: buttonStart is not defined at ...` instead of say `buttonStart.onclick is not a function`? Why is it not defined? – Anurag Srivastava Apr 06 '20 at 18:53
  • @AnuragSrivastava it should not event throw an error. – epascarello Apr 06 '20 at 18:54
  • @epascarello So agreed that the behavior is not correct? – Anurag Srivastava Apr 06 '20 at 19:01

2 Answers2

1

The main issue is that you're capturing the <button> elements using getElementsByClassName. This method returns a HTML Collection which behaves like an array (technically an array like object). So, to fix this you would need to reference the first element of that collection:

var buttonStart = document.getElementsByClassName('btn btn-primary')[0]

Working example below:

window.onload = function() {
  var seconds = 00;
  var tens = 00;
  var appendTens = document.getElementById("tens");
  var appendSeconds = document.getElementById("seconds");
  var buttonStart = document.getElementsByClassName('btn btn-primary')[0];
  var buttonStop = document.getElementsByClassName("btn btn-secondary")[0];
  var buttonReset = document.getElementsByClassName("btn btn-tertiary")[0];
  var interval;

  buttonStart.onclick = function() {

    clearInterval(interval);
    interval = setInterval(startTimer, 10);
  }
  buttonStop.onclick = function() {
    clearInterval(interval);
  }


  buttonReset.onclick = function() {
    clearInterval(interval);
    tens = "00";
    seconds = "00";
    appendTens.innerHTML = tens;
    appendSeconds.innerHTML = seconds;
  }

  function startTimer() {
    tens++;

    if (tens < 9) {
      appendTens.innerHTML = "0" + tens;
    }

    if (tens > 9) {
      appendTens.innerHTML = tens;

    }

    if (tens > 99) {
      console.log("seconds");
      seconds++;
      appendSeconds.innerHTML = "0" + seconds;
      tens = 0;
      appendTens.innerHTML = "0" + 0;
    }

    if (seconds > 9) {
      appendSeconds.innerHTML = seconds;
    }

  }
}
<p><span id="seconds">00</span>:<span id="tens">00</span></p>
<button type="button" class="btn btn-primary">Start</button>
<button type="button" class="btn btn-secondary">Stop</button>
<button type="button" class="btn btn-tertiary">Reset</button>

It's probably a better idea to use an ID along with getElementById or if you want to keep using those classes you can use querySelector which will return the first element that matches that specific class.

Note: I modified the third class to be btn-tertiary so the example could work.

Juan Marco
  • 1,806
  • 2
  • 18
  • 22
0

you need to add 3 even listeners and define your functions correctly, the code is fine.

     
window.onload = function(){
    var seconds = 00;
    var tens = 00;
    var appendTens = document.getElementById("tens");
    var appendSeconds = document.getElementById("seconds");
    var buttonStart = document.getElementsByClassName('btn btn-primary')[0];
    var buttonStop = document.getElementsByClassName("btn btn-secondary")[0];
    var buttonReset = document.getElementsByClassName("btn btn-secondary")[1];
    var interval;

    buttonStart.addEventListener("click", start);

    function start() {        
        clearInterval(interval);
        interval = setInterval(startTimer, 10);
    }
    buttonStop.addEventListener("click", stop);
  function stop() {
        clearInterval(interval);
    }


   buttonReset.addEventListener("click", restart);
  function restart() {
      clearInterval(interval);
     tens = "00";
       seconds = "00";
     appendTens.innerHTML = tens;
       appendSeconds.innerHTML = seconds;
   }

   function startTimer () {
    tens++; 

    if(tens < 9){
      appendTens.innerHTML = "0" + tens;
    }

    if (tens > 9){
      appendTens.innerHTML = tens;

    } 

    if (tens > 99) {
      console.log("seconds");
      seconds++;
      appendSeconds.innerHTML = "0" + seconds;
      tens = 0;
      appendTens.innerHTML = "0" + 0;
    }

    if (seconds > 9){
      appendSeconds.innerHTML = seconds;
    }

  }
}
     <p><span id="seconds">00</span>:<span id="tens">00</span></p>
        <button type="button" class="btn btn-primary">Start</button>
        <button type="button" class="btn btn-secondary">Stop</button>
        <button type="button" class="btn btn-secondary">Reset</button>
DCR
  • 10,658
  • 7
  • 38
  • 86