interview
frontend-classic
怎么使用JS实现元素拖拽功能?

前端经典面试题合集, 怎么使用 JS 实现元素拖拽功能?

前端经典面试题合集, 怎么使用 JS 实现元素拖拽功能?

QA

Step 1

Q:: 如何使用 JavaScript 实现元素拖拽功能?

A:: 使用 JavaScript 实现元素拖拽功能可以通过以下步骤:1. 添加鼠标事件监听器(mousedown、mousemove 和 mouseup)到要拖拽的元素。2. 在 mousedown 事件中,记录鼠标初始位置和元素的初始位置。3. 在 mousemove 事件中,根据鼠标移动的距离实时更新元素的位置。4. 在 mouseup 事件中,移除鼠标移动的事件监听器。以下是一个简化的代码示例:

 
let draggable = document.getElementById('draggable');
let offsetX, offsetY;
draggable.addEventListener('mousedown', function(e) {
  offsetX = e.clientX - draggable.getBoundingClientRect().left;
  offsetY = e.clientY - draggable.getBoundingClientRect().top;
  document.addEventListener('mousemove', mouseMoveHandler);
  document.addEventListener('mouseup', mouseUpHandler);
});
function mouseMoveHandler(e) {
  draggable.style.left = e.clientX - offsetX + 'px';
  draggable.style.top = e.clientY - offsetY + 'px';
}
function mouseUpHandler() {
  document.removeEventListener('mousemove', mouseMoveHandler);
  document.removeEventListener('mouseup', mouseUpHandler);
}
 

Step 2

Q:: 如何确保拖拽的元素在浏览器窗口内?

A:: 要确保拖拽的元素始终在浏览器窗口内,需要在 mousemove 事件中检查元素的新位置,并根据窗口的边界调整位置。例如:

 
function mouseMoveHandler(e) {
  let newLeft = e.clientX - offsetX;
  let newTop = e.clientY - offsetY;
  let rightEdge = window.innerWidth - draggable.offsetWidth;
  let bottomEdge = window.innerHeight - draggable.offsetHeight;
  if (newLeft < 0) newLeft = 0;
  if (newTop < 0) newTop = 0;
  if (newLeft > rightEdge) newLeft = rightEdge;
  if (newTop > bottomEdge) newTop = bottomEdge;
  draggable.style.left = newLeft + 'px';
  draggable.style.top = newTop + 'px';
}
 

用途

面试这个内容是为了考察候选人对基本 DOM 操作和事件处理的掌握程度。这在实际生产环境中非常重要,尤其是对于构建复杂的交互式用户界面时。拖拽功能在许多应用场景下都非常常见,比如拖动文件上传、拖放排序列表以及拖动调整 UI 布局等。\n

相关问题

🦆
请解释事件捕获和事件冒泡机制.

事件捕获和事件冒泡是 DOM 事件流的两个阶段。事件捕获阶段,事件从根节点向目标节点传播;事件冒泡阶段,事件从目标节点向上冒泡回根节点。可以通过 addEventListener 的第三个参数来指定事件监听器是在捕获阶段还是冒泡阶段执行。

 
document.addEventListener('click', function() {
  console.log('Document clicked!');
}, true); // 捕获阶段
 
document.addEventListener('click', function() {
  console.log('Document clicked!');
}, false); // 冒泡阶段
 
🦆
如何阻止事件冒泡和默认行为?

可以使用 event.stopPropagation() 方法来阻止事件冒泡,使用 event.preventDefault() 方法来阻止默认行为。

 
element.addEventListener('click', function(event) {
  event.stopPropagation(); // 阻止事件冒泡
  event.preventDefault(); // 阻止默认行为
});
 
🦆
什么是事件委托,为什么要使用它?

事件委托是利用事件冒泡机制,将子元素的事件处理器委托到父元素上进行统一处理。这减少了内存消耗,提升了性能,特别是对于动态添加的元素。

 
document.getElementById('parent').addEventListener('click', function(event) {
  if (event.target.classList.contains('child')) {
    console.log('Child element clicked!');
  }
});
 
🦆
如何使用 CSS 实现元素拖拽?

使用 CSS 实现元素拖拽通常是通过设置元素的 draggable 属性为 true 并结合 ondragstartondragoverondrop 事件来实现。

 
<div id="draggable" draggable="true">Drag me</div>
<script>
let draggable = document.getElementById('draggable');
draggable.ondragstart = function(event) {
  event.dataTransfer.setData('text/plain', null);
};
document.ondragover = function(event) {
  event.preventDefault();
};
document.ondrop = function(event) {
  event.preventDefault();
  let x = event.clientX;
  let y = event.clientY;
  draggable.style.left = x + 'px';
  draggable.style.top = y + 'px';
};
</script>