在香草javascript的一组坐标内选择常规javascript元素?



在指定位置获取元素- JavaScript

这个问题只回答了一个特定的x和y点,但是我想选择一个矩形内的所有元素,由4个x和y点定义,然后只能选择具有特定类名的元素,类名可以是"selectable"在常规javascript中有办法做到这一点吗?最有效的方法是什么?

我在考虑打电话给文档。elementsFromPoint(x, y)重复,但因为x和y参数不是整数,我将不得不无限次调用它。

我想我已经回答了。虽然我还没怎么测试过。

首先是程序的描述。该程序从body元素开始递归地遍历dom,并测试它是否完全在查询矩形内。我的代码假设元素不会在父元素之外找到,但如果你不想这样做,请删除标记的行。

// first some helper functions
function isRecPartialyInside(inside, outside){
if((between(inside.xmin, outside.xmin,outside.xmax) || between(inside.xmax, outside.xmin,outside.xmax ) && (between(inside.ymin, outside.ymin,outside.ymax) || between(inside.ymax, outside.ymin,outside.ymax )))){
return true;
}
return isRecFullyInside(outside, inside);
}
function between(x, min, max){
return x > min && x < max; 
}
function clientRecToRec(clientRec){
return {xmin: clientRec.x, xmax:clientRec.right, ymin: clientRec.y, ymax: clientRec.bottom};
}
function isRecFullyInside(possiblyInside, possiblyOutside){
return (possiblyInside.xmin > possiblyOutside.xmin && possiblyInside.xmax < possiblyOutside.xmax && possiblyInside.ymin > possiblyOutside.ymin && possiblyInside.ymax < possiblyOutside.ymax);
}
function isClientRecFullyInside(clientRec, rec){
let crec = clientRecToRec(clientRec);
return isRecFullyInside(crec, rec);
}
function isClientRecPartiallyInside(clientRec,rec) {
let crec = clientRecToRec(clientRec);
return isRecPartialyInside(crec, rec);
}
// here is the real deal
function elementsFromBox(x1,x2,y1,y2){
let output = [];
let boundsRec = {xmin:x1,xmax:x2,ymin:y1,ymax:y2};
let curr = document.body;
let stack = [];
let frame = {index:0,list:[curr]};
stack.push(frame);
while(stack.length > 0){
let currFrame = stack.at(-1);
if(currFrame.index >= currFrame.list.length){
stack.pop();
continue;
}
let currEl = currFrame.list[currFrame.index];
currFrame.index +=1;
// Check if the element is fully inside. If so report
if(isClientRecFullyInside(currEl.getBoundingClientRect(), boundsRec)){
output.push(currEl);
}
if(isClientRecPartiallyInside(currEl.getBoundingClientRect(), boundsRec)){ // del
stack.push({index:0,list:currEl.children});
continue;
} // del
}
return output;
}

最新更新