-1

在这里完成关于 Javascript 主题的新手。我正在尝试编写井字游戏,同时使用 JS 的对象来节省代码空间。我想我可能会创建一个 JS 对象,它将 HTML 代码中定义的所有 9 个字段以 ids 'one' 到 'nine' 作为值,然后还有一个自定义方法可用于交换 value 的 textContent,如下所示:

var fields = {
    one: document.querySelector('#one'),
    two: document.querySelector('#two'),
    three: document.querySelector('#three'),
    four: document.querySelector('#four'),
    five: document.querySelector('#five'),
    six: document.querySelector('#six'),
    seven: document.querySelector('#seven'),
    eight: document.querySelector('#eight'),
    nine: document.querySelector('#nine'),
    swap: function(element) {
        if (this.element.textContent === "") {
            this.element.textContent = "X";
        } else if (this.element.textContent === "X") {
            this.element.textContent = "O";
        } else {
            this.element.textContent = "";
        }
    }
}

然后,我想我会像这样添加一堆 addEventListeners:

fields['one'].addEventListener('click', fields.swap(fields['one']));

问题是,我可能完全把这个概念当作它在 Python 中运行的方式来对待,而且我可能在这里弄乱了语法。谁能给我一些关于我在哪里出错的想法?

上面复制的代码目前不起作用。

它使用的 HTML 如下(我在这里省略了格式以节省空间):

<body>
  <div class="container">
    <table id="gameboard">
      <tr class="row">
      <td id="one" class="gameField">X</td>
      <td id="two" class="gameField">X</td>
      <td id="three" class="gameField">X</td>
    </tr>
    <tr class="row">
      <td id="four" class="gameField">X</td>
      <td id="five" class="gameField">X</td>
      <td id="six" class="gameField">X</td>
    </tr>
    <tr class="row">
      <td id="seven" class="gameField">X</td>
      <td id="eight" class="gameField">X</td>
      <td id="nine" class="gameField">X</td>
    </tr>
  </table>
</div>

4

3 回答 3

1

将你的交换功能从你的对象中分离出来,然后一起摆脱这个对象。将一个添加到您希望添加 EventListener 的所有 HTMLElement,然后使用以下命令查询它们:

<div id="one" class="your-class"></div>
<div id="two" class="your-class"></div>

function swap(element) {
   if (element.textContent === ""){
      element.textContent = "X";
    }else if (element.textContent === "X") {
      element.textContent = "O";
    }else {
      element.textContent = "";
    }
}

document.querySelectorAll('.your-class').forEach(function (element) {
   element.addEventListener('click', swap(element));
});
于 2018-08-28T03:25:01.873 回答
1

井字游戏!

只是添加样式,抱歉走神了,也许有点兴趣。

//
const board = [
  [1, 2, 3],
  [1, 2, 3],
  [1, 2, 3]
];

new Vue({
  el: '#app',
  data() {
    return {
      plays: 0,
      player: true,
      winner: '',
      board: JSON.parse(JSON.stringify(board))
    }
  },
  methods: {
    resetGame() {
      this.plays = 0
      this.winner = ''
      this.board = JSON.parse(JSON.stringify(board))
    },
    isBool(value) {
      return typeof(value) === typeof(true)
    },
    play(x, y) {
      if (!this.isBool(this.board[x][y]) && this.winner === '') {
        this.board[x][y] = this.player
        this.plays++
          this.checkWin(this.player)
        this.player = !this.player
      }
    },
    slot(x, y) {
      return {
        'fa-circle-o': this.isBool(this.board[x][y]) && this.board[x][y] === true,
        'fa-times': this.isBool(this.board[x][y]) && this.board[x][y] === false
      }
    },
    endGame(player) {
      this.winner = player
    },
    checkWin(player) {
      // check horizontal win
      for (var i = 0; i <= 2; i++) {
        if (this.board[i][0] === player &&
          this.board[i][1] === player &&
          this.board[i][2] === player) {
          this.endGame(player);
        }
      }
      // check vertical win
      for (var i = 0; i <= 2; i++) {
        if (this.board[0][i] === player &&
          this.board[1][i] === player &&
          this.board[2][i] === player) {
          this.endGame(player);
        }
      }
      // check diagonal win
      if ((this.board[0][0] === player &&
          this.board[1][1] === player &&
          this.board[2][2] === player) ||
        this.board[0][2] === player &&
        this.board[1][1] === player &&
        this.board[2][0] === player) {
        this.endGame(player);
      }
      if (this.plays === 9) {
        this.endGame(-1);
      }
    }
  }
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
  table tr td {
    min-width: 20px;
    min-height: 20px;
    padding: 3px;
    text-align: center;
  }
</style>
<div id="app">

  <h3>Tic-Tac-Vue</h3>

  <p>It's player <i :class="['fa', {'fa-circle-o': player, 'fa-times': !player}]"></i>'s go!</p>

  <table border="1">
    <tr>
      <td @click="play(0,0)"><i :class="['fa', slot(0,0)]"></i></td>
      <td @click="play(0,1)"><i :class="['fa', slot(0,1)]"></i></td>
      <td @click="play(0,2)"><i :class="['fa', slot(0,2)]"></i></td>
    </tr>
    <tr>
      <td @click="play(1,0)"><i :class="['fa', slot(1,0)]"></i></td>
      <td @click="play(1,1)"><i :class="['fa', slot(1,1)]"></i></td>
      <td @click="play(1,2)"><i :class="['fa', slot(1,2)]"></i></td>
    </tr>
    <tr>
      <td @click="play(2,0)"><i :class="['fa', slot(2,0)]"></i></td>
      <td @click="play(2,1)"><i :class="['fa', slot(2,1)]"></i></td>
      <td @click="play(2,2)"><i :class="['fa', slot(2,2)]"></i></td>
    </tr>
  </table>

  <p v-if="winner === true || winner === false">Player <i :class="['fa', {'fa-circle-o': !player, 'fa-times': player}]"></i> is the winner!!</p>
  <p v-if="winner === -1">Game Over, Draw!!</p>
  <button @click="resetGame()">Reset Game</button>
</div>

看到它在这里工作:https ://jsfiddle.net/7ktbphaf/

于 2018-08-28T05:37:38.200 回答
0

太有趣了,我已经用 Jeremy Dejno 的一些代码解决了这个问题,但不得不调整它。考虑到我在第一篇文章中发布的 HTML 代码,这对我有用:

function swap(){
    if (this.textContent === ""){
      this.textContent = "X";
    }else if (this.textContent === "X") {
      this.textContent = "O";
    }else {
      this.textContent = "";
    }
  }

document.querySelectorAll('.gameField').forEach(function(element){
    element.addEventListener('click',swap);
  })

由于这对我来说是一个全新的东西(我来自 Python 背景),有人可以告诉我我是否理解正确:在每个带有 .gameField 类的项目上调用 .addEventListener 后,每次点击事件都会调用一个交换函数在它们中的任何一个上,并且可以在没有任何参数的情况下调用交换函数,因为 THIS 关键字使它尝试修改调用它的任何对象的 .textContent 属性?

于 2018-08-28T04:14:34.283 回答