在现代Web开发中,拖拽交互是提升用户体验的有效手段。本文将介绍如何使用原生JavaScript实现基本的拖拽功能,并展示如何通过触摸事件适配移动设备。此外,我们还将使用SortableJS库演示如何在栅格布局中拖拽移动卡片,为构建响应式的交互界面提供解决方案。
使用原生JavaScript实现拖拽功能
HTML 结构
我们将定义一个具有特定样式的<div>
元素,用户可以在页面上自由拖动这个元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple Drag and Drop Example</title>
<style>
#draggable {
width: 100px;
height: 100px;
background-color: teal;
position: absolute;
cursor: pointer;
}
</style>
</head>
<body>
<div id="draggable">Drag me!</div>
<script src="app.js"></script>
</body>
</html>
JavaScript 代码
在app.js
文件中,我们编写代码来处理拖拽逻辑,包括监听鼠标事件和触摸事件。
document.addEventListener('DOMContentLoaded', function () {
const elem = document.getElementById('draggable');
let offsetX = 0, offsetY = 0, isDragging = false;
const startDrag = (x, y) => {
isDragging = true;
offsetX = x - elem.getBoundingClientRect().left;
offsetY = y - elem.getBoundingClientRect().top;
};
const stopDrag = () => {
isDragging = false;
};
const doDrag = (x, y) => {
if (isDragging) {
elem.style.left = (x - offsetX) + 'px';
elem.style.top = (y - offsetY) + 'px';
}
};
elem.addEventListener('mousedown', e => startDrag(e.clientX, e.clientY));
document.addEventListener('mouseup', stopDrag);
document.addEventListener('mousemove', e => doDrag(e.clientX, e.clientY));
// 添加触摸事件监听
elem.addEventListener('touchstart', e => {
e.preventDefault();
const touch = e.touches[0];
startDrag(touch.clientX, touch.clientY);
}, { passive: false });
document.addEventListener('touchend', stopDrag);
document.addEventListener('touchmove', e => {
if (isDragging) {
const touch = e.touches[0];
doDrag(touch.clientX, touch.clientY);
}
}, { passive: false });
});
使用SortableJS库实现拖拽网格
HTML 和 CSS
在HTML文件中,我们创建一个栅格布局,每个卡片可以通过SortableJS进行拖拽。
<div id="grid" class="grid">
<div class="card">Card 1</div>
<div class="card">Card 2</div>
<div class="card">Card 3</div>
<div class="card">Card 4</div>
<div class="card">Card 5</div>
<div class="card">Card 6</div>
</div>
JavaScript 初始化SortableJS
在app.js
文件中,我们使用SortableJS来使栅格中的卡片可拖拽。
document.addEventListener('DOMContentLoaded', () => {
new Sortable(document.getElementById('grid'), {
animation: 150,
ghostClass: 'sortable-ghost',
chosenClass: "sortable-chosen",
dragClass: "sortable-drag",
});
});
完整代码
原生拖拽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple Drag and Drop Example</title>
<style>
#draggable {
width: 100px;
height: 100px;
background-color: teal;
position: absolute;
cursor: pointer;
}
</style>
</head>
<body>
<div id="draggable">Drag me!</div>
<script src="app.js"></script>
</body>
</html>
// app.js
document.addEventListener('DOMContentLoaded', function () {
const elem = document.getElementById('draggable');
let offsetX = 0, offsetY = 0, isDragging = false;
const startDrag = (x, y) => {
isDragging = true;
offsetX = x - elem.getBoundingClientRect().left;
offsetY = y - elem.getBoundingClientRect().top;
};
const stopDrag = () => {
isDragging = false;
};
const doDrag = (x, y) => {
if (isDragging) {
elem.style.left = (x - offsetX) + 'px';
elem.style.top = (y - offsetY) + 'px';
}
};
elem.addEventListener('mousedown', e => startDrag(e.clientX, e.clientY));
document.addEventListener('mouseup', stopDrag);
document.addEventListener('mousemove', e => doDrag(e.clientX, e.clientY));
// 添加触摸事件监听
elem.addEventListener('touchstart', e => {
e.preventDefault();
const touch = e.touches[0];
startDrag(touch.clientX, touch.clientY);
}, { passive: false });
document.addEventListener('touchend', stopDrag);
document.addEventListener('touchmove', e => {
if (isDragging) {
const touch = e.touches[0];
doDrag(touch.clientX, touch.clientY);
}
}, { passive: false });
});
SortableJS 拖拽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Draggable Grid Demo</title>
<style>
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
padding: 10px;
}
.card {
padding: 20px;
background-color: #f9f9f9;
border: 1px solid #ccc;
text-align: center;
}
.sortable-ghost {
opacity: 0.4;
}
</style>
</head>
<body>
<div id="grid" class="grid">
<div class="card">Card 1</div>
<div class="card">Card 2</div>
<div class="card">Card 3</div>
<div class="card">Card 4</div>
<div class="card">Card 5</div>
<div class="card">Card 6</div>
<div class="card">Card 7</div>
<div class="card">Card 8</div>
<div class="card">Card 9</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
<script src="app.js"></script>
</body>
</html>
// app.js
document.addEventListener('DOMContentLoaded', () => {
var el = document.getElementById('grid');
var sortable = new Sortable(el, {
animation: 500, // 动画延迟
ghostClass: 'sortable-ghost', // 拖拽时的透明类
chosenClass: "sortable-chosen", // 选择类
dragClass: "sortable-drag", // 拖拽类
});
});
结论
通过这些示例,我们展示了如何从零开始实现基本的拖拽功能,以及如何使用SortableJS库提供更复杂的拖拽界面。无论是通过原生JavaScript实现基础功能,还是利用现代库简化开发流程,拖拽交互都能显著提升用户体验。这些技术的应用可以广泛应用于各种Web开发项目中,帮助开发者构建更动态、更互动的Web应用。
Comments NOTHING