从Firefox扩展获取DOM元素的绝对屏幕边界

rep*_*vsd 2 javascript xul firefox-addon jsctypes

我有一个firefox扩展,需要获取DOM元素的确切屏幕坐标,并通过js/c-types将其传递给本机DLL.

现在我主要涵盖了它:

var gDomWindowUtils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(nsIDOMWindowUtils);

function getScreenRect(oElem)
{
    var rc =
    {
        x : 0,
        y : 0,
        w : 0,
        h : 0
    };

    var o = oElement;
    while(o != null)
    {
        rc.y += o.offsetTop;
        rc.x += o.offsetLeft;
        o = o.offsetParent;
    }

    var x = {}, y = {};
    gDomWindowUtils.getScrollXY(false, x, y);
    rc.x -= x.value;
    rc.y -= y.value;

    var scale = gDomWindowUtils.screenPixelsPerCSSPixel;
    rc.x *= scale;
    rc.y *= scale;
    rc.w *= scale;
    rc.h *= scale;

    return rc;
};
Run Code Online (Sandbox Code Playgroud)

这会处理滚动和缩放,但我得到的值是相对于浏览器窗口而不是屏幕.

如何检测浏览器实际渲染区域的客户区域的偏移量?我甚至可以通过js/ctypes使用本机代码(Win32),所以我试着看看我是否可以使用FindWindow()/ GetWindowRect()来获取它,但是整个firefox是一个单独的HWND,控件都不是本机窗口.

所以我有一个想法是,因为firefox的UI是一个XUL文档,我应该能够获得菜单栏,标签栏等等,并找到浏览器区域的绝对偏移量.但是,我不知道如何访问定义浏览器UI的XUL树.

有人可以给我指针吗?

[编辑]忽略上面代码中未定义的rc.w和rc.h,它与问题无关.

Wla*_*ant 7

你大多已经得到它但我建议使用getBoundingClientRect()而不是offsetLeft/offsetTop:

var rect = oElement.getBoundingClientRect();
var rc = {
  x: rect.left,
  y: rect.top,
  w: rect.width,
  h: rect.height
};
Run Code Online (Sandbox Code Playgroud)

getBoundingClientRect()考虑滚动,以便您不再需要添加它.使用window.mozInnerScreenX和得到相对于屏幕的坐标window.mozInnerScreenY:

rc.x += window.mozInnerScreenX;
rc.y += window.mozInnerScreenY;
Run Code Online (Sandbox Code Playgroud)

然后你将这些值乘以screenPixelsPerCSSPixel.这应该给你正确的屏幕坐标.