JavaScript - 如何判断元素是否为空?

8
我正在制作井字游戏。我的问题是,即使其中一个方格已经包含X或O,我的代码仍然允许重写X或O。我使用if语句根据每次增加的数字变量来写入X或O。我想添加另一个条件,只有在我的标签为空时才允许写入X或O。我该如何做?注意:请只使用JavaScript,因为我还没有开始学习jQuery。提前感谢!
var tds = document.querySelectorAll("td");
var player = 1;
var str = "";

for (var i = 0; i < tds.length; i++) {
  tds[i].addEventListener("click", function(){
     if( player % 2 === 0 && tds[i] !== "<td>X</td>"  && tds[i] !==
     "<td>O</td>"){
       this.textContent = "O";
     } else if (player % 2 !== 0 && tds[i] === "" ) {
       this.textContent = "X";
     }
   player++;

  });
}

HTML -

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css.css">
    <title></title>
  </head>
  <body>
    <table>
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
    </table>
    <script type="text/javascript" src="js.js">

    </script>
  </body>
</html>

请注意,您的代码存在许多语法和语义错误 - 请尝试发布可工作的代码。还请注意,如果您能够执行this.textContent = "X";(不确定该 this 应该是什么...),那么您也可以执行this.textContent.length === 0 - Ken Y-N
6个回答

11
您可以检查元素的 childNodes 属性,它会返回一个 Nodelist

如果长度为 0,则表示您的元素为空。

const elem = document.querySelector("#container")
console.log(elem.childNodes.length)
<div id="container"></div>

小心,因为换行符也会被视为 文本


1
这将解决空白/换行符作为文本的问题 https://stackoverflow.com/questions/48722545/how-do-i-check-if-an-element-div-is-empty-without-jquery-but-with-javascript - analytical_prat
1
childNondes 也会返回注释节点。因此,如果它没有元素和文本,但是内部有一个注释标签,则长度将大于0。最好循环遍历 childNodes 并返回 Node.TEXT_NODENode.ELEMENT_NODE 的列表。然后检查数组的长度。在后一种情况下,它还需要修剪,因为浏览器会在注释周围创建空文本节点。 - Gevorg Hakobyan
@GevorgHakobyan,你能把这个编辑到答案里吗?这是一个非常好的和重要的注释。 - nicholaswmin
@nicholaswmin,我只是想提醒一下限制。我们也可以使用elem.outerHTML.length,但它也会考虑注释标记。如果我们期望空白作为空文本节点,则使用elem.innerText.length(考虑到空文本节点)和elem.innerText.trim().length(对于完全没有文本的元素节点)。 - Gevorg Hakobyan

5

node.childNodes.length 返回的是节点内部的所有元素数量,包括空格和格式化返回值。

例如:以下代码会返回3

<td>
  <!-- returns NodeList(3) [text, comment, text] -->
</td>

<span>&nbsp;<span> 将返回1,而 <span>&nbsp;<span>&nbsp;</span></span> 将返回 2

除非您确信数据正确或对数据源进行了良好的清洗,否则建议使用以下方法来检测节点是否为空。

// <div id="SomeElement" />

function isEmpty(node) {
  return node.textContent.trim() === "";
}

isEmpty(SomeElement);

// or

Element.prototype.isEmpty = function() {
  return this.textContent.trim() === "";
}

SomeElement.isEmpty();

function emptyElementNode(node) {
  return node.textContent.trim() === "";
}

var xo = TicTacToe.getElementsByTagName('div');

for (var i = 0; i < xo.length; ++i) {

 if (emptyElementNode(xo[i])) {
    xo[i].classList.add('highlight');
    xo[i].textContent = "⚬";
  }

}
#TicTacToe {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  grid-gap: 0.063rem;
  width: 6.25rem;
  height: 6.25rem;
  align-items: center;
  justify-items: center;
  margin: -0.063rem;
  overflow: hidden;
}

#TicTacToe {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  grid-gap: 0.063rem;
  width: 6.25rem;
  height: 6.25rem;
  align-items: center;
  justify-items: center;
  margin: -0.063rem;
  overflow: hidden;
}

#TicTacToe div{
  position: relative;
}

#TicTacToe div::before {
  content: "";
  display: block;
  position: absolute;
  width: calc(6.25rem / 3);
  height: calc(6.25rem / 3);
  left: 50%;
  top: 50%;
  transform: translate3d(-50%, -50%, 0);
  background: #fff;
  z-index: -1;
  outline: 1px solid #222;
}

#TicTacToe .highlight::before {
  background: #ddd;
}

#TicTacToe div{
  position: relative;
}

#TicTacToe div::before {
  content: "";
  display: block;
  position: absolute;
  width: calc(6.25rem / 3);
  height: calc(6.25rem / 3);
  left: 50%;
  top: 50%;
  transform: translate3d(-50%, -50%, 0);
  background: #fff;
  z-index: -1;
  outline: 1px solid #222;
}

#TicTacToe .highlight::before {
  background: #ddd;
}
<div id="TicTacToe">
  <div></div>
  <div>×</div>
  <div>×</div>
  <div></div>
  <div></div>
  <div>×</div>
  <div></div>
  <div>×</div>
  <div></div>
</div>


2

您可以使用 innerHtml 属性来检查元素是否包含任何内容。但是,当您设置 html X或O 时,我更喜欢添加类 marked。然后在您的 js 中检查该元素是否具有类 marked。 使用以下方法在单击事件中添加 td 类:

function mark(e)
{
var isMarked = hasClass(e,"marked");
if(!isMarked )
{
e.className+= " marked";
//add X or O
}
else
{
//do something else
}
function hasClass(element, className) {
    return element.className && new RegExp("(^|\\s)" + className + "(\\s|$)").test(element.className);
}

HTML:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css.css">
    <title></title>
  </head>
  <body>
    <table>
      <tr>
        <td onclick="mark(this)"></td>
       .
       .
        <td></td>
      </tr>
    </table>
    <script type="text/javascript" src="js.js">

    </script>
  </body>
</html>

hasClass参考: http://sonnyt.com/blog/development/javascript-check-if-element-has-class


2

这个方法在所有浏览器中都有完整的支持:yourNode.hasChildNodes()

Node.hasChildNodes() 方法返回一个布尔值,指示给定的节点是否具有子节点。

文档


0

您可以检查元素的 innerHTML 属性,以确定它们是否包含任何内容- 在您的情况下是 XO

因此,条件应该像这样。

if( player % 2 === 0 && tds[i].innerHTML !== "X"  && tds[i].innerHTML !== "O") {

}

你的代码中可能还存在其他错误,但这是一种检查 DOM 元素内容的方法。 - Charlie

0
请在下面找到可行的解决方案。

var player = 1;
var blocks = document.querySelectorAll('td');
var title = document.getElementById('title');

function switchPlayer(currentPlayer) {
  if (currentPlayer === 1) {
    player = 2;
    title.innerHTML = 'Player: 2(O)'
  } else {
    player = 1;
    title.innerHTML = 'Player: 1(X)'
  }
}

blocks.forEach(function(block) {
  block.addEventListener('click', function() {
    if (!block.innerHTML) {
      if (player === 1) {
        block.innerHTML = 'X';
      } else {
        block.innerHTML = 'O';
      }
      switchPlayer(player)
    }
  })
});
td {
  border: 1px solid black;
  width: 50px;
  height: 50px;
}
<h1 id="title">
Player: 1 (X)
</h1>
<table>
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</table>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接