我正在尝试用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)有什么关系吗?
答案 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>
@dandavis在comments中说过,您可以做的另一个调整是
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
才会重建。
每次获得或设置分数时,您都可以使用appendChild或getElementById
解决此问题
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;