拖拽时模拟Escape键盘事件无法触发的问题求助
模拟Escape终止拖拽失效的原因及解决办法
失效原因
isTrusted属性无法通过脚本篡改:浏览器仅将原生用户交互(真实按键、点击等)触发的事件标记为可信(isTrusted: true),通过脚本创建的KeyboardEvent无法设置该属性为true,此类非可信事件会被浏览器忽略,不会触发终止拖拽的原生行为。- 事件派发对象错误:真实的Escape按键事件作用于
document或window层面,而非拖拽元素boxA,即便事件可信,派发给拖拽元素也无法被识别为终止拖拽的信号。
最优解决方案:直接触发dragend事件
不需要模拟按键,直接利用拖拽API的原生dragend事件终止拖拽,这是浏览器认可的标准方式。修改后的完整代码如下:
<html> <head> <style type="text/css"> #boxA, #boxB { float:left;padding:10px;margin:10px;-moz-user-select:none; } #boxA { background-color: #6633FF; width:75px; height:75px; } #boxB { background-color: #FF6699; width:150px; height:150px; } </style> </head> <body> <center> <div id = "main"> <h2>cancel drag test</h2> <div id="boxA" draggable="true" ondragstart="return dragStart(event)"> <p>Drag Me</p> </div> <div id="boxB" ondragenter="return dragEnter(event)" ondrop="return dragDrop(event)" >Stop Dragging here</div> </div> </center> </body> <script> function dragStart(ev) { ev.dataTransfer.effectAllowed='move'; ev.dataTransfer.setData("Text", ev.target.getAttribute('id')); ev.dataTransfer.setDragImage(ev.target,0,0); return true; } function dragEnter(ev) { ev.preventDefault(); // 创建并触发dragend事件终止拖拽 const dragEndEvent = new Event('dragend', { bubbles: true, cancelable: true }); document.getElementById('boxA').dispatchEvent(dragEndEvent); return true; } function dragOver(ev) { return false; } function dragDrop(ev) { var src = ev.dataTransfer.getData("Text"); ev.target.appendChild(document.getElementById(src)); ev.stopPropagation(); return false; } </script> </html>
若坚持模拟Escape键(不推荐)
需修正两个问题,但仍无法保证浏览器响应:
- 移除
isTrusted: true的设置(脚本无法修改该属性) - 将事件派发给
document而非拖拽元素
修改后的simEscape函数示例:
function simEscape(){ console.log("SimEscapedStarted"); const event = new KeyboardEvent('keydown', { charCode: 0, key: "Escape", code: "Escape", which: 27, keyCode: 27, bubbles: true }); document.dispatchEvent(event); }
内容的提问来源于stack exchange,提问作者JobouJP
相关产品推荐
相关产品推荐

