我有一些JavaScript函数,用于添加和删除HTML div到更大的div。函数init是正文的onload。当外部按钮调用NewLine()时,会添加新行。当所述div内的按钮调用DeleteLine()时,Div被删除。但是代码有一些问题:当我添加一个新行时,所有其他行的颜色值都被清除,当删除行时,按钮,标题和行框的ID不同步。我已经使用Chrome调试器进行了几次,但每次我修复它似乎都会导致一个新问题。我非常感谢我对错误的看法。
function init()
{
numOfLines = 0; //Keeps track of the number of lines the Artulator is displaying
}
function NewLine()
{
var LineBoxHolder = document.getElementById("LineBoxHolder");
numOfLines += 1;
LineBoxCode += "<div class = 'Line Box' id = 'LineBox" + numOfLines + "'>" //The code is only split onto multiple lines to look better
+ " <h6 id = 'Title " + numOfLines + "' class = 'Line Box Title'>Line " + numOfLines + "</h6>";
+ " <p>Color: <input type = 'color' value = '#000000'></p>"
+ " <input type = 'button' value = 'Delete Line' id = 'DeleteLine" + numOfLines + "' onclick = 'DeleteLine(" + numOfLines + ")'/>"
+ "</div>";
LineBoxHolder.innerHTML += LineBoxCode;
}
function DeleteLine(num)
{
deletedLineName = "LineBox" + num;
deletedLine = document.getElementById(deletedLineName);
deletedLine.parentNode.removeChild(deletedLine);
num++;
for ( ; num < numOfLines + 1 ; )
{
num++;
var newNum = num - 1;
var changedLineName = "LineBox" + num;
var changedHeaderName = "Title" + num;
var changedButtonName = "DeleteLine" + num;
var changedButtonOC = "DeleteLine(" + newNum + ")";
var changedLine = document.getElementById(changedLineName);
var changedHeader = document.getElementById(changedHeaderName);
var changedButton = document.getElementById(changedButtonName);
var changedLine.id = "LineBox" + newNum;
var changedHeader.innerHTML = "Line" + newNum;
var changedHeader.id = "Title" + newNum;
var changedButton.setAttribute("onclick",changedButtonOC);
var changedButton.id = "DeleteLine" + newNum;
}
num--;
numOfLines = num;
}
答案 0 :(得分:1)
由于您的方法,您很难调试代码。您使用您构造的ID“标记”各种元素,并使用ID查找和寻址元素。这意味着当事情发生变化时,例如删除行,您必须返回并修复标记。几乎按照定义,您编写的复杂代码会执行类似的操作会产生错误。即使你有很好的调试技巧,你也会花一些时间来处理这些错误。
不要过度使用ID作为识别DOM元素的穷人。这样做需要在创建元素时构造ID并为子元素构造更多ID。然后要再次找到该元素,您必须构造另一个ID字符串并执行getElementById
。相反,使用JavaScript来管理DOM。而不是传递ID和数字的ID部分,而不是传递DOM元素本身。在您的情况下,您根本不需要ID。
让我们从DeleteLine
开始吧。而不是传递一个数字,传递给元素本身,你可以修复你的大DOM字符串中的代码,如下所示:
<input type='button' value='Delete Line' onclick="DeleteLine(this.parentNode)"/>
因此我们没有line元素的ID,元素没有ID,onclick处理程序中没有ID。 DeleteLine
本身现在可以简单地
function DeleteLine(line) {
{
line.parentNode.removeChild(line);
renumberLines();
}
稍后我们会显示renumberLines
。无需调整ID,重写现有元素或其他任何内容。
由于我们不再需要每一行或其子元素上的ID,因此创建每个元素的代码变得更加简单:
function NewLine()
{
var LineBoxHolder = document.getElementById("LineBoxHolder");
numOfLines += 1;
var LineBoxCode = "<div class='LineBox'>" +
+ " <h6 class='LineBoxTitle'>Line " + "numOfLines + "</h6>"
+ " <p>Color: <input type='color' value='#000000'></p>"
+ " <input type='button' value='Delete Line' onclick= 'DeleteLine(this.parentNode)'/>"
+ "</div>";
LineBoxHolder.innerHTML += LineBoxCode;
}
唯一剩下的工作是修复标题以显示正确的数字。您可以通过循环遍历这些来完成此操作,如
function renumberLines() {
var LineBoxHolder = document.getElementById("LineBoxHolder");
var lines = LineBoxHolder.childElements;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
var h6 = line.querySelector('h6');
h6.textContent= "Line " + (i+1);
}
}
答案 1 :(得分:0)
我投票结束是因为问题 过于宽泛,但无论如何都会在几点上回答......好吧,指向正确的方向。
var changedButton.setAttribute("onclick",changedButtonOC);
这不是变量声明。省略var
。
for ( ; num < numOfLines + 1 ; ) { num++; ...
此处的正确表单只是for (; num < numOfLines + 1; num++) { ...
。
而不是递增(num++
)然后在循环周围递减(num--
),为什么不使用正确的数学呢?
请参阅:
for (; num < numOfLines; num++) {
...
}