简体   繁体   中英

function only runs on first click?

I'm working on a leaderboard for a ctf game website I developed for University. I started playing around a bit with some simple animations and found some bugs that I can't figure out: 1. You have to click twice on login button or add button for it to actually work the first time. 2. When a wrong answer is submitted, the animation only works once and then for any subsequent wrong answers nothing happens.

This is the link for the page: https://nerdts-4ed61.firebaseapp.com/leaderboards.html

<footer>
    <h6 class="right-ans">
      Correct! Your progress will be added to your account.
    </h6>
  </br>
    <div id="addFlagInput" class="input-group">
      <div class="input-group-prepend">
        <span
          class="input-group-text"
          style="background: transparent; color: white; border-top: none; border-left: none; border-bottom: none; border-width: 2px; border-color: rgba(0,0,0,0.09);"
          id=""
          >Name and flag</span
        >
      </div>
      <input
        id="inputbox1"
        type="text"
        class="form-control transparent-input"
      />
      <input
        id="inputbox2"
        type="text"
        class="form-control transparent-input"
      />
      <div class="input-group-append">
        <button
          id="submitBtn"
          onclick="submit()"
          class="btn btn-light"
          style="background: transparent; color: white; border-color: rgba(0,0,0,0.09);"
          type="button"
        >
          Submit
        </button>
      </div>
    </div>
  </footer>
</div>    
 <!--ANIMATION LOGIN BTN-->
<script>
  function addFlag() {
    const element = document.querySelector("#addFlagBtn");
    element.classList.add("animated", "fadeInDown");
    const display = element.style.display;
    if (display == "none") {
      element.style.display = "block";
    } else {
      element.style.display = "none";
    }
  }
</script>
<!--check user state for flag add-->
<script>
  function isUser() {
    firebase.auth().onAuthStateChanged(function(user) {
      if (user) {
        //show input form
        const inElement = document.querySelector("#addFlagInput");
        inElement.classList.add("animated", "fadeInUp");
        const visibility = inElement.style.visibility;
        if (visibility == "hidden") {
          inElement.style.visibility = "visible";
        } else {
          inElement.style.visibility = "hidden";
        }
      } else {
        //tooltip: you must register to add a flag
        const element = document.querySelector("#addFlagBtn");
        element.setAttribute("title", "You must register to add a flag.");
      }
    });
  }
</script>
<!--Submit button functionality-->
<script>
  function hideText() {
    document.querySelector(".right-ans").style.display = "none";
  }
  function submit() {
    const submitElement = document.querySelector("#inputbox2");
    const answer = submitElement.value;
    console.log("Your answer is: ", answer);
    var database = firebase.database();
    var dbRef = database.ref("flags/");
    dbRef.orderByKey().on("value", snapshot => {
      if (snapshot.exists()) {
        snapshot.forEach(function(data) {
          var val = data.val();
          if (val.id == answer) {
            document
              .querySelector(".right-ans")
              .classList.add("animated", "heartBeat");
            document.querySelector(".right-ans").style.display = "inline";
            console.log("correct!");
            setTimeout(hideText, 5000);
          }
          else {
            const inputdiv = document.querySelector("#addFlagInput");
            inputdiv.classList.remove("fadeInUp");
            inputdiv.classList.add("animated","swing");
          }
        });
      }
    });
  }
</script>

What does

dbRef.orderByKey().on("value", snapshot => {
  if (snapshot.exists()) {
    snapshot.forEach(function(data) {

do? It looks like you have the code that actually adds or removes the class inside a firebase event listener. Every time you run a function, the variables or functions inside are created again, and whenever you get to the end of that function, or outside of the scope, if the variable was created inside that scope and not assigned to any other variable outside, it is destroyed.

So every time your submit function runs that firebase-looking event gets created again.

The event only runs the second time you click the button because the event doesn't exist yet, the first time you click the button, because it only exists after the first submit() occurs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM