TypeError: game_1.flip 不是一个函数

TypeError: game_1.flip is not a function

本文关键字:函数 一个 game flip TypeError      更新时间:2023-09-26

我正在尝试制作一个简单的专注游戏的OOP版本。一切看起来都不错,即游戏板和卡片出现在游戏的每个实例中,但卡片不会翻转。

我正在尝试使用Firefox Web开发人员进行调试,这是我收到的错误消息:

TypeError: game_1.flip 不是一个函数。

我一辈子都无法弄清楚翻转功能出了什么问题。我已经阅读了几个TypeError问题和回复,但似乎都不适用于我的问题。

法典

<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>"More Concentration"</title>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />  
    <style type="text/css">
        body {background-color:green;}
        p {color: white}
        img {border:1px solid black}    
        #theGame {width: 400px; height: 390px; border: 1px solid white; padding:15px; text-align: center;  margin-left: auto; margin-right: auto;}
        #wrapper {text-align: center;}
    </style>
<script type="text/javascript">
// <![CDATA[
function Card() {
this.value = ""; 
this.suit = ""; 
this.name = ""; 
this.image = ""; //add a spot to store a path to the card image.
}
function Game(gameId) {
this.gameId = gameId;   
var firstCard = 'unused'; // A place to remember the first pick...
var touchedCard = 'unused'; // ... and the last touched card
var waiting = false; // This variable will control WHEN we can flip cards.
this.Deck = new Array(52);
this.shuffle = function() {
    var r;
    var someCard = new Card();
    for (i=51;i >= 0;i--){
        r = Math.round(Math.random() * i);
        someCard = this.Deck[i]; this.Deck[i] = this.Deck[r]; this.Deck[r] = someCard;
    }
};
this.initDeck = function() {    
var Names = new Array("2","3","4","5","6","7","8","9","10","jack","queen","king","ace");
var suitNames = new Array("spades","diamonds","hearts","clubs");
    for (var i=0;i<13;i++){
        for (var j=0;j< 4;j++){     
        this.Deck[i + (j * 13)] = new Card();
        this.Deck[i + (j * 13)].suit = suitNames[j];
        this.Deck[i + (j * 13)].value = i;
        this.Deck[i + (j * 13)].name = Names[i];
        //This line builds the path to the card image based on available info.
        this.Deck[i + (j * 13)].image = 'images/' + suitNames[j] + '_' +  Names[i] + '.png';
        }
    }
};
this.flip = function(passedCard){
//This function is the core of the interactivity
    if (waiting == false){ 
    //check to see if we're "waiting" for any flips to finish
         touchedCard = passedCard;
         document.images[touchedCard].src = this.Deck[touchedCard].image;
        if (firstCard  == 'unused'){ 
                   //If this is the first cards selected...
            firstCard = touchedCard; // ... remember it for later
        }else{ //If this is the second card selected ...
            waiting = true; //... disallow further flips and ...
            if (this.Deck[touchedCard].value ==  this.Deck[firstCard].value){ // ... compare it to the first.
                //If they match, do this.//

            setTimeout(this.gameId + ".retireSelection("+ this.firstCard + '_' + this.gameId + ","+touchedCard+")",2000);
            } else { 

                setTimeout(this.gameId + ".resetSelection("+   this.firstCard + '_' + this.gameId + ","+touchedCard+")",2000);
                }
                 firstCard  = 'unused';
        }
    }
};

this.resetSelection = function(carda,cardb){
      //Turn the cards facedown after NOT matching
    document.images[carda].src = 'images/card_back.png'; 
    document.images[cardb].src = 'images/card_back.png';
    waiting = false; // re-allow more flips
};
this.retireSelection = function(carda, cardb){
    //Indicate the cards are matched using the "X' card.
    document.images[carda].src = 'images/blank.png';
    document.images[cardb].src = 'images/blank.png';
    //Deactivate the handler so they can't be flipped again after a match.
    document.images[carda].onclick = '';
    document.images[cardb].onclick = '';
    waiting = false; // re-allow more flips
 };
 this.plop_cards = function(){
     //Writes HTML to put cards on the page     
     this.shuffle();
    //document.writeln("<p>" +this.gameId + "</p>");
    document.write('<div id="theGame">');
     for(var i=0;i<52;i++){     
    document.writeln("<img src = 'images/card_back.png' id =" + this.gameId +  ' Card_' + i + " onclick='" + this.gameId + ".flip("+i+")'>");
    }
    document.write('</div>');
 }; 
 }  
     // ]]>
</script>
  </head>
  <body>      
  <div id="pageTitle">
<h1>&quot;More Concentration&quot; <br /> By Dawn Lassen</h1>
  </div>
  <div id="wrapper" class="center">
  <script type="text/javascript">
  // <![CDATA[

    var game_1 = new Game('game_1');
    var game_2 = new Game('game_2');
    var game_3 = new Game('game_3');
    var game_4 = new Game('game_4');
    var game_5 = new Game('game_5');
    game_1.initDeck();
    game_2.initDeck();
    game_3.initDeck();
    game_4.initDeck();
    game_5.initDeck();
    game_1.plop_cards();
    game_2.plop_cards();
    game_3.plop_cards();
    game_4.plop_cards();
    game_5.plop_cards();
    // ]]>
</script>
   </div>
   </body>
   </html>

任何帮助,指导,建议,不胜感激。正如你可能知道的,我是这个论坛和 JavaScript 的新手。

问题是您在编写图像时正在创建无效的 (X)HTML。请参阅以下代码行:

document.writeln("<img src = 'images/card_back.png' id =" + this.gameId + ' Card_' + i + " onclick='" + this.gameId + ".flip("+i+")'>");

id属性没有引号,因此输出将是乱码,因为它将包含类似 <img ... id=game_1 Card_1 onclick=...> 的内容。首先,这是完全错误的,因为一个游戏的所有卡片都将具有相同的id(这在HTML中也是无效的,也不是你想要的),特别是在XHTML的情况下,不带引号的属性是被禁止的。

简单的解决方法是正确引用它

document.writeln("<img src = 'images/card_back.png' id ='" + this.gameId + ' Card_' + i + "' onclick='" + this.gameId + ".flip("+i+")'>");

但是,尝试直接写入 DOM 流是一个坏主意。如果您完全避免使用像document.write这样的方法会好得多,因为通常建议不要使用它们,而使用 DOM 方法。

例如,您可以执行以下操作:

var img = document.createElement('img');
img.src = 'images/card_back.png';
img.id = this.gameId + ' Card_' + i;
img.onclick = (function(_this, i) {
    return function() {
        _this.flip(i);
    };
})(this, i);
document.body.appendChild(img);

您可以在此小提琴中看到它将允许调用flip。小提琴暂时破坏了页面的格式,这只是一个快速演示。顺便说一下,我还建议不要将id属性与空格一起使用。

出于好奇:你使用XHTML有什么具体的原因吗?您也可以使用 HTML(即 HTML5),然后还可以删除脚本周围的 CDATA 块注释。虽然XHTML更严格,这通常不是太糟糕的事情,但HTML5的传播程度要高得多,所以没有理由不使用它。