提问人:Zearin 提问时间:10/4/2023 更新时间:10/5/2023 访问量:89
Web 组件中的拖放 API(点亮)
Drag-and-Drop API in Web Components (Lit)
问:
背景信息
我设法使用普通元素和事件侦听器学习了拖放 API 的基础知识。但我想看看我是否可以使用 Web 组件重新创建相同的功能。
在“vanilla”Web Component中重新创建拖放功能时遇到了一些麻烦后,我决定尝试一下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 有关。
我只知道我能够使用完整的 API 使用标准 HTML 元素和一些函数来实现。一旦我尝试使用 Web 组件,我就不能再进一步了。dragstart
为什么?
答:
1赞
Danny '365CSI' Engelman
10/5/2023
#1
你的 Lit 代码所做的只是为你创建 shadowDOM。
这是下面本机 Web 组件中的 1 行。
注意:自己做拖放是一件痛苦的事情,需要几天时间才能让它按照你想要的方式工作。一旦你为一个应用程序完成了它,你就可以在每个应用程序中做到这一点。
我不做 Lit。如果此代码在从 ...那么我还有一个不使用 Lit 的理由。LitElement
最大的绊脚石:
- 试图处理太多事件,这就是为什么下面的限制为 1 秒。
也许使用和dragover
dragenter
dragleave
dataTransfer
恕我直言,这是一种痛苦。
我通常存储有关在 parentNode 上拖动的内容的信息。想<chess-board>
- 别忘了 Event 及其所有用于触摸屏的表亲
touchmove
- shadowDOM 中的 DOM 节点过多;下面的代码有一个...
<style>
- 不使用系统。每个 JS 对象都可以处理一个默认函数/方法
handleEvent
- 注意光标/抓取位置如何触发事件
dragover
<div class="board">
<drag-box color="red"></drag-box>
<drag-box color="yellow"></drag-box>
<drag-box color="blue"></drag-box>
</div>
<script>
console.clear();
customElements.define('drag-box', class extends HTMLElement {
constructor() {
super()
.attachShadow({mode:'open'})
.innerHTML = `<style>
:host {
display: inline-block;
width: 100px;
height: 100px;
cursor: grab;
background: var(--color)
}
</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;
let dragcolor = this.board.dragging.color;
console.log(dragcolor,'dragover', this.color);
setTimeout(() => this.updatedragover = true, 1000);
}
}
dragstart(e) {
console.log(e.type, this.color);
this.style.opacity = 0.3;
this.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);
}
get board(){
return this.closest(".board");
}
})
</script>
评论