开发者问题收集

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