onchange 第一次会运行一个函数来创建一个 html 元素,但第二次就不会再这么做了
2017-08-17
126
我试图用 javascript 制作一个聊天程序,在有人输入第一个问题的答案之前,该程序不会显示下一个问题。
此函数可以显示第一个问题(“第一段”),然后显示第二个问题(“第二段”),但第三次不起作用。
我一直收到错误:
"Uncaught TypeError: Cannot set property 'onchange' of null."
我尝试使用
onkeyup
和 jquery 的
.keyup()
函数,但它给出了相同的错误。当我使用调试器查看生成的 html 时,它显示第二段,所以我不明白为什么计算机说它是空的。
我该如何解决这个问题?
<div id = "div1">
</div>
<script>
function setElement(text, id, id2){
var para = document.createElement("p");
var node = document.createTextNode(text);
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
para.id = id;
var inputBox = document.createElement("input");
element.appendChild(inputBox);
inputBox.id = id2;
}
setElement("This is paragraph one.", "p1", "i1");
document.getElementById("i1").onchange = function(){setElement("This is paragraph two.", "p2", "i2")};
document.getElementById("i2").onchange = function(){setElement("This is paragraph three.", "p3", "i3")};
//Uncaught TypeError: Cannot set property 'onchange' of null
</script>
3个回答
document.getElementById("i2").onchange = function(){setElement("This is paragraph three.", "p3", "i3")};
javascript 运行时该元素不存在,因此会抛出错误。您需要在创建新元素后运行此行代码。
function setElement(pnum){
var para = document.createElement("p");
var node = document.createTextNode("this is paragraph " + pnum + ".");
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
para.id = "p" + pnum;
var inputBox = document.createElement("input");
element.appendChild(inputBox);
inputBox.id = "i" + pnum;
pnum++;
inputBox.onchange = function(){setElement(pnum)};
}
setElement(1);
上述更改将继续创建段落和输入字段。
Momus
2017-08-17
我不确定你实际上想要用这个实现什么,但这里有一个聊天应用程序的模拟,它完全在浏览器窗口内的前端 javascript 中运行。
function setElement(caller){
var outputs = document.getElementsByClassName("output");
Array.prototype.forEach.call(outputs, function(o) {
o.appendChild(makePara(caller, o));
o.scrollTop = o.scrollHeight;
});
caller.value = "";
}
function makePara(caller, o) {
var para = document.createElement("p");
var node = document.createTextNode(caller.value);
para.appendChild(node);
if (o.parentElement != caller.parentElement.parentElement) {
para.style.textAlign = "right";
para.style.backgroundColor = "#ffeeee";
} else {
para.style.textAlign = "left";
para.style.backgroundColor = "#eeffee";
}
return para;
}
var inputBox1 = document.getElementById("input1");
var inputBox2 = document.getElementById("input2");
inputBox1.onchange = function(){setElement(this)};
inputBox2.onchange = function(){setElement(this)};
.chat {
display: inline-block;
width: 200px;
padding: 20px;
border: 1px solid black;
}
.output {
width: 200px;
height: 200px;
overflow-y: scroll;
overflow-x: wrap;
}
<div id="div1" class="chat">
<h4>Chat window 1</h4>
<div id="txt1" class="output"></div>
<div id="inpt1">
<input type='text' id="input1" />
</div>
</div>
<div id="div2" class="chat">
<h4>Chat window 2</h4>
<div id="txt2" class="output"></div>
<div id="inpt2">
<input type='text' id="input2" />
</div>
</div>
Momus
2017-08-18
这是我最终得到的结果,感谢 Momus 和 https://www.w3schools.com/css/tryit.asp?filename=trycss_display_js 。还要感谢所有一直告诉我这些元素尚不存在的人。我决定先让它们存在,然后使用 javascript 来显示它们。
<div id = "div1">
<p id = "p1" style = "display:none;">Hi, I'm RiddleBot. What is your name?</p>
<input id = "i1" type = "text" style = "display:none;">
<p id = "p2" style = "display: none;">Hi. What do you like to do?</p>
<input id = "i2" type = "text" style = "display:none;">
<p id = "p3" style = "display: none;">I like to tell riddles. Do you want to hear one?</p>
<input id = "i3" type = "text" style = "display:none;">
<p id = "p4" style = "display: none;">In marble walls as white as...</p>
<input id = "i4" type = "text" style = "display:none">
</div>
<script>
function showElement(pnum){
var inputBox = document.getElementById("i" + pnum);
document.getElementById("p" + pnum).style.display = "block";
document.getElementById("i" + pnum).style.display = "block";
pnum++;
inputBox.onchange = function () {showElement(pnum)};
}
showElement(1);
</script>
erin
2017-08-19