javascript - 克隆时将数据记录到适当的 html 子元素
问题描述
我在 Google 表格中有一个表格,我从表格中发送动态数据。
我循环工作表数据并以与我的标题数量相同的形式创建相同数量的块。
我有第一块用 html 编写的元素。我从第一个块克隆的其余块,克隆它的 ID 并将我的工作表标题发送到表单的元素。
我写的第一个标题(带有数组中的最后一个标题)到循环之前存在的唯一块。
然后我克隆那个块给一个克隆新标题并尝试在第一个块([0])之前插入克隆,但它出错并覆盖了我的第一个硬编码标题。
它以随机数附加块,因此我无法以正确的顺序获得标题,例如“1,2,3”。 它总是像“2,1,1”或“1,3,2”等。
我尝试了附加克隆元素的不同变体(例如motherDiv.appendChild(clonedRow)
and motherDiv.insertBefore(clonedRow, motherDiv.children[0])
,但无法使其正常工作。
请指出这里有什么问题。
这是代码和屏幕:
//my google app backend function with data
var numbers = [1, 2, 3]
var stats = ["Валовый доход", "Кол-во клиентов", "Кол-во размещенной рекламы"]
var stats = {
statNumbers: numbers,
statStats: stats
}
//select initialization
document.addEventListener('DOMContentLoaded', function() {
var getstats = getStats();
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems);
});
//getting stats object
function getStats() {
google.script.run.withSuccessHandler(processStats).statsObj();
google.script.run.withFailureHandler(showError).statsObj()
return;
}
//creating dynamic stats fields in the form
function processStats(stats) {
//name first statistic with the last number
var firstStat = document.getElementById("statName").innerHTML = stats.statNumbers[stats.statStats.length - 1] + ". " + stats.statStats[stats.statStats.length - 1]
//mother div
var motherDiv = document.getElementById("motherDiv")
//sample row to copy
var statRow = document.getElementById("statsample");
//loop stat names
for (var i = 0; i < stats.statStats.length - 1; i++) {
var statName = stats.statStats[i]
var statNumber = stats.statNumbers[i]
//cloning the original row
var clonedRow = statRow.cloneNode(true)
//setting unique ID to whole row
var rowId = clonedRow.id = "statsample" + i
//setting unique ID to stat div
var clonedStatID = motherDiv.getElementsByClassName("statClass")[0].id = "statName" + statNumber
//stat titles (except first one)
var statHtml = document.getElementById(clonedStatID).innerHTML = statNumber + ". " + statName;
var err = document.getElementById("err").innerHTML = motherDiv.children.length
//appending it to the mother div
//motherDiv.appendChild(clonedRow);
motherDiv.insertBefore(clonedRow, motherDiv.children[0]);
}
return;
}
function showError() {
var err = document.getElementById("err").innerHTML = "There was an error."
}
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<div id="motherDiv">
<!-- mother div -->
<div class="row" id="statsample">
<div class=" input-field col s3 #fffde7 yellow lighten-5">
<h6 id="statName" class="statClass"></h6>
</div>
<div class="input-field col s3">
<select class="icons browser-default" id="weeksSel4">
<option value="" disabled selected>Неделя</option>
</select>
</div>
<div class="input-field col s2">
<input id="numbers" type="text" class="validate">
<label for="numbers">Значение</label>
</div>
<div class="input-field col s1.5">
<select class="icons browser-default" id="measure">
<option value="" disabled selected>Ед. изм:</option>
<option value="">шт.</option>
<option value="">%</option>
<option value="">$</option>
<option value="">руб.</option>
<option value="">грн.</option>
</select>
</div>
<div class="input-field col s2.5">
<a class="waves-effect waves-light btn-small #039be5 light-blue darken-1" style="float: right;" id="btn1row"><i class="material-icons right">send</i>Ввести</a>
</div>
</div>
<!-- row end -->
</div>
<!-- mother div end-->
<div id="err"> </div>
解决方案
我建议使用数组的第一个元素填充“主”div,并且克隆从索引 1 开始迭代数组。我们需要对您的processStats(stats)
函数进行一些根本性的更改。首先填充主人:
var firstStat = document.getElementById("statName").innerHTML = stats.statNumbers[0] + ". " + stats.statStats[0];
以下两行未触及
var motherDiv = document.getElementById("motherDiv")
var statRow = document.getElementById("statsample");
将 for 循环更改为从 1 开始
for (var i = 1; i < stats.statStats.length; i++) {
}
现在 for 循环本身需要一些更改。这三行没问题
var statName = stats.statStats[i];
var statNumber = stats.statNumbers[i];
var clonedRow = statRow.cloneNode(true);
我不明白的是以下
var clonedStatID = motherDiv.getElementsByClassName("statClass")[0].id = "statName" + statNumber
我知道您想为新克隆的 div 子statClass提供一个带有序号的唯一 id,但是对于 for 循环的每次迭代,这都会为列表中的第一个元素提供 id。上面你已经有一个变量,它包含对克隆的 div clonedRow的引用,你也可以使用它来访问它的子项。
所以摆脱这条线并使用它:
clonedRow.getElementsByTagName("h6")[0].innerHTML = statNumber + ". " + statName;
现在只需将 div 附加到父级
motherDiv.appendChild(clonedRow);
这是一个工作示例 - 只需单击“运行代码片段”即可查看它的实际效果:
//my google app backend function with data
var numbers = [1, 2, 3]
var stats = ["Валовый доход", "Кол-во клиентов", "Кол-во размещенной рекламы"]
var stats = {
statNumbers: numbers,
statStats: stats
}
function processStats(stats) {
//name first statistic with the last number
var firstStat = document.getElementById("statName").innerHTML = stats.statNumbers[0] + ". " + stats.statStats[0];
//mother div
var motherDiv = document.getElementById("motherDiv")
//sample row to copy
var statRow = document.getElementById("statsample");
//loop stat names
for (var i = 1; i < stats.statStats.length; i++) {
var statName = stats.statStats[i];
var statNumber = stats.statNumbers[i];
var clonedRow = statRow.cloneNode(true);
var rowId = clonedRow.id = "statsample" + i;
clonedRow.getElementsByTagName("h6")[0].innerHTML = statNumber + ". " + statName;
var err = document.getElementById("err").innerHTML = motherDiv.children.length
motherDiv.appendChild(clonedRow);
}
return;
}
function showError() {
var err = document.getElementById("err").innerHTML = "There was an error."
}
processStats(stats);
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<div id="motherDiv">
<!-- mother div -->
<div class="row" id="statsample">
<div class=" input-field col s3 #fffde7 yellow lighten-5">
<h6 id="statName" class="statClass"></h6>
</div>
<div class="input-field col s3">
<select class="icons browser-default" id="weeksSel4">
<option value="" disabled selected>Неделя</option>
</select>
</div>
<div class="input-field col s2">
<input id="numbers" type="text" class="validate">
<label for="numbers">Значение</label>
</div>
<div class="input-field col s1.5">
<select class="icons browser-default" id="measure">
<option value="" disabled selected>Ед. изм:</option>
<option value="">шт.</option>
<option value="">%</option>
<option value="">$</option>
<option value="">руб.</option>
<option value="">грн.</option>
</select>
</div>
<div class="input-field col s2.5">
<a class="waves-effect waves-light btn-small #039be5 light-blue darken-1" style="float: right;" id="btn1row"><i class="material-icons right">send</i>Ввести</a>
</div>
</div>
<!-- row end -->
</div>
<!-- mother div end-->
<div id="err"> </div>
推荐阅读
- c# - 如何将 IEnumerable 转换为字符串以将其放入 c# 中的消息框中?
- python - 如何将 Python 变量输入到 AWS Lambda 中的一段 xml 代码中?
- java - 无法使用 JWT 将文件上传到盒子 - curl: (26) 创建表单数据失败
- php - 正则表达式捕获任何内容和任何空格或换行符
- c - 用gcc修改补丁认证程序
- c# - 如何使用 Winium Desktop c# 复制、粘贴、删除文件或文档
- laravel - 个人访问令牌 - Laravel
- python - TensorFlow 中 session.run() 执行时间增加
- r - 在一个 ggplot 图中使用不同长度的刻度
- javascript - 如何避免在javascript中等待地狱