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

Lit Web Components中Drag-and-Drop API仅触发dragstart事件问题

问题原因与解决方案

问题核心出在dragstart事件处理函数中的evt.preventDefault()调用——拖拽API规定,dragstart事件不能被阻止默认行为,一旦执行这个方法,浏览器会直接取消整个拖拽操作的初始化流程,后续的drag(拖拽过程中持续触发)和dragend(拖拽结束时触发)事件自然不会被触发。

你之前用普通元素能正常工作,大概率是当时的代码没有在dragstart中调用preventDefault(),这个问题和Web Components/Lit的Shadow DOM无关,纯粹是拖拽API的使用错误。

修改后的代码

只需移除onDragStart里的evt.preventDefault()即可:

class LiDragdrop extends LitElement {

    static styles = css`
        :host   { display: block }
        :host b { display: inline-block }
    `

    constructor() {
        super()
    }

    connectedCallback() {
        super.connectedCallback()

        this.setAttribute('draggable', 'true')

        this.addEventListener('dragstart',  this.onDragStart, {passive: false})
        this.addEventListener('drag',       this.onDrag)
        this.addEventListener('dragend',    this.onDragEnd)
    }

    onDragStart(evt) {
        // 移除这行错误的阻止默认行为代码
        // evt.preventDefault()
        evt.dataTransfer.effectAllowed = 'move'
        evt.dataTransfer.setData('text/html', this.outerHTML)
        console.log(evt.type, `${evt.target.localName} (${evt.target.textContent})`, evt)
    }

    onDrag(evt) {
        console.log(evt.type, `${evt.target.localName} (${evt.target.textContent})`, evt)
        // drag事件无需阻止默认行为,不影响核心拖拽流程
    }

    onDragEnd(evt) {
        console.log(evt.type, evt.target.localName, evt)
    }

    render() {
        return html`<b>⠿</b><slot></slot>`
    }
}

customElements.define('li-dragdrop', LiDragdrop)

补充说明

  • 拖拽API中,仅在dragover、drop这类事件里阻止默认行为才有实际意义(比如允许元素被放置,需要阻止dragover的默认行为)。
  • dragstart的默认行为就是启动拖拽操作,阻止它等于直接取消整个拖拽动作,事件链会直接中断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 10:16:14