**已关闭。**此问题需要debugging details。目前不接受回答。
编辑问题以包括desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将帮助其他人回答问题。
1小时前关闭
Improve this question的
在这个例子中,工作区由26张table组成。当员工从顶部框中拖动时,我希望他能捕捉到红点,并且只能在红点上放下。有人能帮忙吗,谢谢...
const workplace = document.getElementById('workplace');
const employeesContainer = document.getElementById('employees-container');
// Layout based on the provided configuration
const columnWidth = 225;
const rowHeight = 125;
// Greate Office Tables
function createTable(x, y, number) {
const table = document.createElement('div');
table.className = 'table';
table.setAttribute('draggable', false);
table.style.left = `${x}px`;
table.style.top = `${y}px`;
table.textContent = number;
if (number % 2 === 0) {
const dots = ['right'];
dots.forEach((position) => {
const dot = document.createElement('div');
dot.className = 'drop-dot';
dot.dataset.position = position;
table.appendChild(dot);
});
} else {
const dots = ['left'];
dots.forEach((position) => {
const dot = document.createElement('div');
dot.className = 'drop-dot';
dot.dataset.position = position;
table.appendChild(dot);
});
}
workplace.appendChild(table);
}
//Create Employees
function createEmployee(x, y, firstName, lastName, initials) {
const employee = document.createElement('span');
employee.className = 'employee';
employee.style.left = `${x}px`;
employee.style.top = `${y}px`;
employee.textContent = initials;
employee.draggable = true;
// Add drag start event listener
employee.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text/plain', 'employee'); // Custom data for identification
employee.classList.add('dragging');
});
workplace.appendChild(employee);
}
// Create Employee Avatar
function createEmployeeBox(firstName, lastName) {
const employeeBox = document.createElement('div');
employeeBox.className = 'employee-box';
const initials = `${firstName.charAt(0).toUpperCase()}${lastName.charAt(0).toUpperCase()}`;
employeeBox.textContent = initials;
employeeBox.draggable = true;
employeeBox.dataset.initials = initials; // Add custom data attribute
// Add drag start event listener
employeeBox.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text/plain', 'employee-box'); // Custom data for identification
employeeBox.classList.add('dragging');
});
employeesContainer.appendChild(employeeBox);
}
// First row
for (let i = 0; i < 10; i += 2) {
createTable(i * (columnWidth / 3), 0, i + 1);
createTable((i + 1) * (columnWidth / 3) - 20, 0, i + 2); // Adjusted spacing
}
// Second row
for (let i = 4; i < 10; i += 2) {
createTable(i * (columnWidth / 3), rowHeight, i + 7);
createTable((i + 1) * (columnWidth / 3) - 20, rowHeight, i + 8); // Adjusted spacing
}
// Third row (same as the first)
for (let i = 0; i < 10; i += 2) {
createTable(i * (columnWidth / 3), 2 * rowHeight, i + 17);
createTable((i + 1) * (columnWidth / 3) - 20, 2 * rowHeight, i + 18); // Adjusted spacing
}
// Add employees
createEmployeeBox('sofia', 'Dhomas');
createEmployeeBox('Cofia', 'Whomas');
createEmployeeBox('Mofia', 'Lhomas');
createEmployeeBox('Cofia', 'Nhomas');
function createEmployee(x, y, firstName, lastName, initials) {
const employee = document.createElement('span');
employee.className = 'employee';
employee.style.left = `${x}px`;
employee.style.top = `${y}px`;
employee.textContent = initials;
employee.draggable = true;
// Add drag start event listener
employee.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text/plain', 'employee'); // Custom data for identification
employee.classList.add('dragging');
});
workplace.appendChild(employee);
}
// Event listeners for drag-and-drop
workplace.addEventListener('dragover', (event) => {
event.preventDefault();
});
workplace.addEventListener('drop', (event) => {
event.preventDefault();
const dataType = event.dataTransfer.getData('text/plain');
const offsetX = event.clientX - workplace.getBoundingClientRect().left;
const offsetY = event.clientY - workplace.getBoundingClientRect().top;
if (dataType === 'employee') {
const employee = document.querySelector('.employee.dragging');
if (employee) {
console.log('employee')
const nearestTable = findNearestTable(offsetX, offsetY);
if (nearestTable) {
console.log('nearestTable')
const tableRect = nearestTable.getBoundingClientRect();
const snappedX = tableRect.left + tableRect.width / 2 - employee.clientWidth / 2;
const snappedY = tableRect.top + tableRect.height / 2 - employee.clientHeight / 2;
// Remove the corresponding employee box
const initials = employee.textContent;
const employeeBox = document.querySelector(`.employee-box[data-initials='${initials}']`);
if (employeeBox) {
employeesContainer.removeChild(employeeBox);
}
employee.style.left = `${snappedX}px`;
employee.style.top = `${snappedY}px`;
employee.classList.remove('dragging');
}
// Move employee to new position
//employee.style.left = `${offsetX - 12.5}px`; // Adjust for centering
//employee.style.top = `${offsetY - 12.5}px`; // Adjust for centering
}
} else if (dataType === 'employee-box') {
console.log('employee-box')
// Remove the dragged employee box
const nearestTable = findNearestTable(offsetX, offsetY);
if (nearestTable) {
console.log('nearestTable');
}
const employeeBox = document.querySelector('.employee-box.dragging');
if (employeeBox) {
employeesContainer.removeChild(employeeBox);
}
// Create new employee at the dropped position
const initials = employeeBox.textContent;
createEmployee(offsetX - 12.5, offsetY - 12.5, 'New', 'Employee', initials);
}
}); // Orginal
// Double-click to return employee to the employee box
workplace.addEventListener('dblclick', (event) => {
if (event.target.classList.contains('employee')) {
const employee = event.target;
const initials = employee.textContent;
// Remove the employee from the workplace
workplace.removeChild(employee);
// Create a new employee box with the correct initials
createEmployeeBox(initials.charAt(0), initials.charAt(1));
}
});
// FN
// Function to find the nearest table
function findNearestTable(x, y) {
const tables = document.querySelectorAll('.table');
let nearestTable = null;
let minDistance = Infinity;
tables.forEach((table) => {
const tableRect = table.getBoundingClientRect();
console.log(tableRect)
const distance = Math.sqrt((x - tableRect.left - tableRect.width / 2) ** 2 +
(y - tableRect.top - tableRect.height / 2) ** 2);
if (distance < minDistance) {
console.log('tableRect')
minDistance = distance;
nearestTable = table;
}
});
return nearestTable;
}
body {
font-family: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
font-size: 0.9375rem;
font-wiight: 400;
line-height: 1.47;
display: flex;
flex-direction: column;
align-items: center;
}
.workplace {
position: relative;
width: 740px;
height: 375px;
border: 2px solid #cfd3ec;
margin: 20px;
background-color: #434968;
border-radius: 0.5rem;
}
.table {
position: absolute;
width: 40px;
height: 80px;
background-color: #424659;
border: 2px solid #cfd3ec;
border-radius: 0.2rem;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
margin: 20px;
color: #cfd3ec;
}
.table.highlighted-table {
border: 2px solid yellow;
/* Change the color as needed */
}
.employee {
position: absolute;
width: 25px;
height: 25px;
border: 1px solid black;
border-radius: 50%;
background-color: white;
display: flex;
align-items: center;
justify-content: center;
font-weight: 500;
cursor: move;
user-select: none;
}
.employees-container {
display: flex;
width: 740px;
height: 100px;
background-color: #434968;
border: 2px solid #cfd3ec;
border-radius: 0.3rem;
box-sizing: border-box;
align-items: center;
margin-top: 20px;
flex-wrap: wrap;
}
.employee-box {
width: 25px;
height: 25px;
border: 1px solid #cfd3ec;
border-radius: 50%;
background-color: white;
display: flex;
align-items: center;
justify-content: center;
font-weight: 500;
cursor: move;
user-select: none;
margin: .5rem;
}
.drop-dot {
position: absolute;
width: 10px;
height: 10px;
background-color: red;
border-radius: 50%;
cursor: pointer;
}
.drop-dot[data-position="left"] {
top: 50%;
left: -5px;
transform: translateY(-50%);
}
.drop-dot[data-position="right"] {
top: 50%;
right: -5px;
transform: translateY(-50%);
}
<div class="employees-container" id="employees-container"></div>
<div class="workplace" id="workplace"></div>
1条答案
按热度按时间n53p2ov01#
在dragstart上,你需要关于被拖动的员工的信息。在dragstart上,你可以通过设置className来更改“drop zone”的样式。在drop事件上,被拖动的元素必须被移动/附加到新的drop zone。然后,被拖动的元素必须被样式化,以便在适当的位置。
already
对象用于测试员工是否已经在table上。