Google Sheets闪烁效果重置编辑单元格值(疑似异步问题)
问题分析
你的代码出现值被重置的核心原因是:闪烁循环会先对所有标记为闪烁的行设置文本,再尝试覆盖已编辑的值,这会导致短暂的文本闪烁,甚至在脚本执行时序冲突时直接覆盖用户输入;另外editedValues的逻辑冗余,反而加剧了时序问题引发的冲突。
解决方案
修改思路:一旦用户编辑某行,立即标记该行停止闪烁,且闪烁循环完全跳过对该行的任何修改操作,直接保留用户输入的值和背景色。
修改后的代码:
var blinkingRows = {}; var isBlinking = false; var targetSheetName = "sheet3"; function onOpen() { startBlinking(); } function onEdit(e) { var sheet = e.source.getActiveSheet(); if (sheet.getName() !== targetSheetName) return; var cell = e.range; var row = cell.getRow(); if (cell.getColumn() === 2 && row <= 100) { // 标记该行停止闪烁 blinkingRows[row] = false; // 强制设置为白色背景,确保停止闪烁后的状态 cell.setBackground("white"); SpreadsheetApp.flush(); } } function startBlinking() { var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(targetSheetName); if (!sheet) return; // 初始化所有行为闪烁状态 for (var row = 1; row <= 100; row++) { blinkingRows[row] = true; } if (!isBlinking) { isBlinking = true; blinkLoop(); } } function blinkLoop() { var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(targetSheetName); if (!sheet) { isBlinking = false; return; } var colors = ["purple", "white"]; var texts = ["om", ""]; var i = 0; function innerLoop() { if (!isBlinking) return; for (var row = 1; row <= 100; row++) { // 仅处理标记为闪烁的行,已编辑行直接跳过 if (blinkingRows[row] !== true) continue; var cell = sheet.getRange(row, 2); cell.setValue(texts[i % 2]); cell.setBackground(colors[i % 2]); } SpreadsheetApp.flush(); i++; Utilities.sleep(1000); // 用setTimeout替代递归,避免长时间运行触发递归深度超限 setTimeout(innerLoop, 0); } innerLoop(); }
关键修改点
- 移除冗余的
editedValues变量,从根源上消除时序冲突 - 在闪烁循环中通过
continue跳过所有已标记停止闪烁的行,完全不修改这些单元格,确保用户输入值不会被覆盖 - 将递归调用替换为
setTimeout,避免脚本长时间运行后触发递归深度超限错误
内容的提问来源于stack exchange,提问作者R S
相关产品推荐
相关产品推荐

