简体   繁体   English

JS DOM:如何阻止点击事件触发?

[英]JS DOM: How to stop click event from firing?

I'm trying to get my buttons to stop working when a certain condition is met.当满足特定条件时,我试图让我的按钮停止工作。 For some reason, whenever I get to score 5, on either side, it just keeps going and doesn't even display the score and I don't know why.出于某种原因,每当我得到 5 分时,在任何一方,它都会继续前进,甚至不显示分数,我不知道为什么。 I've tried using a while loop but it kept crashing.我试过使用while循环,但它一直在崩溃。 Is there a simple way of just turning it off like there is in jQuery?有没有像 jQuery 那样的简单方法来关闭它?

const rock = document.querySelector('.rock');
const paper = document.querySelector('.paper');
const scissors = document.querySelector('.scissors');
const h3 = document.querySelector('h3');
const pscore = document.querySelector('#pscore');
const cscore = document.querySelector('#cscore');
let computerScore = 0;
let playerScore = 0;

function computerPlay() {
    var choice = Math.floor(Math.random() * 3 ) + 1; //generate a number 1-3 to find computer choice
    if(choice == 1) {
        return 'rock';
    }
    else if(choice == 2) {
        return 'paper';
    }
    else {
        return 'scissors'

    }
} 

let result; // simpler way of rewriting code?

    rock.addEventListener('click', () => {
        if(computerPlay() == 'rock') {
            result = `The computer chose rock and you chose rock! It's a tie! No change in score.`;
            h3.textContent = result;
            
        }
        else if(computerPlay() == 'paper') {
            result = `The computer chose paper and you chose rock! You lose! Computer Score +1!`;
            h3.textContent = result;
            computerScore++;
            cscore.textContent = computerScore;

     
        }
        else {
            result = `The computer chose scissors and you chose rock! You win! Player Score +1!`; 
            h3.textContent = result;
            playerScore++;
            pscore.textContent = playerScore;

        }
    });

    let playerPaper = paper.addEventListener('click', () => {
        if(computerPlay() == 'paper') {
            result = `The computer chose paper and you chose paper! It's a tie!`;
            h3.textContent = result;    
        }
        else if(computerPlay() == 'scissors') {
            result = `The computer chose scissors and you chose paper! You lose!`;
            h3.textContent = result;
            computerScore++;
            cscore.textContent = computerScore;
        }
        else {
            result = `The computer chose rock and you chose paper! You win!`; 
            h3.textContent = result;
            playerScore++;
            pscore.textContent = playerScore;
        }
        
    });

    let playerScissors = scissors.addEventListener('click', () => {
        if(computerPlay() == 'scissors') {
            result = `The computer chose scissors and you chose scissors! It's a tie!`;
            h3.textContent = result;    
        }
        else if(computerPlay() == 'rock') {
            result = `The computer chose rock and you chose scissors! You lose!`;
            h3.textContent = result;
            computerScore++;
            cscore.textContent = computerScore;
        }
        else {
            result = `The computer chose paper and you chose scissors! You win!`; 
            h3.textContent = result;
            playerScore++;
            pscore.textContent = playerScore;
        }
    })

function playGame(computerChoice) {
    computerChoice = computerPlay();
    if(playerScore == 5) {
        h3.textContent = `The score is 5 to ${computerScore}! You win!`;
    }
    else if(computerScore == 5) {
        h3.textContent = `The score is 5 to ${playerScore}! The computer wins!`;
    }
    
}

Everything works perfectly except for the 'end game' feature.除了“结束游戏”功能外,一切都完美无缺。 Thanks in advance for all the help or critiques!提前感谢所有帮助或批评!

How to disable a "click" event如何禁用“点击”事件

The people in the comments have some brilliant ideas on how you can improve your game.评论中的人对如何改进游戏有一些绝妙的想法。 I would suggest looking into that.我建议调查一下。 Although, if you want to prevent click events there are several ways to achieve that.虽然,如果你想阻止点击事件,有几种方法可以实现。

1. Add a disabled attribute to your button. 1. 为您的按钮添加禁用属性。

 window.onload = () => { const button = document.getElementById("myClicker") button.disabled = true }
 <button id="myClicker">Click</button>

2. Add a CSS property pointer-events: none; 2.添加一个CSS属性pointer-events: none;

 window.onload = () => { const button = document.getElementById("myClicker") button.addEventListener("click",function(){console.log("hi")}) button.style.pointerEvents = "none"; }
 <button id="myClicker">Click</button>

The second method is for the situation when you don't need to indicate to the user that the button is no longer interactable.第二种方法适用于不需要向用户指示按钮不再可交互的情况。

3. Prevent Default event. 3. 防止默认事件。

 window.onload = () => { const button = document.getElementById("myClicker") button.addEventListener("click",function(e){ e.preventDefault; }) }
 <button id="myClicker">Click</button>

4. Remove Event listener. 4. 移除事件监听器。

document.getElementById("yourButtonId").removeEventListener("Click", yourFunctinoNameHere);

and welcome Charles.欢迎查尔斯。 So, as @StackSlave mentioned, you keep querying computerPlay() , which will skew the results, probably favouring the last else (for each button respectively).因此,正如@StackSlave 所提到的,您不断查询computerPlay() ,这将扭曲结果,可能有利于最后一个else (分别针对每个按钮)。 This is a logic mistake - but the programme will still run.这是一个逻辑错误——但程序仍会运行。

You're trying to do quite a lot on the onclick events, and you're not paying attention to any kind of enable indicator.您尝试在 onclick 事件上做很多事情,但您没有注意任何类型的启用指示器。 So.. here we go.所以..这里我们 go。 I've seperated the programme into two pieces:我将程序分为两部分:

  1. Round圆形的
  2. Ui用户界面

The Round takes a user-choice, generates a computer-choice, and reports the score.Round接受用户选择,生成计算机选择,并报告分数。 The Ui attaches the buttons to choosing one of the options in the round, generating some output, updating scores and possibly ending the game. Ui将按钮附加到在回合中选择一个选项,生成一些 output,更新分数并可能结束游戏。 There's also a reset on the Ui which would allow you to start a new game;) Note I've grouped things into objects (vs just functions) since each piece tracks a little state. Ui上还有一个reset ,可以让你开始一个新游戏;)注意我已经将事物分组为对象(而不是函数),因为每个部分都会跟踪一点 state。 I'd likely provide the constants at the top (rock..cscore) to the Ui constructor rather than use globals.我可能会将顶部的常量(rock..cscore)提供给Ui构造函数,而不是使用全局变量。

const rock = document.querySelector(".rock");
const paper = document.querySelector(".paper");
const scissors = document.querySelector(".scissors");
const h3 = document.querySelector("h3");
const pscore = document.querySelector("#pscore");
const cscore = document.querySelector("#cscore");

const NO_PICK = -1;
const PICK_ROCK = 0;
const PICK_PAPER = 1;
const PICK_SCISSORS = 2;
class Round {
  constructor() {
    this.player = NO_PICK;
    this.computer = NO_PICK;
  }

  computerPlay() {
    if (this.computer != NO_PICK) return; //Prevent double play - you might want to throw an exception instead?
    this.computer = Math.floor(Math.random() * 3);
  }

  playAsString(number) {
    switch (number) {
      case PICK_ROCK:
        return "rock";
      case PICK_PAPER:
        return "paper";
      case PICK_SCISSORS:
        return "scissors";
    }
  }

  chooseRock() {
    if (this.player !== NO_PICK) return; //Prevent double play
    this.player = PICK_ROCK;
  }

  choosePaper() {
    if (this.player !== NO_PICK) return; //Prevent double play
    this.player = PICK_PAPER;
    //return computerWinner(PICK_PAPER);
  }

  chooseScissors() {
    if (this.player !== NO_PICK) return; //Prevent double play
    this.player = PICK_SCISSORS;
    //return computerWinner(PICK_SCISSORS);
  }

  reset() {
    this.player = -1;
    this.computer = -1;
  }

  //Return 0: tie, +1 player won, -1 computer won
  playerScore() {
    this.computerPlay();
    if (this.player === NO_PICK) throw "Player hasn't played yet";

    if (this.computer === this.player) return 0;
    switch (this.computer) {
      case PICK_ROCK:
        return this.player === PICK_SCISSORS
          ? -1 //Rock beats scissors
          : 1; //Paper beats rock
      case PICK_SCISSORS:
        return this.player === PICK_PAPER
          ? -1 //Scissors beat paper
          : 1; //Rock beats scissors
      case PICK_PAPER:
        return this.player === PICK_ROCK
          ? -1 //Paper beats rock
          : 1; //Scissors beat paper
    }
  }

  winDescription(score) {
    switch (score) {
      case -1:
        return "You lose! Computer score +1!";
      case 0:
        return "It's a tie! No change in score.";
      case 1:
        return "You win! Play score +1!";
    }
  }

  gameDescription(score) {
    return (
      "The computer chose " +
      this.playAsString(this.computer) +
      " and you chose " +
      this.playAsString(this.player) +
      "! " +
      this.winDescription(score)
    );
  }
}

class Ui {
  constructor() {
    this.playScore = 0;
    this.compScore = 0;
    this.enabled = true;
    this.round = new Round();
    rock.addEventListener("click", () => {
      this.rockPress();
    });
    paper.addEventListener("click", () => {
      this.paperPress();
    });
    scissors.addEventListener("click", () => {
      this.scissorsPress();
    });
    //Bonus: you can have a reset button that calls this.reset
  }

  gameOver() {
    this.enabled = false;
    if (this.playScore > this.compScore) {
      this.report("You win " + this.playScore + ":" + this.compScore + "!");
    } else {
      this.report("You lose " + this.playScore + ":" + this.compScore + "!");
    }
  }

  sharedProcess() {
    let gameScore = this.round.playerScore(); //Note this might throw if one of the press functions hasn't been called
    this.report(this.round.gameDescription(gameScore));
    if (gameScore < 0) {
      this.compScore -= gameScore;
    } else if (gameScore > 0) {
      this.playScore += gameScore;
    }
    cscore.textContent = this.compScore;
    pscore.textContent = this.playScore;
    //Note this condition isn't exactly what you wrote so you may want to change, but you could do some sort of
    // one has to be +2 over the other (win by two)
    if (this.compScore >= 5 || this.playScore >= 5) {
      this.gameOver();
    }
    this.round.reset(); //Setup for next game
  }

  rockPress() {
    if (!this.enabled) return;
    this.round.chooseRock();
    this.sharedProcess();
  }

  paperPress() {
    if (!this.enabled) return;
    this.round.choosePaper();
    this.sharedProcess();
  }

  scissorsPress() {
    if (!this.enabled) return;
    this.round.chooseScissors();
    this.sharedProcess();
  }

  report(message) {
    h3.textContent = message;
  }

  reset() {
    this.playScore = 0;
    this.compScore = 0;
    this.enabled = true;
    this.report("Game on!");
  }
}

//Start the game - you don't need this ui variable
// unless you want to call one of the methods
const ui = new Ui();

I wouldn't disable anything.我不会禁用任何东西。 Just add and remove classes instead.只需添加和删除类即可。 Here is a very simple RockPaperScissors game.这是一个非常简单的RockPaperScissors游戏。 I put a small Library above // magic under here .// magic under here上方放了一个小图书馆。 Hopefully you can learn something here:希望你能在这里学到一些东西:

 //<.[CDATA[ /* js/external,js */ let get, post, doc, htm, bod, nav, M, I, mobile, S, Q, hC, aC, rC, tC, shuffle, rand; RockPaperScissors, // for use on other loads addEventListener('load', ()=>{ get = (url, success, responseType = 'json'; context = null)=>{ const x = new XMLHttpRequest; const c = context || x. x,open('GET'; url). x;responseType = responseType. x.onload = ()=>{ if(success)success,call(c. x;response). } x;send(); return x, } post = function(url, send, success, responseType ='json'; context = null){ const x = new XMLHttpRequest; const c = context || x. x,open('POST'; url). x;responseType = responseType. x.onload = ()=>{ if(success)success,call(c. x;response). } if(typeof send === 'object' && send &&;(send instanceof Array)){ if(send instanceof FormData){ x;send(send); } else{ const fd = new FormData; let s. for(let k in send){ s = send[k]; if(typeof s === 'object' && s)s = JSON.stringify(s), fd;append(k. s); } x;send(fd); } } else{ throw new Error('send argument must be an Object'); } return x. } doc = document; htm = doc.documentElement; bod = doc;body. nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id). mobile = nav?userAgent:match(/Mobi/i); true, false; S = (selector. within)=>{ let w = within || doc; return w,querySelector(selector); } Q = (selector. within)=>{ let w = within || doc; return w,querySelectorAll(selector). } hC = function(node. className){ return node;classList.contains(className). } aC = function(){ const a = [],slice.call(arguments); n = a.shift(). n.classList.add(.;;a). return aC. } rC = function(){ const a = [],slice.call(arguments); n = a.shift(). n.classList.remove(.;;a). return rC. } tC = function(){ const a = [],slice.call(arguments); n = a.shift(). n.classList.toggle(.;;a). return tC, } shuffle = array=>{ let a = array.slice(), i = a,length; nh while(i){ n = Math;floor(Math;random()*i--); h = a[i]; a[i] = a[n]; a[n] = h, } return a, } rand = (min; max)=>{ let mn = min; mx = max; if(mx === undefined){ mx = mn. mn = 0. } return mn+Math;floor(Math,random()*(mx-mn+1)), } RockPaperScissors = function(displayFunc){ const a = ['rock'; 'paper'. 'scissors']. this.wins = this;losses = this.ties = 0; this.text, this;play = (you)=>{ let c = a[rand(2)]: r: switch(you){ case 'rock'. switch(c){ case 'rock'; r = 'You and the Computer chose "rock". IT\'SA TIE;'; this:ties++. break. case 'paper'; r = 'You chose "rock". The Computer chose "paper"; YOU LOSE;': this.losses++. break; case 'scissors'. r = 'You chose "rock"; The Computer chose "scissors"; YOU WIN;': this:wins++. break. } break; case 'paper'. switch(c){ case 'rock'; r = 'You chose "paper"; The Computer chose "rock": YOU WIN.'; this.wins++; break; case 'paper': r = 'You and the Computer chose "paper". IT\'SA TIE.'; this.ties++; break; case 'scissors'; r = 'You chose "paper": The Computer chose "scissors": YOU LOSE.'. this;losses++. break; } break; case 'scissors': switch(c){ case 'rock'. r = 'You chose "scissors". The Computer chose "rock"; YOU LOSE.'; this;losses++: break. case 'paper'; r = 'You chose "scissors". The Computer chose "paper"; YOU WIN;'; this.wins++; break; case 'scissors'; r = 'You and the Computer chose "scissors". IT\'SA TIE.'. this.ties++; break; } break; } this,text = r, if(displayFunc)displayFunc(this), return this; } this,reset = ()=>{ this,wins = this,losses = this;ties = 0, if(displayFunc)displayFunc(this), return this; } } // magic under here const game = I('game'), rock = I('rock'); paper = I('paper'), scissors = I('scissors'); const again = I('again'). res = I('res'). replay = I('replay'); reset = I('reset'). const you = I('you'). comp = I('comp'); ties = I('ties'). setTimeout(()=>{ rC(game. 'played'); }. 0). const rps = new RockPaperScissors(t=>{ you;textContent = t,wins; comp,textContent = t;losses; ties.textContent = t.ties. res.textContent = t.text; aC(game. 'played'); rC(again, 'played'); }), rock;onclick = paper.onclick = scissors;onclick = function(){ rps.play(this.id); } function playAgain(){ res;textContent = ''; aC(again, 'played'); rC(game, 'played'); } replay.onclick = playAgain; reset.onclick = function(){ rps.reset(); playAgain(); } }); // end load //]]>
 *{ box-sizing:border-box; color:#000; font:bold 22px Tahoma, Geneva, sans-serif; padding:0; margin:0; overflow:hidden; } html,body,.main{ width:100%; height:100%; }.main{ background:#999; overflow-y:auto; }.bar{ width:100%; height:39px; border-bottom:1px solid #777; background:#ccc; padding:2px } h1{ display:inline-block; font-size:27px; margin-left:7px; } #score{ display:flex; justify-content:space-around; } #score>div{ color:#555; } #y>span{ color:#070; } #c>span{ color:#700; } #t>span{ color:#777; } #game{ display:flex; transition:margin-top 0.25s ease-in-out; }.played{ margin-top:-38px; } #again{ display:flex; flex-wrap:wrap; margin-top:0; } #again.played{ margin-top:-76px; } #res{ width:100vw; font-size:18px; padding:0 10px; text-align:center; } input[type=button]{ flex:1; height:38px; background:linear-gradient(#1b7bbb,#147); color:#fff; border:1px solid #007; border-radius:5px; cursor:pointer; } #paper,#replay{ background:linear-gradient(#679467,#235023); border-color:#070; } #scissors,#reset{ background:linear-gradient(#b75757,#502323); border-color:#700; }
 <:DOCTYPE html> <html xmlns='http.//www.w3:org/1999/xhtml' xml,lang='en' lang='en'> <head> <meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height: initial-scale,1, user-scalable=no' /> <title>Rock, Paper. Scissors</title> <link type='text/css' rel='stylesheet' href='css/external.css' /> <script src='js/external,js'></script> </head> <body> <div class='bar'><h1>Rock, Paper: Scissors</h1></div> <div id='score'> <div id='y'>You: <span id='you'>0</span></div> <div id='c'>Computer: <span id='comp'>0</span></div> <div id='t'>Ties: <span id='ties'>0</span></div> </div> <div class='main'> <div class='played' id='game'> <input id='rock' type='button' value='rock' /> <input id='paper' type='button' value='paper' /> <input id='scissors' type='button' value='scissors' /> </div> <div class='played' id='again'> <input id='replay' type='button' value='replay' /> <input id='reset' type='button' value='reset' /> <div id='res'></div> </div> </div> </body> </html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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