循环超时更改图标
Changing icons with timeout in a loop
我有以下代码循环遍历 table 中的每条记录并将保存图标设置为复选标记。
2 秒后它应该变回保存图标。除了它没有。
我对其他按钮也使用了完全相同的方法,并且有效。所以我怀疑它与循环遍历每条记录的速度有关。虽然 setTimeout 应该是异步的...
有更好的方法吗?每个按钮都应该单独行动。我的最后一招是编写一个函数来更改页面上的所有图标,但我不想这样做。
const iconToggle = () => {
const isCheckIcon = btn.firstElementChild.classList.contains('fa-check');
if (isCheckIcon) {
btn.innerHTML = '<i class="fa fa-save fa-2x"></i>';
} else {
btn.innerHTML = '<i class="fa fa-check fa-2x"></i>';
}
}
for (row = 0; row < table.rows.length; row++) {
currentRow = table.rows.item(row);
...
returncode = save_row();
btn = currentRow.getElementsByClassName('record-save')[0].firstElementChild;
if (returncode == 0) {
iconToggle();
setTimeout(iconToggle, 2000);
}
}
编辑:
$('.table-save-all').on('click', 'i', function() {
var table = document.getElementById('edit_history_table_body');
const iconToggle = (abtn, state) => {
if (state == "save") {
abtn.innerHTML = '<i class="fa fa-save fa-2x"></i>';
} else if (state == "check") {
abtn.innerHTML = '<i class="fa fa-check fa-2x"></i>';
}
}
var currentRow, key, TotalNoBreakDec, OvertimeDec, TotalDec, StartDec, HourSchedule, returncode, btn;
// loop through each row of the table.
for (row = 0; row < table.rows.length; row++) {
currentRow = table.rows.item(row);
...
returncode = save_row();
btn = currentRow.getElementsByClassName('record-save')[0].firstElementChild;
if (returncode == 0) {
iconToggle(btn, "check");
setTimeout(() => { iconToggle(btn, "save") }, 2000);
}
}
btn = document.getElementsByClassName('table-save-all')[0].firstElementChild;
iconToggle(btn, "check");
setTimeout(() => { iconToggle(btn, "save") }, 2000);
});
您应该将要更改的 btn
作为参数传递给 iconToggle()
方法。目前,您的循环抛出所有按钮并重新分配——看似全局的——btn
变量。因此,一旦触发重置图标的超时,btn
可能会分配给您的按钮的最后一个,并且在超时中多次调用 iconToggle
只会切换此按钮。
此外,我建议将所需的状态传递到您的 iconToggle
方法中,以便它始终清楚,正在发生什么变化,并且 iconToggle
的错误调用不会以不受欢迎的方式更新您的界面。
const iconToggle = (abtn, state) => {
if (state == "save") {
abtn.innerHTML = '<i class="fa fa-save fa-2x"></i>';
} else if (state == "check") {
abtn.innerHTML = '<i class="fa fa-check fa-2x"></i>';
}
}
for (row = 0; row < table.rows.length; row++) {
currentRow = table.rows.item(row);
...
returncode = save_row();
const btn = currentRow.getElementsByClassName('record-save')[0].firstElementChild;
if (returncode == 0) {
iconToggle(btn, "save");
setTimeout(() => {iconToggle(btn, "check")}, 2000);
}
}
编辑关于您的评论和您答案中的更新代码:
将你的代码与我的进行比较。你会看到我有
const btn = ...
在循环体内,而你只有
btn = ...
因此,这行代码
setTimeout(() => {iconToggle(btn, "check")}, 2000);
在您的版本中,将引用在循环体外部某处声明的 btn
变量(您未显示位置)。但是当你在循环迭代期间和循环之后不断更新这个 btn
变量时,btn
最终指向这个元素
btn = document.getElementsByClassName('table-save-all')[0].firstElementChild;
这就是元素,超时回调中的所有 iconToggles
都适用。
在循环体内声明 btn
变量——或者在 if
的体内更好——它会起作用。
if (returncode == 0) {
const btn = currentRow.getElementsByClassName('record-save')[0].firstElementChild;
iconToggle(btn, "save");
setTimeout(() => {iconToggle(btn, "check")}, 2000);
}
所有变量都应该在尽可能小的范围内定义,以防止此类错误。
我有以下代码循环遍历 table 中的每条记录并将保存图标设置为复选标记。
2 秒后它应该变回保存图标。除了它没有。
我对其他按钮也使用了完全相同的方法,并且有效。所以我怀疑它与循环遍历每条记录的速度有关。虽然 setTimeout 应该是异步的...
有更好的方法吗?每个按钮都应该单独行动。我的最后一招是编写一个函数来更改页面上的所有图标,但我不想这样做。
const iconToggle = () => {
const isCheckIcon = btn.firstElementChild.classList.contains('fa-check');
if (isCheckIcon) {
btn.innerHTML = '<i class="fa fa-save fa-2x"></i>';
} else {
btn.innerHTML = '<i class="fa fa-check fa-2x"></i>';
}
}
for (row = 0; row < table.rows.length; row++) {
currentRow = table.rows.item(row);
...
returncode = save_row();
btn = currentRow.getElementsByClassName('record-save')[0].firstElementChild;
if (returncode == 0) {
iconToggle();
setTimeout(iconToggle, 2000);
}
}
编辑:
$('.table-save-all').on('click', 'i', function() {
var table = document.getElementById('edit_history_table_body');
const iconToggle = (abtn, state) => {
if (state == "save") {
abtn.innerHTML = '<i class="fa fa-save fa-2x"></i>';
} else if (state == "check") {
abtn.innerHTML = '<i class="fa fa-check fa-2x"></i>';
}
}
var currentRow, key, TotalNoBreakDec, OvertimeDec, TotalDec, StartDec, HourSchedule, returncode, btn;
// loop through each row of the table.
for (row = 0; row < table.rows.length; row++) {
currentRow = table.rows.item(row);
...
returncode = save_row();
btn = currentRow.getElementsByClassName('record-save')[0].firstElementChild;
if (returncode == 0) {
iconToggle(btn, "check");
setTimeout(() => { iconToggle(btn, "save") }, 2000);
}
}
btn = document.getElementsByClassName('table-save-all')[0].firstElementChild;
iconToggle(btn, "check");
setTimeout(() => { iconToggle(btn, "save") }, 2000);
});
您应该将要更改的 btn
作为参数传递给 iconToggle()
方法。目前,您的循环抛出所有按钮并重新分配——看似全局的——btn
变量。因此,一旦触发重置图标的超时,btn
可能会分配给您的按钮的最后一个,并且在超时中多次调用 iconToggle
只会切换此按钮。
此外,我建议将所需的状态传递到您的 iconToggle
方法中,以便它始终清楚,正在发生什么变化,并且 iconToggle
的错误调用不会以不受欢迎的方式更新您的界面。
const iconToggle = (abtn, state) => {
if (state == "save") {
abtn.innerHTML = '<i class="fa fa-save fa-2x"></i>';
} else if (state == "check") {
abtn.innerHTML = '<i class="fa fa-check fa-2x"></i>';
}
}
for (row = 0; row < table.rows.length; row++) {
currentRow = table.rows.item(row);
...
returncode = save_row();
const btn = currentRow.getElementsByClassName('record-save')[0].firstElementChild;
if (returncode == 0) {
iconToggle(btn, "save");
setTimeout(() => {iconToggle(btn, "check")}, 2000);
}
}
编辑关于您的评论和您答案中的更新代码:
将你的代码与我的进行比较。你会看到我有
const btn = ...
在循环体内,而你只有
btn = ...
因此,这行代码
setTimeout(() => {iconToggle(btn, "check")}, 2000);
在您的版本中,将引用在循环体外部某处声明的 btn
变量(您未显示位置)。但是当你在循环迭代期间和循环之后不断更新这个 btn
变量时,btn
最终指向这个元素
btn = document.getElementsByClassName('table-save-all')[0].firstElementChild;
这就是元素,超时回调中的所有 iconToggles
都适用。
在循环体内声明 btn
变量——或者在 if
的体内更好——它会起作用。
if (returncode == 0) {
const btn = currentRow.getElementsByClassName('record-save')[0].firstElementChild;
iconToggle(btn, "save");
setTimeout(() => {iconToggle(btn, "check")}, 2000);
}
所有变量都应该在尽可能小的范围内定义,以防止此类错误。