移动端Backspace功能异常:双退格删除逻辑失效问题咨询
核心问题定位
你的双退格删除逻辑在移动端失效,主要是事件重复绑定、移动端键盘事件兼容性以及全局DOM查询不可靠这三个原因导致的,具体问题点和修改方案如下:
1. 重复绑定事件导致逻辑混乱
每次调用createAdditionalDiv时,你都通过$(".mainBox").on("keydown", ...)给所有.mainBox元素绑定新的keydown监听,这会导致同一个元素被绑定多次事件。在移动端,多次事件触发会干扰正常逻辑,比如重复插入deletionMarker或重复执行删除/标记操作,最终出现复制span的异常。
修改方案:
只给当前新创建的innerBox绑定事件,而非全局绑定:
// 替换原来的 $(".mainBox").on(...) innerBox.addEventListener('keydown', function(event) { // 原逻辑代码 });
2. 移动端键盘事件event.key兼容性问题
部分移动端浏览器的退格键event.key值可能不是标准的'Backspace'(比如小写'backspace'或其他值),导致条件判断失效,无法触发自定义逻辑,反而执行了浏览器默认的退格行为。
修改方案:
同时通过event.keyCode(退格键对应8,删除键对应46)判断,提升兼容性:
// 替换原条件判断 const isBackspace = event.key === 'Backspace' || event.keyCode === 8; const isDelete = event.key === 'Delete' || event.keyCode === 46; if (isBackspace || isDelete) { // 原逻辑代码 }
3. 全局DOM查询导致元素选择错误
你使用document.querySelector('#deletionMarker')和document.querySelector('.toDelete')进行全局查询,当页面存在多个.mainBox时,可能会选中其他元素的marker或标记,导致逻辑执行错误,尤其是在重复绑定事件后,这种问题会更明显。
修改方案:
基于当前触发事件的元素(this)来查找相邻元素,避免全局查询:
// 插入marker后,在当前元素内查找 putDataToCarentPos(deletionMarker.outerHTML.toString(), false); let deletionMarkerEl = this.querySelector('#deletionMarker'); if (!deletionMarkerEl) return; let previousTag = deletionMarkerEl.previousSibling; while (previousTag && !previousTag.textContent) { previousTag = previousTag.previousSibling; }
4. 事件阻止时机过晚
原代码中event.preventDefault()是在判断previousTag后才调用,移动端浏览器可能已经先执行了默认的退格行为(比如删除字符),导致自定义逻辑被干扰。
修改方案:
在事件触发后立即调用event.preventDefault(),阻止默认行为:
innerBox.addEventListener('keydown', function(event) { const isBackspace = event.key === 'Backspace' || event.keyCode === 8; const isDelete = event.key === 'Delete' || event.keyCode === 46; if (isBackspace || isDelete) { event.preventDefault(); // 提前阻止默认行为 // 原逻辑代码 } });
修改后的完整函数示例
function createAdditionalDiv() { let innerBox = document.createElement('div') innerBox.contentEditable = "true" innerBox.id = totalBoxes++; innerBox.className = "mainBox" let mainBox = document.getElementById('mainContainer') innerBox.addEventListener('keyup', checkTrigger) // 只给当前新创建的元素绑定keydown事件 innerBox.addEventListener('keydown', function(event) { // 兼容移动端键盘事件 const isBackspace = event.key === 'Backspace' || event.keyCode === 8; const isDelete = event.key === 'Delete' || event.keyCode === 46; if (isBackspace || isDelete) { event.preventDefault(); // 提前阻止默认行为 let deletionMarker = document.createElement('span'); deletionMarker.hidden = true deletionMarker.id = "deletionMarker" putDataToCarentPos(deletionMarker.outerHTML.toString(), false); // 在当前元素内查找marker,避免全局查询 let deletionMarkerEl = this.querySelector('#deletionMarker'); if (!deletionMarkerEl) return; let previousTag = deletionMarkerEl.previousSibling while (previousTag && !previousTag.textContent) { previousTag = previousTag.previousSibling } if (previousTag && previousTag.tagName === "SPAN") { if (previousTag.className === "toDelete") { deletionMarkerEl.remove(); previousTag.remove() } else { deletionMarkerEl.remove(); previousTag.className = 'toDelete'; event.stopImmediatePropagation(); } } else { deletionMarkerEl.remove(); } } }); mainBox.appendChild(innerBox); }
内容的提问来源于stack exchange,提问作者Anirudh S

