【问题标题】:Get screen coordinates of DOM element获取 DOM 元素的屏幕坐标
【发布时间】:2013-03-20 04:14:55
【问题描述】:

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

【问题讨论】:

    标签: javascript c++ dom coordinates firebreath


    【解决方案1】:

    我知道你没有提到 jQuery,但你可以使用 http://api.jquery.com/offset/ 作为示例。它结合了所有父节点的 offsetLeft/top 并考虑了滚动,为嵌套节点提供准确的 x,y(相对于主体)。

    请注意,如果您正在处理事件,则事件对象始终使用http://api.jquery.com/event.pageX/http://api.jquery.com/event.pageY/ 告诉您事件发生的位置

    同样,仅当您不想使用 jQuery 时,才提及 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】:

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

    element.offsetLeft\Top 并没有真正按照它的意思工作。
    从 HTML 中,您可以获得相对于页面空间左上角的坐标,而不是用户屏幕本身。

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

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

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

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

    有一种更简单的方法,您可以不从顶部开始,而是从底部开始 - 获取 rect 底部的坐标并通过 HTML 的element.offset 进行一些计算 - 将坐标系绑定到底部的左下点窗户。
    底部没有用户浏览器栏,因此可以对页面和窗口角落之间的空间更有信心,但是有些浏览器会在此处弹出带有下载信息等的栏,在这里我们又搞砸了。

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

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

    2) 很明显 - 模式窗口带来的乐趣可能会让最终用户感到不舒服,因为它削减了浏览器用户习惯的一些浏览器控件和机制。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 呵呵,不错的答案。我实际上有这个想法,但仅在一年后我才发布了这个问题。其实很简单。虽然在网站使用过程中会弹出一些东西,比如下载栏等可能会搞砸一些东西,所以它并不理想,但看起来是你能得到的最好的东西。
      猜你喜欢
      • 2011-08-15
      • 2021-04-23
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-28
      相关资源
      最近更新 更多