JavaScript上的拖选(使元素可选择)



如何实现拖拽选择(使HTML元素可通过区域鼠标选择)?

我对元素选择很感兴趣,就像它在文件浏览器(Windows, Linux)和许多其他提供文件浏览器行为的网站(dropbox.com, google)。开车,兆。

我的意思是当你用鼠标移动创建一个矩形区域时所有被这个区域触及的元素都会被选中(例如,一个额外的CSS类被添加到它们)。

怎么做?最好的方法?

给你

只要保持{x, y, width, height}getBoundingClientRect对于每个可选择的项目,然后检查每个项目与选择区域的矩形相交在一个循环中。

有29行代码从这里创建选择区域矩形(只有2额外的行),检查5条直线的矩形交点,5行创建demodivs主逻辑只有17行

即使在选择时滚动也可以正常工作。

for (let i = 0; i < 50; i++) {
const div = document.createElement("div");
div.style.backgroundColor = `hsl(${Math.random() * 360}, 100%, 50%)`;
div.classList.add("selectable");
document.body.append(div);
}
// --- Main ---
const selectables = [];
const selectableElems = [...document.querySelectorAll(".selectable")];
for (const selectable of selectableElems) {
const {x, y, width, height} = selectable.getBoundingClientRect();
selectables.push({x: x + window.scrollX, y: y + window.scrollY, width, height, elem: selectable});
selectable.dataset.info = JSON.stringify({x, y, width, height});
}
function checkSelected(selectAreaElem) {
const select = selectAreaElem.getBoundingClientRect();
const {x, y, height, width} = select;
for (const selectable of selectables) {
if (checkRectIntersection({x: x + window.scrollX, y: y + window.scrollY, height, width}, selectable)){
selectable.elem.classList.add("intersected");
} else {
selectable.elem.classList.remove("intersected");
}
}
}
// ------------
function checkRectIntersection(r1, r2) {
return !(r1.x + r1.width  < r2.x ||
r2.x + r2.width  < r1.x ||
r1.y + r1.height < r2.y ||
r2.y + r2.height < r1.y);
}
addEventListener("pointerdown", createDiv);
async function createDiv(event){
event.preventDefault();
const x = event.pageX;
const y = event.pageY;
const div = document.createElement("div");
div.style.position = "absolute";
div.style.width = "0";
div.style.height = "0";
div.style.left = x + "px";
div.style.top = y + "px";
div.classList.add("drag-select");
document.body.append(div);
function resize(event) {
const diffX = event.pageX - x;
const diffY = event.pageY - y;
div.style.left = diffX < 0 ? x + diffX + "px" : x + "px";
div.style.top = diffY < 0 ? y + diffY + "px" : y + "px";
div.style.height = Math.abs(diffY) + "px";
div.style.width = Math.abs(diffX) + "px";
checkSelected(div);
}
selectables.forEach(item => item.elem.classList.remove("intersected"));
addEventListener("pointermove", resize);
addEventListener("pointerup", () => {
removeEventListener("pointermove", resize);
div.remove();
});
}
html, body {
display: inline-grid;
justify-content: center;
width: 100%;
}
div {
width: 128px;
height: 32px;
}
.drag-select {
background-color: rgba(20, 137, 189, 0.5);
}
.intersected {
border: 5px solid black;
box-sizing: border-box;
}

相关内容

  • 没有找到相关文章

最新更新