JS:innerHTML 不一致
JS: innerHTML inconsistency
我正在使用 Google Chrome 版本 43.0.2357.130。我正在尝试使用 innerHTML 将输出附加到 HTML 元素,这是在循环内部完成的。大多数时候我都能得到预期的结果,但如果我一遍又一遍地点击 "Generate" 按钮,最终它会给我一个意想不到的结果。例如,其中一个密码将在随机位置被截断。我在 Chrome 中使用了 JS 调试器,但这并没有太大帮助。然后我尝试通过使用 alert() 函数和 innerHTML 属性 来自己调试它,以便我可以比较输出。与 innerHTML.
不同,alert() 弹出窗口中的输出从未被截断
我在 JS 文件中用 '/* PROBLEM CODE */' 突出显示了我认为是问题的代码。这些文件应放在同一目录中。这是 HTML 和 JS:
<!DOCTYPE html>
<html>
<head>
<title>PassGen - Random Password Generator</title>
<!--link rel="stylesheet" src="//normalize-css.googlecode.com/svn/trunk/normalize.css"-->
<!--link href="css/main.css" rel="stylesheet" type="text/css"-->
<!--script src="../app/js/jquery-2.1.4.js"></script-->
</head>
<body>
<form>
<h2>Password amount</h2>
<input type="text" id="amount" name="amount" />
<h2>Letter amount</h2>
<input type="text" id="letters" name="letters" />
<h2>Number amount </h2>
<input type="text" id="numbers" />
<h2>Symbol amount</h2>
<input type="text" id="symbols" />
<input onclick="generatePassword(); return false;" type="submit" value="Generate" />
</form>
<p id="output"></p>
<script src="plain-app.js"></script>
</body>
</html>
// get the DOM element we will be using for the final output
var output = document.getElementById("output");
function generatePassword(amount) {
clearPasswords();
// get DOM form elements (user input)
var amount = document.getElementById("amount").value;
var letters = document.getElementById("letters").value;
var numbers = document.getElementById("numbers").value;
var symbols = document.getElementById("symbols").value;
// populate character sets
var letterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var numberSet = "0123456789";
var symbolSet = "~!@#$%^&*()-_+=><";
var array = [];
// if there is no password amount specified, create one password
if(amount === undefined) {
amount = 1;
}
for(var j = 0; j < amount; j++) {
// random character sets to be concatenated later
var rl = "";
var rn = "";
var rs = "";
var tp = ""; // concatenated password before shuffling
// 3 random letters
for(var i = 0; i < letters; i++) {
var rnd = Math.floor((Math.random() * 52));
rl += letterSet[rnd];
}
// 3 random numbers
for(var i = 0; i < numbers; i++) {
var rnd = Math.floor((Math.random() * 10));
rn += numberSet[rnd];
}
// 3 random symbols
for(var i = 0; i < symbols; i++) {
var rnd = Math.floor((Math.random() * 17));
rs += symbolSet[rnd];
}
tp = rl + rn + rs; // string concatentation
tp = tp.split(''); // transform string into an array
// shuffling
for(var i = 0; i < tp.length; i++) {
var rnd = Math.floor(Math.random() * tp.length);
var temp = tp[i];
tp[i] = tp[rnd];
tp[rnd] = temp;
}
// transform the array into a string
tp = tp.join("");
array[j] = tp; // for logging and debugging purposes
// tp can be replaced with array[j], but still get the inconsistency
/* PROBLEM CODE */
output.innerHTML += (tp + "<br />");
/* PROBLEM CODE */
//alert(array[j]);
}
console.log(array);
return array; // not useful?
}
// clear all password output
function clearPasswords() {
while(output.hasChildNodes()) {
output.removeChild(output.firstChild);
}
}
innerHTML 是否有我不知道的副作用或我使用不当?它不应该用于追加吗?应该改用 appendChild() 吗?
问题发生在 symbolSet
。它包含字符 <
和 >
。当它们被随机选择并添加到密码中时,当我将密码输出到屏幕时,浏览器试图将它们呈现为元素。为了解决这个问题,我只是从 symbolSet
中删除了两个字符,并更改了随机符号生成循环以反映 symbolSet
的缩短长度。
我将有问题的两段代码更改为
var symbolSet = "~!@#$%^&*()-_+=";
和
for(var i = 0; i < symbols; i++) {
var rnd = Math.floor((Math.random() * 15)); // this end of this line
rs += symbolSet[rnd];
}
另外,我把无用的if
语句改成了(这个可以应用于所有的字段)
if(!isNumber(amount) || amount === 0) {
amount = 1;
}
并添加了一个 isNumber
函数来检查所有字段的有效输入。
function isNumber(obj) {
return !isNaN(parseFloat(obj));
}
问题是某些字符在HTML中具有特殊含义:<
、>
、&
.
因此,您可以
- 从列表中删除这些字符
逃避他们:<
、>
、&
output.innerHTML += tp.replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&') + "<br />";
将文本解析为文本而不是HTML,例如
使用textContent
and white-space
output.textContent += tp + "\n";
#output { white-space: pre-line; }
使用createTextNode
and appendChild
output.appendChild(document.createTextNode(tp));
output.appendChild(document.crateElement('br'));
我正在使用 Google Chrome 版本 43.0.2357.130。我正在尝试使用 innerHTML 将输出附加到 HTML 元素,这是在循环内部完成的。大多数时候我都能得到预期的结果,但如果我一遍又一遍地点击 "Generate" 按钮,最终它会给我一个意想不到的结果。例如,其中一个密码将在随机位置被截断。我在 Chrome 中使用了 JS 调试器,但这并没有太大帮助。然后我尝试通过使用 alert() 函数和 innerHTML 属性 来自己调试它,以便我可以比较输出。与 innerHTML.
不同,alert() 弹出窗口中的输出从未被截断我在 JS 文件中用 '/* PROBLEM CODE */' 突出显示了我认为是问题的代码。这些文件应放在同一目录中。这是 HTML 和 JS:
<!DOCTYPE html>
<html>
<head>
<title>PassGen - Random Password Generator</title>
<!--link rel="stylesheet" src="//normalize-css.googlecode.com/svn/trunk/normalize.css"-->
<!--link href="css/main.css" rel="stylesheet" type="text/css"-->
<!--script src="../app/js/jquery-2.1.4.js"></script-->
</head>
<body>
<form>
<h2>Password amount</h2>
<input type="text" id="amount" name="amount" />
<h2>Letter amount</h2>
<input type="text" id="letters" name="letters" />
<h2>Number amount </h2>
<input type="text" id="numbers" />
<h2>Symbol amount</h2>
<input type="text" id="symbols" />
<input onclick="generatePassword(); return false;" type="submit" value="Generate" />
</form>
<p id="output"></p>
<script src="plain-app.js"></script>
</body>
</html>
// get the DOM element we will be using for the final output
var output = document.getElementById("output");
function generatePassword(amount) {
clearPasswords();
// get DOM form elements (user input)
var amount = document.getElementById("amount").value;
var letters = document.getElementById("letters").value;
var numbers = document.getElementById("numbers").value;
var symbols = document.getElementById("symbols").value;
// populate character sets
var letterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var numberSet = "0123456789";
var symbolSet = "~!@#$%^&*()-_+=><";
var array = [];
// if there is no password amount specified, create one password
if(amount === undefined) {
amount = 1;
}
for(var j = 0; j < amount; j++) {
// random character sets to be concatenated later
var rl = "";
var rn = "";
var rs = "";
var tp = ""; // concatenated password before shuffling
// 3 random letters
for(var i = 0; i < letters; i++) {
var rnd = Math.floor((Math.random() * 52));
rl += letterSet[rnd];
}
// 3 random numbers
for(var i = 0; i < numbers; i++) {
var rnd = Math.floor((Math.random() * 10));
rn += numberSet[rnd];
}
// 3 random symbols
for(var i = 0; i < symbols; i++) {
var rnd = Math.floor((Math.random() * 17));
rs += symbolSet[rnd];
}
tp = rl + rn + rs; // string concatentation
tp = tp.split(''); // transform string into an array
// shuffling
for(var i = 0; i < tp.length; i++) {
var rnd = Math.floor(Math.random() * tp.length);
var temp = tp[i];
tp[i] = tp[rnd];
tp[rnd] = temp;
}
// transform the array into a string
tp = tp.join("");
array[j] = tp; // for logging and debugging purposes
// tp can be replaced with array[j], but still get the inconsistency
/* PROBLEM CODE */
output.innerHTML += (tp + "<br />");
/* PROBLEM CODE */
//alert(array[j]);
}
console.log(array);
return array; // not useful?
}
// clear all password output
function clearPasswords() {
while(output.hasChildNodes()) {
output.removeChild(output.firstChild);
}
}
innerHTML 是否有我不知道的副作用或我使用不当?它不应该用于追加吗?应该改用 appendChild() 吗?
问题发生在 symbolSet
。它包含字符 <
和 >
。当它们被随机选择并添加到密码中时,当我将密码输出到屏幕时,浏览器试图将它们呈现为元素。为了解决这个问题,我只是从 symbolSet
中删除了两个字符,并更改了随机符号生成循环以反映 symbolSet
的缩短长度。
我将有问题的两段代码更改为
var symbolSet = "~!@#$%^&*()-_+=";
和
for(var i = 0; i < symbols; i++) {
var rnd = Math.floor((Math.random() * 15)); // this end of this line
rs += symbolSet[rnd];
}
另外,我把无用的if
语句改成了(这个可以应用于所有的字段)
if(!isNumber(amount) || amount === 0) {
amount = 1;
}
并添加了一个 isNumber
函数来检查所有字段的有效输入。
function isNumber(obj) {
return !isNaN(parseFloat(obj));
}
问题是某些字符在HTML中具有特殊含义:<
、>
、&
.
因此,您可以
- 从列表中删除这些字符
逃避他们:
<
、>
、&
output.innerHTML += tp.replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&') + "<br />";
将文本解析为文本而不是HTML,例如
使用
textContent
andwhite-space
output.textContent += tp + "\n";
#output { white-space: pre-line; }
使用
createTextNode
andappendChild
output.appendChild(document.createTextNode(tp)); output.appendChild(document.crateElement('br'));