javascript - 快速点击时点击功能崩溃

标签 javascript click event-listener

我做了一个卡片内存游戏,一切似乎都很好,只是当你点击卡片太快时,即使不匹配,它们也会打开。我正在尝试的是让用户一次只点击两张卡片或阻止用户点击太快导致甲板崩溃,而且因为我几乎没有 IF 和 Elses(尝试了一个计数器但)放置造成问题,任何建议将不胜感激。 谢谢 完整代码位于 https://codepen.io/ma-halepoto/pen/LJPpKz

function shuffle(array) {
        let currentIndex = array.length, temporaryValue, randomIndex;

        while (currentIndex !== 0) {
            randomIndex = Math.floor(Math.random() * currentIndex);
            currentIndex -= 1;
            temporaryValue = array[currentIndex];
            array[currentIndex] = array[randomIndex];
            array[randomIndex] = temporaryValue;
        }

        return array;
    }


    window.onload = function () {
        let openedCards  =  [];
            matchedCards =  [];
            currentCard  =  [];
            previouseCard= 0 ;
            moveCount = 0 ;
            restart = document.getElementsByClassName ('restart');
            modal = document.getElementById('myModal');
            span = document.getElementsByClassName('close')[0];

            // console.log (restart); just to see if restart works
            restart[0].addEventListener ('click', function (){
                location.reload();

            })
        // console.log("It's loaded!") to check if this works
        const cards = ['fa-diamond','fa-diamond', 'fa-paper-plane-o','fa-paper-plane-o', 'fa-anchor', 'fa-anchor', 'fa-bolt', 'fa-bolt', 'fa-cube', 'fa-cube', 'fa-leaf', 'fa-leaf', 'fa-bicycle', 'fa-bicycle',
         'fa-bomb','fa-bomb' ]; 
        let shuffleCards = shuffle (cards);
        // console.log (shuffleCards); to check if this works
        let cardElements = document.getElementsByClassName('symbols');
        // console.log (cardElements); to check if this works
        for (i=0; i < cardElements.length; i++ ) {
            cardElements[i].className = shuffleCards[i]+ ' fa symbols';

        }

        // initialising popup 

        function popup() {
                        modal.style.display = "flex";
                        document.getElementById('p1').innerHTML = 'You did it in '+ moveCount+ ' moves'  + ' and ' + seconds+ ' seconds.';
        }

        // Closing popup by clicking x
        span.onclick = function closeX () {
                            modal.style.display = "none";
                        }

        // function close popup by clicking any where
        window.onclick = function(event) {
                            if (event.target == modal) {
                                modal.style.display = "none";
                            }
                        }

        // Stopwatch initialisation
        let stopWatch = document.getElementById ('timer');
            time = 0;
            seconds=0

        // start time
        function startTime () {
            time = setInterval ( function (){
                seconds++;
                stopWatch.innerHTML = seconds + ' s';
            }, 1000); 
        }

        // stop the time function
        function stopTime ()    {
            clearInterval (time);
        }

        let displayCards = document.getElementsByClassName ('card');       
            console.log (displayCards);

        // Click Event
        function cardClick () {
            currentCard = this;
            currentCard.removeEventListener ('click', cardClick); 
            console.log (currentCard);



            // updating move counts
            let countMoves = document.getElementById ('moves');

            moveCount++ ;
            countMoves.innerHTML= moveCount;
            console.log(countMoves);

            // star ranking;
            if ( moveCount === 20) {
                let removeStar = document.getElementById('star3');
                removeStar.style.display = 'none';
            } else if (moveCount ===30) {
                let removeStarTwo = document.getElementById ('star2');
                removeStarTwo.style.display = 'none';
                }   

            // start  stopwatch at the first click.
            if ( moveCount ===1) {
                startTime ();
            }

                currentCard.classList.add('open', 'show');


                if (previouseCard) {

                    // matching cards
                    if (currentCard.innerHTML === previouseCard.innerHTML) {
                        currentCard.classList.add('match');
                        previouseCard.classList.add('match');
                        matchedCards.push(currentCard,previouseCard);

                        // console.log ('match'); this line here for just test purpose
                        previouseCard = null ;

                        // check if won
                        if (cards.length === matchedCards.length) {

                            // stopping stopwatch 
                            stopTime();

                            // calling popup function 
                            popup ();

                        }
                    } else {
                        // when cards are not matched
                        setTimeout (function(){

                            currentCard.classList.remove ('open', 'show');  
                            previouseCard.classList.remove ('open', 'show');
                            currentCard.addEventListener ('click', cardClick);
                            previouseCard.addEventListener ('click', cardClick);
                            previouseCard = null ;

                        }, 500);

                    }


                } else {
                        previouseCard = currentCard ;   
                        openedCards.push(this); 
                    }                   
        } 

            // event listener function 
        for (i=0; i < displayCards.length; i++) {
            displayCards[i].addEventListener('click', cardClick);

        }

     }

最佳答案

通过在 cardClick() 上设置 clickFlag 可以防止用户点击太快。

  1. 声明 clickFlag=true; 为全局。

  2. cardClick() 函数开始时添加返回条件。

    if(!clickFlag){
     alert("Please wait");
     return;
    }
    
  3. if (previouseCard) {....) 的开头将此标志设置为 false 以防止用户点击。因为这里的用户已经点击了 2卡片。

  4. 处理后将此标志设置为true

My CodePen

代码片段在这里:

function shuffle(array) {
	    let currentIndex = array.length, temporaryValue, randomIndex;

	    while (currentIndex !== 0) {
	        randomIndex = Math.floor(Math.random() * currentIndex);
	        currentIndex -= 1;
	        temporaryValue = array[currentIndex];
	        array[currentIndex] = array[randomIndex];
	        array[randomIndex] = temporaryValue;
	    }

	    return array;
	}


	window.onload = function () {
		let openedCards	 = 	[];
			matchedCards = 	[];
			currentCard  = 	[];
			previouseCard= 0 ;
			moveCount = 0 ;
			restart = document.getElementsByClassName ('restart');
			modal = document.getElementById('myModal');
			span = document.getElementsByClassName('close')[0];

			// console.log (restart); just to see if restart works
			restart[0].addEventListener ('click', function (){
				location.reload();

			})
		// console.log("It's loaded!") to check if this works
		const cards = ['fa-diamond','fa-diamond', 'fa-paper-plane-o','fa-paper-plane-o', 'fa-anchor', 'fa-anchor', 'fa-bolt', 'fa-bolt', 'fa-cube', 'fa-cube', 'fa-leaf', 'fa-leaf', 'fa-bicycle', 'fa-bicycle',
		 'fa-bomb','fa-bomb' ]; 
		let shuffleCards = shuffle (cards);
		// console.log (shuffleCards); to check if this works
		let cardElements = document.getElementsByClassName('symbols');
		// console.log (cardElements); to check if this works
		for (i=0; i < cardElements.length; i++ ) {
			cardElements[i].className = shuffleCards[i]+ ' fa symbols';
		
		}

		// initialising popup 

		function popup() {
	    				modal.style.display = "flex";
	    				document.getElementById('p1').innerHTML = 'You did it in '+ moveCount+ ' moves'  + ' and ' + seconds+ ' seconds.';
		}

		// Closing popup by clicking x
		span.onclick = function closeX () {
	    					modal.style.display = "none";
						}

		// function close popup by clicking any where
		window.onclick = function(event) {
	    					if (event.target == modal) {
	        					modal.style.display = "none";
	    					}
						}

		// Stopwatch initialisation
		let stopWatch = document.getElementById ('timer');
			time = 0;
			seconds=0
		
		// start time
		function startTime () {
			time = setInterval ( function (){
				seconds++;
				stopWatch.innerHTML = seconds + ' s';
			}, 1000); 
		}

		// stop the time function
		function stopTime ()	{
			clearInterval (time);
		}
		
		let displayCards = document.getElementsByClassName ('card');       
			//console.log (displayCards);
var clickFlag=true;
		// Click Event
		function cardClick () {
      if(!clickFlag){
        alert("Please wait");
        return;
        }
	 		currentCard = this;
	 		currentCard.removeEventListener ('click', cardClick); 
	 		//console.log (currentCard);

	 		

	 		// updating move counts
	 		let countMoves = document.getElementById ('moves');

	 		moveCount++ ;
	 		countMoves.innerHTML= moveCount;
	 		//console.log(countMoves);

	 		// star ranking;
	 		if ( moveCount === 20) {
	 			let removeStar = document.getElementById('star3');
				removeStar.style.display = 'none';
	 		} else if (moveCount ===30) {
	 			let removeStarTwo = document.getElementById ('star2');
	 			removeStarTwo.style.display = 'none';
	 			}	

	 		// start  stopwatch at the first click.
	 		if ( moveCount ===1) {
	 			startTime ();
	 		}
	 			
	 			currentCard.classList.add('open', 'show');


	 			if (previouseCard) {
          clickFlag=false;
	 				// matching cards
	 				if (currentCard.innerHTML === previouseCard.innerHTML) {
	 					currentCard.classList.add('match');
	 					previouseCard.classList.add('match');
	 					matchedCards.push(currentCard,previouseCard);
	 		
	 					// console.log ('match'); this line here for just test purpose
	 					previouseCard = null ;
	 					
	 					// check if won
	 					if (cards.length === matchedCards.length) {
	 					
	 						// stopping stopwatch 
	 						stopTime();

	 						// calling popup function 
	 						popup ();
						
	 					}
           clickFlag=true;
	 				} else {
	 					// when cards are not matched
	 					setTimeout (function(){

	 						currentCard.classList.remove ('open', 'show');	
	 						previouseCard.classList.remove ('open', 'show');
	 						currentCard.addEventListener ('click', cardClick);
	 						previouseCard.addEventListener ('click', cardClick);
	 						previouseCard = null ;
	 						clickFlag=true;
	 					}, 500);
	 				
	 				}
	 			 	

	 			} else {
	 					previouseCard = currentCard ;	
	 					openedCards.push(this);	
          clickFlag=true;
	 				}		
	 	} 
	 		
	 		// event listener function 
	 	for (i=0; i < displayCards.length; i++) {
			displayCards[i].addEventListener('click', cardClick);

		}
		
	 }
html {
        box-sizing: border-box;
    }

    *,
    *::before,
    *::after {
        box-sizing: inherit;
    }

    html,
    body {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
    }

    body {
        background: #ffffff url('../img/geometry2.png');
        font-family: 'Coda', cursive;
    }

    .container {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;
    }

    h1 {
        font-family: 'Open Sans', sans-serif;
        font-weight: 300;
    }

    /*
     * Styles for the deck of cards
     */

    .deck {
        width: 660px;
        min-height: 680px;
        background: linear-gradient(160deg, #02ccba 0%, #aa7ecd 100%);
        padding: 32px;
        border-radius: 10px;
        box-shadow: 12px 15px 20px 0 rgba(46, 61, 73, 0.5);
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        align-items: center;
        margin: 0 0 3em;
    }

    .deck .card {
        height: 125px;
        width: 125px;
        background: #2e3d49;
        font-size: 0;
        color: #ffffff;
        border-radius: 8px;
        cursor: pointer;
        display: flex;
        justify-content: center;
        align-items: center;
        box-shadow: 5px 2px 20px 0 rgba(46, 61, 73, 0.5);
    }

    .deck .card.open {
        transform: rotateY(0);
        background: #02b3e4;
        cursor: default;
    }

    .deck .card.show {
        font-size: 33px;
    }

    .deck .card.match {
        cursor: default;
        background: #02ccba;
        font-size: 33px;
    }

    /*
     * Styles for the Score Panel
     */

    .score-panel {
        text-align: left;
        width: 345px;
        margin-bottom: 10px;
    }

    .score-panel .stars {
        margin: 0;
        padding: 0;
        display: inline-block;
        margin: 0 5px 0 0;
    }

    .score-panel .stars li {
        list-style: none;
        display: inline-block;
    }

    .score-panel .restart {
        float: right;
        cursor: pointer;
    }


    /*creating a popup*/


    /* The Modal (background) */
    .modal {
    display: none; 
    position: fixed; 
    z-index: 1; 
    padding-top: 100px; 
    left: 0;
    top: 0;
    width: 100%; 
    height: 100%; 
    overflow: auto; 
    background-color: rgb(0,0,0);
    background-color: rgba(0,0,0,0.4);
    }

    /* Modal Content */
    .modal-content {
    background-color: #fefefe;
    margin: auto;
    padding: 20px;
    border: 1px solid #888;
    width: 80%;
    }

    /* The Close Button */
    .close {
    color: #aaaaaa;
    float: right;
    font-size: 28px;
    font-weight: bold;
    }

    #middle {
    text-align: center;
    }

    h2 {
    color: blue;
    }


    .close:hover,
    .close:focus {
    color: #000;
    text-decoration: none;
    cursor: pointer;
    }
<link rel="stylesheet prefetch" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
        <link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Coda">
        <link rel="stylesheet" href="css/app.css">

    
    <body>
    <div class="container">
        <header>
            <h1>Matching Game</h1>
        </header>

        <section class="score-panel">
        	<ul class="stars">
        		<li id= 'star1'><i class="fa fa-star"></i></li>
        		<li id= 'star2' ><i class="fa fa-star"></i></li>
        		<li id= 'star3'><i class="fa fa-star"></i></li>
        	</ul>

        	<span id="moves">0</span> Moves
            <span id="timer">0</span> Timer

            <div class="restart">
        		<i class="fa fa-repeat"></i>
        	</div>
        </section>

        <ul class="deck">
            <li class="card">
                <i class="fa fa-diamond symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-paper-plane-o symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-anchor symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-bolt symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-cube symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-anchor symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-leaf symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-bicycle symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-diamond symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-bomb symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-leaf symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-bomb symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-bolt symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-bicycle symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-paper-plane-o symbols"></i>
            </li>
            <li class="card">
                <i class="fa fa-cube symbols"></i>
            </li>
        </ul>
    </div>
        <div>
        <div id="myModal" class="modal">
            <div class="modal-content">
                <span class="close">&times;</span>
                <div id="middle">
                    <h2>Congratulations!</h2> 
                    <p id="p1"></p>
                    <button id='playBt' onClick ='window.location.reload()'>Play Again</button>
                </div>
            </div>
        </div>
        </div>    
     
    </body>

关于javascript - 快速点击时点击功能崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51911689/

相关文章:

javascript - 检查 Javascript 中的按钮是否被单击

Java - num1 = event.getActionCommand() 不起作用(无法将字符串设置为 Int)

javascript - 在 InDesign CC 2017 javascript 中,使用 eventListener "afterOpen"时,如何避免警告 "No documents are open."?

javascript - TypeScript:TypeError:App 不是构造函数

javascript - React JS 条件更新状态

javascript - 如何在 PHP 中将 json 转换为人类可读的格式

javascript - 循环上的 addEventListener 无法与 IIFE 一起使用

javascript - javascript新手不了解数组

c - 如何使用 Xlib 作为 xeyes 通过透明窗口发送点击信号?

Android - 如何仅通过单击应用程序图标来执行项目的主要功能?