快速点击时点击功能崩溃

时间:2018-08-18 18:56:48

标签: 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);

        }

     }

1 个答案:

答案 0 :(得分:1)

通过在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>