我成功地使用普通元素和事件监听器学习了拖放 API 的基础知识。但我想看看是否可以使用 Web 组件重新创建相同的功能。
在“普通”Web 组件中重新创建拖放功能时遇到一些麻烦后,我决定尝试一下 Lit(因为它建立在我喜欢的现有标准之上)。
使用准系统设置来学习。
就这么简单,控制台仅触发
dragstart
事件,但不触发 drag
或 dragend
事件。
这是课程:
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)
}
// fires repeatedly while dragging
onDrag(evt) {
evt.preventDefault()
console.log(evt.type, `${evt.target.localName} (${evt.target.textContent})`, evt)
}
// always fires, even for unsuccessful drops
onDragEnd(evt) {
console.log(evt.type, evt.target.localName, evt)
}
render() {
return html`<b>⠿</b><slot></slot>`
}
}
customElements.define('li-dragdrop', LiDragdrop)
除了最基本的 HTML 文档之外,这是我在
body
中拥有的所有内容:
<li-dragdrop>Item 1</li-dragdrop>
<li-dragdrop>Item 2</li-dragdrop>
我拖动元素。我看到
dragstart
已记录到控制台,但没有其他内容。
我不确定这是否与 Shadow DOM 事件或 Lit 有关。
我只知道我能够使用标准 HTML 元素和一些函数来使用完整的 API。一旦我尝试使用 Web 组件,我就无法获得比
dragstart
更进一步的结果。
为什么?
您的 Lit 代码所做的就是为您创建 ShadowDOM。
这是下面 native Web 组件中的 1 行。
注意:自己进行拖放是一件痛苦的事情,您需要几天时间才能让它按照您想要的方式工作。一旦您完成了一个应用程序的操作,您就可以在每个应用程序中执行此操作。
最大的旅行:
dragover
被限制为1秒。dragenter
和 dragleave
dataTransfer
恕我直言,这是一种痛苦。<chess-board>
touchmove
及其所有触摸屏的表兄弟<drag-box color="red"></drag-box>
<drag-box color="yellow"></drag-box>
<drag-box color="blue"></drag-box>
<script>
console.clear();
customElements.define('drag-box', class extends HTMLElement {
constructor() {
super()
.attachShadow({mode:'open'})
.innerHTML = `<style>:host {
display: inline-block;
background: var(--color); width: 100px; height: 100px;
cursor: grab
}</style>`;
this.updatedragover = true;
}
connectedCallback() {
this.color = this.color;
this.setAttribute("draggable", true);
// let JS default "handleEvent" on the class handle the event
this.addEventListener("dragstart", this);
this.addEventListener("dragend" , this);
this.addEventListener("dragover" , this);
}
handleEvent(e) {
if (this[e.type]) this[e.type](e); // exec method
}
dragover(e) {
if (this.updatedragover) { // only once a second
this.updatedragover = false;
console.log('dragover', this.color);
setTimeout(() => this.updatedragover = true, 1000);
}
}
dragstart(e) {
console.log(e.type, this.color);
this.style.opacity = 0.3;
// this.closestElement("chess-board").dragging = this
}
dragend(e) {
console.log(e.type, this.color);
this.style.opacity = 1;
}
get color() { return this.getAttribute("color") || "grey" }
set color(c) { this.style.setProperty("--color", c) }
})
</script>