How to detecting a click under an overlapping element?

自闭症网瘾萝莉.ら 提交于 2019-12-13 00:21:08

问题


I have two HTML documents, b.html contains c.html using an iframe.

On b.html I need to draw some DIV (in my example id=selector), which partially cover content of c.html visualized in the iframe.

I need to get the ID of a DOM element corresponding to the mouse coordinate under the DIV selector.

At the moment Using document.elementFromPoint() directly in in c.html works partially, as when the mouse it is on DIV selector I cannot identify the underling DOM element in c.html (in this example DIV c).

I would need to know:

  • Is it possible to select element under another, using document.elementFromPoint() or any other means?
  • What could be a possible alternatively solution possibly using DOM and native API?

Example here (Please look at the console in Chrome):

http://jsfiddle.net/s94cnckm/5/

----------------------------------------------- b.html

<!doctype html>

<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>B</title>
    <script type="text/javascript">
        window.app = {
            start: function () {
            }
        };
    </script>
    <style>
        #selector {
            position: absolute;
            top: 150px;
            left: 150px;
            width: 250px;
            height: 250px;
            -webkit-box-shadow: 0px 0px 0px 5px yellow;
            -moz-box-shadow: 0px 0px 0px 5px yellow;
            box-shadow: 0px 0px 0px 5px yellow;
        }

        #iframe {
            width: 500px;
            height: 500px;
            border: none;
        }
    </style>
</head>
<body onload="app.start();">
    <div id="selector">SELECTOR</div>
    <iframe id="iframe" src="c.html"></iframe>
</body>
</html>

----------------------------------------------- c.html

<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>C</title>
    <script type="text/javascript">
        window.app = {
            start: function () {
                document.querySelector('body').addEventListener('mousemove', function (event) {
                //console.log(event.pageX, event.pageY, event.target.id);
                var item = document.elementFromPoint(event.pageX, event.pageY);
                console.log(item.id);
                }.bind(this));
            }
        };
    </script>
    <style>
        body {
            background-color: lightslategray;
        }

        #a {
            position: absolute;
            top: 50px;
            left: 50px;
            width: 100px;
            height: 100px;
            background-color: green;
            z-index: 2;
        }

        #b {
            position: absolute;
            top: 100px;
            left: 100px;
            width: 100px;
            height: 100px;
            background-color: #ffd800;
            z-index: 1;
        }
    </style>
</head>
<body onload="app.start();">
    <h1>Content</h1>
    <div id="a">a</div>
    <div id="b">b</div>
</body>
</html>

回答1:


A possible soltion is the usage of pointer-events.

The CSS property pointer-events allows authors to control under what circumstances (if any) a particular graphic element can become the target of mouse events. When this property is unspecified, the same characteristics of the visiblePainted value apply to SVG content.

When you apply

#selector {
    /* ... */
    pointer-events: none;
 }

All content of #selector and the element itself are no more interactive. Content may not be selected and events like :hover or click are not applicable.

Here is the demo with the above css: http://jsfiddle.net/s94cnckm/6/




回答2:


Another possible solution, is to capture the document coordinates of a mouse event fired on the masking item(DIV.selector), momentarily hide that masking item, and then ask the document what is under that coordinate position (using document.elementFromPoint(x,y)) before showing the masking item again.

The support for document.elementFromPoint() cover also old version of IE. Unfortunately pointer-events has limited support for older version of IE.

Here a working example:

http://jsfiddle.net/s94cnckm/14/

 document.getElementById('iframe').contentDocument.addEventListener('click', function (event) {
     alert(event.target.id);
 }.bind(this));

 document.getElementById('selector').addEventListener('click', function (event) {
     var selector = document.getElementById('selector');
     selector.style.display = 'none';
     var item = document.getElementById('iframe').contentDocument.elementFromPoint(event.pageX, event.pageY);
     selector.style.display = '';
     alert(item.id);
 }.bind(this));

Regarding the use of pointer-events I link to mention some related article, included a work around for older version of IE.

How to make Internet Explorer emulate pointer-events:none?

https://css-tricks.com/almanac/properties/p/pointer-events/

http://davidwalsh.name/pointer-events

http://robertnyman.com/2010/03/22/css-pointer-events-to-allow-clicks-on-underlying-elements/

This solution was inspired by this article:

http://www.vinylfox.com/forwarding-mouse-events-through-layers/



来源:https://stackoverflow.com/questions/29518070/how-to-detecting-a-click-under-an-overlapping-element

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!