You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium调用dragAndDrop无法触发onDragEnter事件问题问询

Selenium触发.onDragEnter拖拽事件失效问题

要触发.onDragEnter函数,在HTML5拖拽场景下使用Selenium原生API会出现失效问题。
你当前使用的实现代码如下:

// 初始化
// 打开页面,等待加载完成
const actions = await driver.actions();
const da1 = await driver.findElement(By.css('#todrag > span'));
const da2 = await driver.findElement(By.css('#mydropzone'));
await actions.dragAndDrop(da1, da2).perform();

.dragAndDrop()方法运行无效,分步实现也存在相同问题:

await actions.move({origin: da1}).press().move({origin: da2}).release().perform();

异常表现

  • 该问题属于Selenium原生actions API未修复的已知Bug
  • .perform()执行后点击鼠标左键偶发卡顿,真实鼠标指针上会生成[Draggable 1]的拖拽对象

已有疑问回复

cruisepandey 提问:你确定没有漏掉.build.perform()调用吗?
实测各写法报错如下:

.build.perform(); 报错:TypeError: Cannot read property 'perform' of undefined
.build().perform(); 报错:TypeError: actions.dragAndDrop(...).build is not a function
.build.perform(); 报错:TypeError: Cannot read property 'perform' of undefined
.build().perform(); 报错:TypeError: actions.move(...).press(...).move(...).release(...).build is not a function
解决方案

该问题由Selenium原生actions API对HTML5拖拽事件的兼容性缺陷导致,可通过注入JavaScript模拟完整拖拽事件流解决,实现代码如下:

// 封装HTML5拖拽通用方法
async function html5DragAndDrop(sourceEl, targetEl) {
  const dragAndDropScript = `
    function createEvent(type) {
      const event = document.createEvent("CustomEvent");
      event.initCustomEvent(type, true, true, null);
      event.dataTransfer = {
        data: {},
        setData: (key, value) => this.data[key] = value,
        getData: key => this.data[key]
      };
      return event;
    }
    function dispatchEvent(el, event, transferData) {
      if (transferData) event.dataTransfer = transferData;
      el.dispatchEvent ? el.dispatchEvent(event) : el.fireEvent("on" + event.type, event);
    }
    const source = arguments[0], target = arguments[1];
    const dragStart = createEvent("dragstart");
    dispatchEvent(source, dragStart);
    dispatchEvent(target, createEvent("dragenter"), dragStart.dataTransfer);
    dispatchEvent(target, createEvent("dragover"), dragStart.dataTransfer);
    dispatchEvent(target, createEvent("drop"), dragStart.dataTransfer);
    dispatchEvent(source, createEvent("dragend"), dragStart.dataTransfer);
  `;
  await driver.executeScript(dragAndDropScript, sourceEl, targetEl);
}

// 调用方法
const da1 = await driver.findElement(By.css('#todrag > span'));
const da2 = await driver.findElement(By.css('#mydropzone'));
await html5DragAndDrop(da1, da2);

方案说明

  • 直接在浏览器内核层面模拟完整的HTML5拖拽事件流,包含dragstart、dragenter、dragover、drop、dragend全节点事件触发,可正常命中.onDragEnter回调
  • 完全绕过Selenium原生actions API的已知拖拽缺陷,兼容性覆盖所有支持HTML5标准的拖拽场景
  • 不需要修改原有元素定位逻辑,直接传入已获取的源元素和目标元素即可调用

内容的提问来源于stack exchange,提问作者Vadim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 08:48:03