p:dialog内嵌p:textEditor按backspace键无法删除文本问题求助
异常根因分析
该问题是PrimeFaces组件栈的已知兼容问题,核心原因是键盘事件在层级组件间冒泡被拦截,对应具体诱因如下:
- p:dialog默认自带
tabindex="-1"属性,用于实现焦点控制逻辑,该属性会压低内部子组件的键盘事件优先级,p:textEditor底层基于Quill编辑器实现,backspace删除普通文本的事件在冒泡到dialog层时被默认拦截,仅换行对应的块级删除逻辑未被拦截,完全符合你观察到的“仅能删除换行不能删除普通文本”的表现 - 你配置的
<p:hotkey>未指定作用范围,默认全局监听键盘事件,部分PrimeFaces版本的hotkey逻辑存在误拦截backspace事件的缺陷 - 你的弹窗调用代码存在笔误:打开弹窗的commandButton的
onsuccess属性调用的PF('frmPostit').show()是错误写法,frmPostit是表单ID,dialog的widgetVar为dlPostit,该笔误会导致组件初始化时序异常,进一步影响textEditor的事件绑定效果
修复方案
按顺序执行以下修改即可解决问题:
- 修复弹窗调用笔误,将打开按钮的onsuccess逻辑修正为正确的dialog组件调用:
<p:commandButton value="openPostit" widgetVar="openPostit" onsuccess="PF('dlPostit').show();" />
- 给hotkey指定dialog为作用范围,避免全局事件监听误拦截:
<p:hotkey bind="esc" handler="PF('dlgPostit').hide();" scope="dlgPostit" />
- 在dialog的onShow回调中移除默认tabindex属性,取消dialog层的键盘事件拦截:
<p:dialog id="dlgPostit" widgetVar="dlPostit" dynamic="false" modal="false" fitViewport="false" resizable="true" closable="true" onHide="$('#frmPostit\\:quit').click();" onShow="$(this.jqId).removeAttr('tabindex'); $(document).off('keydown.dialog');" >
- 如使用PrimeFaces 7.0及更早版本,可额外给textEditor添加backspace事件放行逻辑,阻止事件冒泡到上层组件:
<p:textEditor id="textPostit" widgetVar="textPostit" value="#{backingbean.text}" style="vertical-align: top; height: 450px"> <p:ajax event="keydown" onstart="if (event.which == 8) event.stopPropagation();" /> </p:textEditor>
内容的提问来源于stack exchange,提问作者Christian O.
相关产品推荐
相关产品推荐

