改变 innerHTML 只工作一次
Changing innerHTML only works once
我正在尝试在 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)有关系吗?
问题是您使用 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 said in the ,您可以做的另一个调整是
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>
这个问题,每次你调用构造函数,它都会重建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);
<div id="scoreboard"></div>
我正在尝试在 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)有关系吗?
问题是您使用 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 said in the
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>
这个问题,每次你调用构造函数,它都会重建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);
<div id="scoreboard"></div>