Firefox下Shiny应用输入矩阵回车键无法保存新值问题求助
Shiny输入矩阵Firefox回车不保存值的问题及修复
问题现象
在Firefox浏览器中运行Shiny应用时,应用内的输入矩阵存在异常:
- 修改首个单元格的值(例如从80改为100)后按下回车键,值会恢复为原始的80,新值无法保存
- 但修改后点击下方其他单元格,新值(100)能够正常保存到矩阵中
排查到的keydown事件代码
通过Firefox开发者工具检查器,获取到该单元格绑定的keydown事件处理代码:
function(e) { if ( // no bubbling, should always fire. // this is just a safety net in case event.timeStamp is unreliable in // certain weird environments... e.target === e.currentTarget || // event is fired after handler attachment e.timeStamp >= attachedTimestamp || // bail for environments that have buggy event.timeStamp implementations // #9462 iOS 9 bug: event.timeStamp is 0 after history.pushState // #9681 QtWebEngine event.timeStamp is negative value e.timeStamp <= 0 || // #9448 bail if event is fired in another document in a multi-page // electron/nw.js app, since event.timeStamp will be using a different // starting reference e.target.ownerDocument !== document ) { return original.apply(this, arguments) } }
问题原因
这段代码是Shiny内部的事件包装逻辑,并非直接返回旧值。问题根源在于Firefox中按下回车键时,e.timeStamp的数值可能小于attachedTimestamp,导致条件判断不通过,没有执行原本负责保存输入值的original处理函数。
而点击其他单元格时,触发的是focusout等其他事件,绕开了这个keydown事件的判断逻辑,因此新值能正常保存。
修复方案
方案1:调整事件判断逻辑(修改或覆盖Shiny源码)
如果可以修改这段事件处理代码,添加对回车键的特殊判断,确保回车时强制执行保存逻辑:
function(e) { // 新增:捕获回车键,直接执行原处理函数 if (e.key === 'Enter') { return original.apply(this, arguments); } if ( e.target === e.currentTarget || e.timeStamp >= attachedTimestamp || e.timeStamp <= 0 || e.target.ownerDocument !== document ) { return original.apply(this, arguments) } }
方案2:在Shiny应用中添加自定义回车事件处理
无需修改源码,在Shiny应用的UI部分插入自定义JavaScript,监听矩阵单元格的回车事件,手动触发值更新:
tags$script(HTML(" // 全局监听keydown事件,捕获输入矩阵单元格的回车操作 document.addEventListener('keydown', function(e) { if (e.key === 'Enter' && e.target.classList.contains('shiny-input-matrix-cell')) { // 手动触发change事件,让Shiny保存新值 e.target.dispatchEvent(new Event('change')); } }); "))
将这段代码添加到你的Shiny UI的fluidPage或tags$body内部即可,它会强制触发输入值的变更逻辑,解决Firefox中的回车保存异常问题。
内容的提问来源于stack exchange,提问作者Sebastian
相关产品推荐
相关产品推荐

