获取DOM元素的屏幕坐标

Max*_*ari 10 javascript c++ dom coordinates firebreath

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

Max*_*ari 7

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

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

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

但是,它与页面的左上角不同,在页面空间的角落,客户端矩形或窗口矩形之间始终存在某些内容.它包括顶级浏览器栏和其他东西.

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

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

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

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

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

2)显而易见的一点 - 模态窗口的乐趣对最终用户来说可能是不舒服的,因为它削减了浏览器用户习惯的浏览器控件和机制.


Jua*_*des 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
    };
}
Run Code Online (Sandbox Code Playgroud)


小智 2

你将光标移动到页面的某个位置,然后发出一个点击事件。(找到窗口,然后 GetWindowRect ,计算一个合适的位置)然后你就可以捕获该事件,记录 clientX 和 clientY。这样,您就在两个不同的坐标系之间建立了一座桥梁。