【问题标题】:Get absolute screen bounds of a DOM element from a Firefox extension从 Firefox 扩展获取 DOM 元素的绝对屏幕边界
【发布时间】:2012-03-18 21:10:49
【问题描述】:

我有一个 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;
};

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

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

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

谁能给我指点一下?

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

【问题讨论】:

    标签: javascript firefox-addon xul jsctypes


    【解决方案1】:

    你基本上已经知道了,但我建议使用getBoundingClientRect() 而不是offsetLeft/offsetTop

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

    getBoundingClientRect() 考虑滚动,因此您不再需要添加它。您可以使用window.mozInnerScreenXwindow.mozInnerScreenY 获得相对于屏幕的坐标:

    rc.x += window.mozInnerScreenX;
    rc.y += window.mozInnerScreenY;
    

    然后将这些值与screenPixelsPerCSSPixel 相乘。这应该会给你正确的屏幕坐标。

    【讨论】:

    【解决方案2】:

    我将再添加一个帮助我解决类似问题的“技巧”。

    每当我的代码接收到 mousemove 事件时,我都会在该事件提供的所有坐标中捕获鼠标光标位置,其中至少包括“屏幕”、“客户端”和“pageXY”坐标。然后,出于任何其他目的,我可以通过减去其中适当的两个来计算这些坐标之间的差异。

    在您的情况下,您可能会像这样计算偏移量:

    deltaX = event.screenX - event.clientX;
    deltaY = event.screenY - event.clientY;
    

    offsetX = event.screenX - event.pageX;
    offsetY = event.screenY - event.pageY;
    

    然后只需将 deltaX 和 deltaY 或 offsetX 和 offsetY 添加到这些坐标即可获得屏幕坐标。

    【讨论】:

      猜你喜欢
      • 2013-03-20
      • 2012-08-25
      • 1970-01-01
      • 1970-01-01
      • 2014-04-16
      • 2021-01-03
      • 2015-07-14
      • 2010-09-29
      • 2018-05-11
      相关资源
      最近更新 更多