Получить абсолютные границы экрана DOM-элемента из расширения Firefox - PullRequest
2 голосов
/ 29 февраля 2012

У меня есть расширение firefox, которое должно получить точные координаты экрана элемента DOM и передать его в собственную DLL через js / c-types.

Теперь у меня это в основном покрыто:

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;
};

Это обрабатывает прокрутку и масштабирование, но значения, которые я получаю, относятся к окну браузера, а не к экрану.

Как определить смещение клиентской области реальной области рендеринга браузера? Я даже могу использовать нативный код (Win32) через js / ctypes, поэтому я попытался выяснить, могу ли я использовать FindWindow () / GetWindowRect (), чтобы получить его, но весь firefox - это один HWND, все элементы управления не являются нативными окнами .

Итак, у меня есть одна идея: поскольку пользовательский интерфейс Firefox является XUL-документом, я должен быть в состоянии получить строку меню, панель вкладок и т. Д. И т. Д. И найти абсолютное смещение областей браузера. Но я понятия не имею, как получить доступ к дереву XUL, которое определяет пользовательский интерфейс браузера.

Может кто-нибудь дать мне указатель?

[Изменить] Игнорируйте, что rc.w и rc.h не определены в приведенном выше коде, это не имеет отношения к вопросу.

Ответы [ 2 ]

7 голосов
/ 29 февраля 2012

Вы уже получили его, но я бы порекомендовал использовать getBoundingClientRect () вместо offsetLeft/offsetTop:

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

getBoundingClientRect() рассматривает прокрутку, так что вам больше не нужно добавлятьЭто.Вы получаете координаты относительно экрана, используя window.mozInnerScreenX и window.mozInnerScreenY:

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

И после этого вы умножаете значения на screenPixelsPerCSSPixel.Это должно дать вам правильные координаты экрана.

1 голос
/ 16 января 2014

Я добавлю еще один «трюк», который помог мне с подобной проблемой.

Всякий раз, когда мой код получает событие mousemove, я фиксирую позиции курсора мыши во ВСЕХ координатах, которые это событие предоставляет, включаяпо крайней мере, координаты "screen", "client" и "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 к этим координатам, чтобы получить координаты экрана.

...