当你有重叠元素时从点获取元素?

时间:2014-03-15 19:14:14

标签: javascript

您可以使用它来查找给定点的文档元素

document.elementFromPoint(x, y);

如果点上有重叠元素,你会怎么做? (我知道这不是一个很好的做事方式 - 在截止日期之前尝试一个针对错误的hackish解决方法)。

5 个答案:

答案 0 :(得分:15)

我认为您已经知道,document.elementFromPoint(x, y);仅返回与该点重叠的最顶层元素。

如果您要尝试做的是找到与给定点重叠的所有元素,甚至是其他元素后面的元素,那么我不知道任何可以为您执行此操作的DOM函数。你可能要写自己的。

有点hackish版本是调用elementFromPoint(x,y),记住DOM项目,然后用display: none隐藏该项目,然后再次调用elementFromPoint(x,y),直到你得到的是身体,然后恢复你隐藏的物品。

一个不太讨厌的版本是循环浏览页面中的所有对象,并将页面中的偏移/高度/宽度与您的点进行比较。

以下是一种方法:

function getAllElementsFromPoint(x, y) {
    var elements = [];
    var display = [];
    var item = document.elementFromPoint(x, y);
    while (item && item !== document.body && item !== window && item !== document && item !== document.documentElement) {
        elements.push(item);
        display.push(item.style.display);
        item.style.display = "none";
        item = document.elementFromPoint(x, y);
    }
    // restore display property
    for (var i = 0; i < elements.length; i++) {
        elements[i].style.display = display[i];
    }
    return elements;
}

工作演示:http://jsfiddle.net/jfriend00/N9pu9/

答案 1 :(得分:3)

不确定提出初始问题的原因是什么,但如果您需要使用触摸或鼠标元素检测当前可拖动的元素,则可以在可拖动元素上设置UPDATE MYTABLE SET COLUMN1 = 'value2' 。执行此操作时,pointer-events: none;将忽略当前可拖动的元素并返回其下方的元素。

答案 2 :(得分:3)

如果要查找在一个点上重叠的所有DOM元素,可以简单地使用document.elementsFromPoint(),它返回在该点找到的所有元素的数组(显然,相对于该点从上到下排序)视口,即:如果有叠加层,它将首先显示在数组中)

答案 3 :(得分:0)

简单解决方案

如果$e是重叠元素,则e是事件

$e.style.display = 'none';
var b = document.elementFromPoint(e.clientX,e.clientY);
$e.style.display = 'block';

答案 4 :(得分:0)

因此,据我所知,这个答案-https://stackoverflow.com/a/54350762/479836-是理想的选择,但不幸的是,document.elementsFromPoint()在IE11中不起作用。

否则,此答案-https://stackoverflow.com/a/22428553/479836中的代码似乎可在包括IE11在内的大多数现代浏览器上运行,但是存在一个错误,即某些DOM元素在函数返回的数组中重复。

但是,如果有人在寻找document.elementsFromPoint()填充片,可以在这里找到一个很好的填充片:

https://gist.github.com/oslego/7265412

为方便起见,在此处复制

function elementsFromPoint(x,y) {
    var elements = [], previousPointerEvents = [], current, i, d;

        // get all elements via elementFromPoint, and remove them from hit-testing in order
    while ((current = document.elementFromPoint(x,y)) && elements.indexOf(current)===-1 && current != null) {

            // push the element and its current style
        elements.push(current);
        previousPointerEvents.push({
                value: current.style.getPropertyValue('pointer-events'),
                priority: current.style.getPropertyPriority('pointer-events')
            });

            // add "pointer-events: none", to get to the underlying element
        current.style.setProperty('pointer-events', 'none', 'important'); 
    }

        // restore the previous pointer-events values
    for(i = previousPointerEvents.length; d=previousPointerEvents[--i]; ) {
        elements[i].style.setProperty('pointer-events', d.value?d.value:'', d.priority); 
    }

        // return our results
    return elements;
}