获取DOM元素的屏幕坐标

时间:2013-03-29 12:51:53

标签: javascript c++ dom coordinates firebreath

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

3 个答案:

答案 0 :(得分:6)

P.S。:我知道很久以前我提出了这个问题,但我想总结一下我最后得到的结论。

element.offsetLeft\Top无法真正以其有意义的方式运作 从HTML中,您可以获得相对于页面空间左上角的坐标,而不是用户屏幕本身。

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

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

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

你可以尝试考虑那些浏览器栏并计算Client rect和页面矩形之间的空间,但是那些浏览器栏在用户之间不一致,一个可以有更多,另一个,你会得到所有的坐标系都搞砸了。然后,您可以以某种方式向浏览器注册安装的条数和添加量,并根据计算的空间量,它们将被消耗,但是条形图和添加项不一样,并且您再次考虑太多变量

有一种更简单的方法,你可以不是从顶部开始,而是从底部开始 - 获取矩形底部的坐标,并通过HTML element.offset进行一些计算 - 将坐标系统绑定到左下角窗口的点。
 你底部没有用户浏览器栏,因此在页面和窗口之间的空间可以更加自信,但是有些浏览器在那里有弹出栏,下载信息等,这里我们再次搞砸了所有内容。 / p>

另一种选择是使用模态窗口 - 即通过JavaScript中的window.open()打开模态窗口中的页面,您可以控制这些窗口中浏览器控件和条形图的数量,您可以删除所有这些用户栏和只使用地址栏和页面制作一个清晰的窗口。现在你得到了更多的控制权,并且几乎可以肯定,角落之间的空间对于所有用户来说都是相同的......差不多。
有两件事需要提及:

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

2)明显的一点 - 对于最终用户而言,模态窗口的乐趣可能会让人感到不舒服,因为它削减了浏览器用户习惯的浏览器控件和机制。

答案 1 :(得分:5)

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

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

告诉您事件发生的位置

再次提到jQuery只有在你不想使用时才能获得灵感。

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

答案 2 :(得分:1)

您将光标移动到页面的某个位置,并进行单击事件。(找到窗口,然后GetWindowRect,计算可变位置)然后您可以捕获事件,记录clientX和clientY。通过这个,你可以在两个不同的坐标系之间建立一座桥梁。