我正在创建一个 Web 构建器,我使用 svelte 来促进 UI 的某些功能,但 Web 构建器本身几乎是纯 JavaScript。我创建了一个工具面板,其中包含按比例创建的不同可拖动元素,以便可以将它们拖放到画布上(它是一个 div,但出于结构目的,我将其称为画布)。然而,为了在画布中创建 html 元素,我正在考虑将标签名称作为文本传递,并让它在画布内创建该类型的新元素。
拖放正在工作,并且元素确实是可拖动的,但问题出在 ondragstart 属性上。我还尝试向元素添加事件侦听器,但这仍然不起作用。此操作包含三个主要组成部分。第一个工具面板如下。用户将在这里看到他的工具并能够将它们拖到画布中
<script lang="ts">
import { onMount } from "svelte";
import {define_default_styles, define_default_content} from "$lib/helpers/default_element_configurations";
let hidden:boolean = true
let element_declaration:string[] = ["div", "h1", "h2", "p", "form", "input", "button"]
let elements: (string | undefined)[] = [];
let element_panel:HTMLElement
onMount(()=>{
for(let element of element_declaration){
let newElement = document.createElement(element)
newElement.className="rounded p-2 border"
newElement.draggable=true
newElement.ondragstart=(event)=>{
console.log("dragstart event fired");
event.dataTransfer?.setData("text/plain", "div");
console.log("Data set: ", event.dataTransfer?.getData("text/plain"));
}
define_default_styles(newElement,element)
define_default_content(newElement,element)
elements.push(newElement.outerHTML)
}
})
</script>
<div class="flex items-center space-x-2 p-2 bg-gray-200">
<h1 class="text-blue-500 font-bold text-xl">Scripter Web-Builder</h1>
<button on:click={()=>{hidden=false}} class="bg-blue-500 text-white rounded text-center px-2 text-xl font-bold py-1 hover:bg-blue-700 active:bg-blue-900">+</button>
</div>
{#if !hidden}
<div bind:this={element_panel} class="absolute border-2 w-1/4 min-h-52 bg-gray-50 rounded shadow-md">
{#each elements as element}
<div class="p-2">{@html element}</div>
{/each}
</div>
{/if}
这是一个添加附加功能的辅助函数,这是我尝试添加事件侦听器的地方。我已经删除了代码中的事件侦听器,但为了说明性目的,我将再次添加它 `
export function define_default_content(node:HTMLElement, node_type:string){
switch(node_type){
case "div":
node.innerText="div"
node.addEventListener("dragstart" ,(event)=>{
console.log("dragstart event fired");
event.dataTransfer?.setData("text/plain", "div");
console.log("Data set: ", event.dataTransfer?.getData("text/plain"));
})
node.addEventListener("drop", (event)=>{event.stopPropagation()})
break;
最后,这就是画布,它确实像宣传的那样工作
<script lang="ts">
import {onMount} from "svelte"
let canvas:HTMLElement
onMount(()=>{
canvas.addEventListener("dragenter",(e)=>e.preventDefault())
canvas.addEventListener("dragover",(e)=>e.preventDefault())
canvas.addEventListener("drop",(e)=>console.log(e.dataTransfer?.getData("text/plain")))
})
</script>
<div bind:this={canvas}>
</div>