C++ 获取 DOM 元素的屏幕坐标

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15703625/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:40:13  来源:igfitidea点击:

Get screen coordinates of DOM element

javascriptc++domcoordinatesfirebreath

提问by Max Yari

Can I somehow get precise screen coordinates (relative to top left corner of the screen) of a DOM object. Through NPAPI\FireBreath or JavaScript. (Need this for plugin, that I'm writing with FireBreath)

我能否以某种方式获得 DOM 对象的精确屏幕坐标(相对于屏幕的左上角)。通过 NPAPI\FireBreath 或 JavaScript。(需要这个插件,我正在用 FireBreath 编写)

采纳答案by Jason Zheng

you move cursor to somewhere of the page ,and make a click event.(find the window,then GetWindowRect ,caculate a sutable position) then you can catch the event,record clientX and clientY. By this ,you build a bridge between two different coordinate system.

您将光标移动到页面的某个位置,并进行点击事件。(找到窗口,然后 GetWindowRect ,计算出一个合适的位置)然后您就可以捕获该事件,记录 clientX 和 clientY。通过这种方式,您可以在两个不同的坐标系之间架起一座桥梁。

回答by Max Yari

P.S.: I know I made this question long ago, but I want to summarize what I got at the end.

PS:我知道我很久以前就提出了这个问题,但我想总结一下我最后得到的东西。

element.offsetLeft\Topdoesn't work truly the way it meant to be in question.
From the HTML you can get coords, relative to top-left corner of page's space, not the user screen itself.

element.offsetLeft\Top并没有真正按照所讨论的方式工作。
从 HTML 中,您可以获得相对于页面空间左上角的坐标,而不是用户屏幕本身。

And from plugin, by GetWindowRect()winAPI function you can get coordinates of top-left corner of the browser window, relative to user screen, and by GetClientRect()you can get coords of the top left corner of Client rectangle.

从插件中,通过GetWindowRect()winAPI 函数,您可以获得浏览器窗口左上角相对于用户屏幕的GetClientRect()坐标,并且您可以获得客户端矩形左上角的坐标。

BUT, it isn't the same point as top-left of page, there is always something between corner of page's space, and client rect, or window rect. It includes top browser bars and other stuff.

但是,它与页面左上角不同,页面空间的角落和客户端矩形或窗口矩形之间总是有一些东西。它包括顶级浏览器栏和其他东西。

What you can do? It seems that there is no easy 100% controllable way:

你可以做什么?似乎没有简单的 100% 可控的方法:

You can try to consider those browser bars and calculate the space between Client rectand page's rectangle, but those browser bars not constant from user to user, one can have more of them, that another, and you will get all your coordinate system screwed up. Then, you can somehow register the amount of installed bars and additions to browser, and according to that calculate amount of space, that will be consumed by them, but bars and additions not the same, and again you got way too much variables to consider.

您可以尝试考虑那些浏览器栏并计算Client rect页面矩形之间的空间,但是这些浏览器栏从用户到用户并不是恒定不变的,一个可以有更多,另一个,您将把所有坐标系都搞砸了。然后,您可以以某种方式注册已安装的栏和添加到浏览器的数量,并根据该数量计算它们将消耗的空间量,但栏和添加不一样,并且您再次需要考虑太多变量.

There is a bit easier way, you can go not from top, but from the bottom - get the coord's of bottom point of rect and through some calculations with HTML's element.offset- bind your coordinate system to bottom-left point of the window.
You got no user browser bars at the bottom, and therefore can be a little more confident in space between page and window corner, but some browsers got pop-up bars there with download information e.t.c, and here we got everything screwed up again.

有一个更简单的方法,你可以不从顶部,而是从底部 - 获取矩形底部点的坐标,并通过一些 HTML 计算element.offset- 将坐标系绑定到窗口的左下角。
底部没有用户浏览器栏,因此可以对页面和窗口角之间的空间更有信心,但有些浏览器在那里有下载信息等弹出栏,在这里我们又把一切搞砸了。

Another option is to use modal window's - i.e. open the page in modal window through window.open()from your JavaScript, you can control amount of browser controls and bars in those windows, you can get rid of all those userbars and make a clear window only with address bar and the page. Now you got much more control, and can almost be sure, that this space between corners will be the same for all your users... almost.
There is two things need to be mentioned:

另一种选择是使用模态窗口 - 即通过window.open()您的 JavaScript在模态窗口中打开页面,您可以控制这些窗口中浏览器控件和栏的数量,您可以摆脱所有这些用户栏并仅使用地址栏制作一个清晰的窗口和页面。现在您有了更多的控制权,并且几乎可以肯定,角落之间的空间对于您的所有用户来说都是一样的......几乎。
有两点需要说明:

1)Some browsers (for example google chrome, as I remember) got those custom browser additions (Firebug for example) to appear as small icons near address bar, and they are still appearing near the address bar of the modal window.
What the difference you can ask - the difference is, that, for some reason, top of the browser window will became around 5 pixels fatter, if there's even one of those icons.(again you can try to register, are there any of those installed on user browser, or not)
And if, anyway, those 5px not crucial for you - it can be a way to go.. if you're ok with the next thing.

1)一些浏览器(例如谷歌浏览器,我记得)让那些自定义浏览器添加(例如Firebug)在地址栏附近显示为小图标,并且它们仍然出现在模式窗口的地址栏附近。
您可以问有什么不同 - 不同之处在于,出于某种原因,浏览器窗口的顶部将变得大约 5 像素,如果甚至有这些图标之一。(再次您可以尝试注册,是否有任何这些图标安装在用户浏览器上,或者没有)
如果,无论如何,那些 5px 对你来说并不重要 - 这可能是一种方法......如果你对接下来的事情感到满意。

2)Obvious one - that fun with modal windows can be uncomfortable for end-user, cos it cuts some browser controls and mechanics that browser users get used to.

2) 显而易见 - 模式窗口的乐趣会让最终用户感到不舒服,因为它减少了浏览器用户习惯的一些浏览器控件和机制。

回答by Juan Mendes

I know you didn't mention jQuery, but you can use http://api.jquery.com/offset/as an example. It combines the offsetLeft/topof all the parents and accounts for scrolling, giving you an accurate x,y (in relation to the body) for nested nodes.

我知道您没有提到 jQuery,但您可以使用http://api.jquery.com/offset/作为示例。它结合了offsetLeft/top所有父项和滚动帐户,为嵌套节点提供准确的 x,y(相对于主体)。

Note that if you're handling events, the event object always tells you where the event happened using http://api.jquery.com/event.pageX/and http://api.jquery.com/event.pageY/

请注意,如果您正在处理事件,则事件对象始终会使用http://api.jquery.com/event.pageX/http://api.jquery.com/event.pageY/告诉您事件发生的位置

Again, mentioning jQuery is for inspiration only if you don't want to use it.

同样,提及 jQuery 只是在您不想使用它时获得灵感。

Here's how jQuery does it

这是 jQuery 如何做到的

$.fn.offset = function (options) {
    var elem = this[0],
        doc = elem && elem.ownerDocument;

    if (!doc) {
        return null;
    }

    if (elem === doc.body) {
        return jQuery.offset.bodyOffset(elem);
    }

    return getOffset(elem, doc, doc.documentElement);
}

function getOffset(elem, doc, docElem, box) {
    try {
        box = elem.getBoundingClientRect();
    } catch(e) {}

    // Make sure we're not dealing with a disconnected DOM node
    if (!box || !jQuery.contains(docElem, elem)) {
        return box ? {
            top: box.top,
            left: box.left
        } : {
            top: 0,
            left: 0
        };
    }

    var body = doc.body,
        win = getWindow(doc),
        clientTop = docElem.clientTop || body.clientTop || 0,
        clientLeft = docElem.clientLeft || body.clientLeft || 0,
        scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
        scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
        top = box.top + scrollTop - clientTop,
        left = box.left + scrollLeft - clientLeft;

    return {
        top: top,
        left: left
    };
}