Javascript 确定iframe内的鼠标位置,但包括父对象

Javascript 确定iframe内的鼠标位置,但包括父对象,javascript,iframe,mouse-position,Javascript,Iframe,Mouse Position,我有一个iframe,在其中我检测到右键单击并将鼠标事件传递给父函数中的函数。在这里,(在父函数内部),我有显示自定义上下文菜单的逻辑,上下文菜单html标记被插入父DOM中。因此,需要根据视口(或父DOM)确定鼠标位置,但我收到的是相对于iframe的 我尝试使用Offsetop和offsetParent,但这只会重复到innerpage的body标记。您可以通过调用父文档中的iframe来获取顶部和左侧。假设您的iFrame在父文档中具有id“my\u iFrame”: offset_lef

我有一个iframe,在其中我检测到右键单击并将鼠标事件传递给父函数中的函数。在这里,(在父函数内部),我有显示自定义上下文菜单的逻辑,上下文菜单html标记被插入父DOM中。因此,需要根据视口(或父DOM)确定鼠标位置,但我收到的是相对于iframe的


我尝试使用Offsetop和offsetParent,但这只会重复到innerpage的body标记。

您可以通过调用父文档中的iframe来获取顶部和左侧。假设您的iFrame在父文档中具有id
“my\u iFrame”

offset_left = parent.document.getElementById('my_iframe').offsetLeft;
offset_top  = parent.document.getElementById('my_iframe').offsetTop;
但是,只有当iFrame中的内容属于同一来源(相同的主机、端口和协议)时,这才起作用


编辑:在bytes.com上也发现了类似的问题:

这是我使用的函数:

// Define class that will hold Object coordinates
function CTopLeft(i_nTop, i_nLeft) {
   this.nTop = i_nTop;
   this.nLeft = i_nLeft;
}

function GetTopLeftFromIframe(i_oElem) {
   var cTL = new CTopLeft(0, 0);
   var oElem = i_oElem;
   var oWindow = window;

   do {
      cTL.nLeft += oElem.offsetLeft;
      cTL.nTop += oElem.offsetTop;
      oElem = oElem.offsetParent;

      if (oElem == null) { // If we reach top of the ancestor hierarchy
         oElem = oWindow.frameElement; // Jump to IFRAME Element hosting the document
         oWindow = oWindow.parent;   // and switching current window to 1 level up
      }
   } while (oElem)

   return cTL;
}

这是从

开始的,直到元素是position:absolute元素的子元素并滚动,Yuriy解决方案才能正常工作。(我寻找的是元素位置,而不是鼠标,但我相信您也可以修改它以实现此目的)

我的解决方案:

function iframe_offset(e){
var  x=e.getBoundingClientRect().x
    ,y=e.getBoundingClientRect().y
    ,w=e.ownerDocument.defaultView
    do{
        e = e.offsetParent
        if(e == null){
            e = w.frameElement
            w = w.parent
            if(e){
                x += e.offsetLeft+e.scrollLeft
                y += e.offsetTop+e.scrollTop
            }
        }
    }while(e)
    return {x:x,y:y}
}

至少现在(可能以前也是),您在
事件
对象(
layerX
screenX
,等等)上有很多坐标,这意味着您最好只使用其中一个集合,为了避免这种额外的计算——在我的用例中,使用
screenX
/
screenY
作为基础,而不是尝试和计算,这大大简化了事情,并且实现了这个技巧。

这非常有效,直到元素是位置的子元素:绝对,并且是滚动的。请参阅下面我的答案,了解我试图绕过这一点的情况。