- 作者:老汪软件技巧
- 发表时间:2024-11-09 07:01
- 浏览量:
1.概述
拖拽式菜单在我们日常生活中十分常见,在餐厅点餐时很多点餐功能都使用到了这个拖拽式功能。下面我简单地利用HTML,CSS以及JS来实现这个功能。
2.目标
实现一个拖拽功能,允许用户从菜单中选择菜品和果品并将它们拖放到顾客的区域中,具备添加和删除的功能。
3.需求分析和实现3.1页面的布局
在实现拖拽功能之前,首先需要规划好页面简单的布局。由于要点餐,势必会有用户的点餐区(用来放置用户拖拽过来的菜品),而菜品也需要一个存放区域(用来放置可供用户选择的所有菜品),由于还要具备删除功能(使用拖拽进行删除),我们还要准备一个删除区域。所以布局上分成3块:
这里我采取的是使用一个表格进行区分,借助表格的分割线更加明确区域的分布(当然你也可以使用网格布局来实现这3个区域),代码如下:
<tr>
<th colspan="3"><strong>请将选择的菜品和果品拖拽至对应顾客下方区域strong>th>
tr>
<tr style="background-color: rgb(242, 242, 242);">
<td>顾客Atd>
<td>顾客Btd>
<td>顾客Ctd>
tr>
<tr>
<td class="A">td>
<td class="B">td>
<td class="C">td>
tr>
可选择的菜品和果品
删除
在这里需要注意的是,要对被拖拽元素设置 draggable="true"这个属性,允许该元素可以被拖动。这里的css样式可以根据的自己的喜好进行设计,根据这个布局,我得到如下图的一个布局:
3.2 拖拽事件
在实现拖拽功能之前,我们需要对拖拽事件有一个简单的了解。拖拽是分阶段和对象的。接下来我会列出来本文拖拽功能实现会用到的拖拽事件。
首先是针对被拖拽元素:
其实被拖拽元素还有一个dragend事件,但这个事件在元素被成功放置的时候会自动触发,如果不需要对被拖拽元素进行额外的操作,可以不写这个事件。
接下来是针对放置区域的拖拽事件:
简略讲解了一下有关拖拽事件的一些知识点,当然这并不是全部,这只是本文会使用到的拖拽事件,有兴趣的可以上网了解。
3.3 拖拽功能的实现
首先给每一个被拖拽元素添加拖拽事件,并且在添加事件的过程中传递被拖拽元素的id号(用于下面触发drop事件时在放置区域添加元素),代码如下:
const imgs = document.querySelectorAll("img")
for (let i = 0; i < imgs.length; i++) {
if (imgs[i].draggable) {
imgs[i].ondragstart = function (e) {
e.dataTransfer.setData("ID", i)
}
}
}
接下来,就是给放置区域设置相应的拖拽事件,这里有两个放置区域,一个是点餐区域,一个是删除区域。
分别给这两个区域设置dragenter,dragover以及drop事件,其中在dragenter和dragover事件中阻止放置区域默认事件的触发(以便支持拖拽);在drop事件中,获取到在dragstart中创术过来的有关被拖拽元素的id号,用于定位到要添加的元素。
给删除区域添加事件:
const del = document.querySelector(".del")
del.ondragenter = function (e) {
e.preventDefault()
}
del.ondragover = function (e) {
e.preventDefault();
}
del.ondrop = function (e) {
const a = e.dataTransfer.getData("ID")
const img = document.getElementById(a)
const position = e.dataTransfer.getData("position")
if (position === "C") {
C.removeChild(img)
}
if (position === "B") {
B.removeChild(img)
}
if (position === "A") {
A.removeChild(img)
}
}
使用dataTransfer.getData获取到被拖拽元素传输过来的id号以及处在哪一个用户的点餐区域,根据这些信息,从对应的区域使用removeChild这个方法将对应的图片进行移除。
给点餐区域添加事件:
const A = document.querySelector(".A")
A.ondragenter = function (e) {
e.preventDefault();
}
A.ondragover = function (e) {
e.preventDefault();
}
A.ondrop = function (e) {
const a = e.dataTransfer.getData("ID")
const img = document.getElementById(a)
const img9 = img.cloneNode();
img9.ondragstart = function (e) {
e.dataTransfer.setData("ID", img9.id)
e.dataTransfer.setData("position", "A")
}
A.appendChild(img9)
}
这里由于在布局上我设置3个用餐区域,所以需要进行三次相同的事件绑定,所以我只给出A区域的绑定事件。
值得注意的是,在给相应的区域添加图片的时候,不能直接将原来的图片获取过来就放进去,这样会导致在删除的时候,会错误地将菜品区域中的图片删除。需要使用cloneNode节点的这个方法将相应的图片节点进行克隆并且给克隆出来的事件也绑定相应的拖拽事件,将克隆出来的图片使用appendChild添加到相应的区域里面去。
4.隐藏的问题
或许有的人已经注意到了,我对克隆出来的图片节点添加拖拽事件的时候,我对给其设置的id号是原图片的id号,那么就可能产生一个问题,在删除的时候通过getElementById获取id号时,会不会错误地获取到菜品区域的图片,从而导致删除错误。
其实这个问题由于我布局的原因,被隐形地解决掉了。为什么呢?其实很简单,getElementById获取的时候,是通过id获取第一个元素,但是由于我布局的时候将点餐区域放置在了菜品区域的上方,所以默认获取到的就是点餐区域的图片,所以是不会错误删除。
解决问题的第二个办法也很简单,就是单独设置一个新的id号,这里我就不多做赘述。
5.总结
拖拽事件是 Web 开发中实现交互式操作的一种重要方式,通过一系列的事件,可以在网页中实现元素的拖拽、放置等操作。掌握这些基本的拖拽事件可以大大提升用户体验,尤其是在文件上传、元素排序等常见的应用场景中,本文只是提供了一个简单的案例以供学习和参考。