admin管理员组文章数量:1396850
How to implement drag-select (make HTML elements selectable by area mouse selecting)?
I'm interested in the element selecting like it is in file explorers (of Windows, Linux) and many other sites that provide a file explorer behaviour (dropbox, google.drive, mega.nz, js-fileexplorer demo).
I mean the selecting when you create a rectangular area by mouse move with all elements are touched by this area are "selected" (for example, an extra CSS class is added to them).
How to do it? Best approach?
How to implement drag-select (make HTML elements selectable by area mouse selecting)?
I'm interested in the element selecting like it is in file explorers (of Windows, Linux) and many other sites that provide a file explorer behaviour (dropbox., google.drive, mega.nz, js-fileexplorer demo).
I mean the selecting when you create a rectangular area by mouse move with all elements are touched by this area are "selected" (for example, an extra CSS class is added to them).
How to do it? Best approach?
Share Improve this question edited Mar 31, 2023 at 19:25 KeyKi asked Mar 31, 2023 at 15:33 KeyKiKeyKi 3,2533 gold badges15 silver badges30 bronze badges 3- 1 A simple way would be to have a layout where these elements are placed. Then keep track of their position, and on mouseclick, keep track of initial click x,y positions until release. Any elements underneath that area, you would then add a class to. – DragonInTraining Commented Mar 31, 2023 at 15:42
-
Well, keeping coordinates (
getBoundingClientRect
) of each selectablediv
and checking the intersection of the selecting area with them should be OK. – KeyKi Commented Mar 31, 2023 at 19:17 - Please post what you have tried and the one challenge that presents you so we may best assist you here. Asking for a remendation is out of scope for this site. – Mark Schultheiss Commented Mar 31, 2023 at 19:19
1 Answer
Reset to default 9Here is it.
Just keep {x, y, width, height}
from getBoundingClientRect
for each selectable item, then check the rectangle intersection of each item with the selecting area in a loop.
There are 29 lines of code from here to create the select area rectangle (with only 2 extra lines),
5 lines to check the rectangle intersection,
5 lines to create demo div
s,
and only 17 lines for the main logic.
It works fine even with scrolling while selecting.
// --- Init ---
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) { // stackoverflow./a/13390495
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", createSelectAreaDiv);
async function createSelectAreaDiv(event) { // stackoverflow./a/75902998
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); // extra line 1
}
selectables.forEach(item => item.elem.classList.remove("intersected")); // extra line 2
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;
}
本文标签: Dragselect on JavaScript (Make elements selectable)Stack Overflow
版权声明:本文标题:Drag-select on JavaScript (Make elements selectable) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744129745a2592123.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论