contenteditable div删字符即删整词功能移动端Chrome失效如何解决
问题说明
- 目标效果:设置了
contenteditable属性的编辑区内,删除Hello/World任意单词的单个字符时,直接删除对应整个单词 - 兼容问题:原有实现仅能在桌面端Chrome 102正式版(64位)运行,Android端同版本Chrome完全失效
- 问题根因:移动端Chrome环境下,软键盘触发的按键事件中
e.key返回值为Unidentified,无法通过该属性识别退格、删除按键,原有判断逻辑完全不触发
原有实现代码
JavaScript 逻辑
$('#div-editor').keyup(function(e) { var $target = $(document.getSelection().anchorNode).closest(".word"); $(".word").each(function(){ if (["Delete", "Backspace"].includes(e.key)) { $target.remove(); e.preventDefault(); } }); });
HTML 结构
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <div contenteditable="true" id = "div-editor" > <span class="word">Hello</span> <span class="word">World</span> </div>
兼容移动端的实现方案
移动端软键盘的按键事件本身兼容性极差,不仅是Chrome,绝大多数移动端浏览器对软键盘按键的keyCode、key属性返回值都不统一,部分第三方输入法甚至不会触发标准的keydown/keyup事件,靠识别按键值判断删除操作的方案本身就不适配移动端。
更稳妥的实现逻辑是绕开按键识别,通过内容长度变化判断是否发生删除操作,具体实现代码如下:
// 初始化记录编辑区内容长度 let lastContentLen = $('#div-editor').text().length; $('#div-editor').on('input keydown', function(e) { const currentLen = $(this).text().length; // 兼容两种删除判定:桌面端按键识别、全端通用的内容长度变短判定 const isDelete = currentLen < lastContentLen || (e.key && ['Backspace', 'Delete'].includes(e.key)); if (isDelete) { const selection = document.getSelection(); if (!selection.rangeCount) { lastContentLen = currentLen; return; } // 定位当前选区所在的单词节点 const $currentWord = $(selection.anchorNode).closest('.word'); if ($currentWord.length) { e.preventDefault(); $currentWord.remove(); } } // 更新记录的内容长度,供下次判断使用 lastContentLen = $(this).text().length; });
方案说明
- 直接绕开移动端
e.key返回Unidentified的坑,不依赖按键值做判断,不管是软键盘退格、实体键盘删字、还是输入法自动裁剪文本,只要内容长度变短就能识别到删除操作 - 保留了桌面端的按键判断逻辑,桌面端操作不会有延迟
- 后续要加新的整词删除节点,直接给对应元素加
.word类就行,不用改逻辑
内容的提问来源于stack exchange,提问作者programmer777
相关产品推荐
相关产品推荐

