更改innerHTML只能工作一次

时间:2015-10-19 08:40:29

标签: javascript html innerhtml

我正在尝试用HTML制作记分牌,其中javascript函数可以改变各种玩家的分数。但是,除了一个玩家之外的所有玩家的得分都无法正确显示。

HTML:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
</head>
<body>
    <div id="scoreboard"></div>
    <script type="text/javascript" src="main.js"></script>
</body>
</html>

使用Javascript:

function Player(ID) {
    this.ID = ID;

    var scoreboard = document.getElementById("scoreboard");

    //Create a <p> in scoreboard with "Player n:" in it, and then
    //create a <span> with the score and a unique ID to use for getting and setting
    scoreboard.innerHTML += "<p>Player " + this.ID + ":" + "<span id=\"PlayerScore" + this.ID + "\">0</span></p>";

    this.scoreElement = document.getElementById("PlayerScore" + this.ID); //set score element

    //Getter and setter for score
    this.getScore = function() {return Number(this.scoreElement.innerHTML);}
    this.setScore = function(scoreIn) {this.scoreElement.innerHTML = scoreIn.toString();}
}

我使用以下Javascript测试此代码:

var player1 = new Player(1);
var player2 = new Player(2);
var player3 = new Player(3);

player1.setScore(player1.getScore() + 1);
player2.setScore(player2.getScore() + 1);
player3.setScore(player3.getScore() + 1);

执行此操作后,生成的网页中的记分板显示为:

Player 1:0
Player 2:0
Player 3:1

但是,应该阅读

Player 1:1
Player 2:1
Player 3:1    

有什么想法吗?为什么只有最后一个有效?我是如何直接从scoreElement的InnerHTML获取和设置的?它与我的浏览器(firefox)有什么关系吗?

2 个答案:

答案 0 :(得分:9)

问题是您使用innerHTML添加更多内容,一旦您使用innerHTML +=它将重新创建所有dom元素,因此您之前创建的scoreElement引用将不再出现在dom树就是那些没有得到更新的原因。

解决问题的方法不是使用.innerHTML来附加内容,而是可以创建dom元素并调用appendChild()方法将其添加到父元素,如

function Player(ID) {
  this.ID = ID;

  var scoreboard = document.getElementById("scoreboard");

  var playerElement = document.createElement('p');
  this.scoreElement = document.createElement('span');
  this.scoreElement.innerHTML = 0;
  playerElement.appendChild(document.createTextNode("Player " + this.ID + ":"));
  playerElement.appendChild(this.scoreElement);
  scoreboard.appendChild(playerElement)

  //Getter and setter for score
  this.getScore = function() {
    return Number(this.scoreElement.innerHTML);
  }
  this.setScore = function(scoreIn) {
    this.scoreElement.innerHTML = scoreIn.toString();
  }
}

var player1 = new Player(1);
var player2 = new Player(2);
var player3 = new Player(3);

player1.setScore(player1.getScore() + 1);
player2.setScore(player2.getScore() + 1);
player3.setScore(player3.getScore() + 1);
<div id="scoreboard"></div>

@dandaviscomments中说过,您可以做的另一个调整是

function Player(ID) {
  this.ID = ID;

  var scoreboard = document.getElementById("scoreboard");

  var playerElement = document.createElement('p');
  playerElement.innerHTML = "Player " + this.ID + ":" + '<span>0</span>';
  this.scoreElement = playerElement.querySelector('span');
  scoreboard.appendChild(playerElement)

  //Getter and setter for score
  this.getScore = function() {
    return Number(this.scoreElement.innerHTML);
  }
  this.setScore = function(scoreIn) {
    this.scoreElement.innerHTML = scoreIn.toString();
  }
}

var player1 = new Player(1);
var player2 = new Player(2);
var player3 = new Player(3);

player1.setScore(player1.getScore() + 1);
player2.setScore(player2.getScore() + 1);
player3.setScore(player3.getScore() + 1);
<div id="scoreboard"></div>

答案 1 :(得分:3)

问题是,每次调用构造函数时,它都会重建scoreboard.innerHTML,这意味着它的所有子元素都被删除并重建,

所以只有在你的最后一个例子中,this.scoreElement才会重建。

每次获得或设置分数时,您都可以使用appendChildgetElementById解决此问题

&#13;
&#13;
function Player(ID) {
    this.ID = ID;

    var scoreboard = document.getElementById("scoreboard");

    //Create a <p> in scoreboard with "Player n:" in it, and then
    //create a <span> with the score and a unique ID to use for getting and setting
    scoreboard.innerHTML += "<p>Player " + this.ID + ":" + "<span id=\"PlayerScore" + this.ID + "\">0</span></p>";


    //Getter and setter for score
    this.getScore = function() {return Number(document.getElementById("PlayerScore" + this.ID).innerHTML);}
    this.setScore = function(scoreIn) { document.getElementById("PlayerScore" + this.ID).innerHTML = scoreIn.toString();}
}


var player1 = new Player(1);
var player2 = new Player(2);
var player3 = new Player(3);



player1.setScore(player1.getScore() + 1);
player2.setScore(player2.getScore() + 1);
player3.setScore(player3.getScore() + 1);
&#13;
<div id="scoreboard"></div>
&#13;
&#13;
&#13;