在Webkit中,由于layerX/layerY已被弃用,我们应该使用什么替代方法?

25

在Chrome Canary中,layerX和layerY已被弃用,但我们应该使用什么代替?

我发现offsetX,但在Firefox中不起作用。因此为了在webkit上获取layerX而不会出现警告,我已经这样做:

var x = evt.offsetX || evt.layerX,
    y = evt.offsetY || evt.layerY;

但是这似乎相当复杂!这真的是我们应该在所有浏览器中使layerX工作的方法吗?

5个回答

21

这里有一个函数可以从点击事件中计算出layerX和layerY:

function getOffset(evt) {
  var el = evt.target,
      x = 0,
      y = 0;

  while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
    x += el.offsetLeft - el.scrollLeft;
    y += el.offsetTop - el.scrollTop;
    el = el.offsetParent;
  }

  x = evt.clientX - x;
  y = evt.clientY - y;

  return { x: x, y: y };
}

感谢Stu Cox指出了用于创建此函数的两个函数。


2
抱歉,但似乎这并不总是获取与layerX和layerY相同的值...看来我们必须继续寻找解决方案... - Alejandro Rizzo
1
只是为了完整回答,要注意 var x = y = 0,因为这会将 y 声明为全局变量。 - fmvilas

7

你确定layerX和layerY已经被弃用了吗?

根据我的经验,它们仍然存在,主要是因为其他浏览器没有实现相关的offsetX和offsetY属性:

不过在webkit和mozilla中有很多讨论:

https://bugs.webkit.org/show_bug.cgi?id=21868https://bugzilla.mozilla.org/show_bug.cgi?id=674292 简而言之,它们都没有得出是否删除它的结论,所以目前它们还没有被删除。

较新的IE版本提供了一个别名,映射到x和y属性(由于缺乏“声望”,我不能在stack overflow上发布更多链接)。


6
唯一合理跨浏览器检测鼠标位置的方法是使用clientX/clientY(相对于窗口)、screenX/screenY(相对于整个屏幕)和pageX/pageY(相对于文档,但不支持IE8及以下版本)。 Quirksmode建议使用以下方法将其标准化为相对于文档的值:
function doSomething(e) {
    var posx = 0;
    var posy = 0;
    if (!e) var e = window.event;
    if (e.pageX || e.pageY)     {
        posx = e.pageX;
        posy = e.pageY;
    }
    else if (e.clientX || e.clientY)     {
        posx = e.clientX + document.body.scrollLeft
            + document.documentElement.scrollLeft;
        posy = e.clientY + document.body.scrollTop
            + document.documentElement.scrollTop;
    }
    // posx and posy contain the mouse position relative to the document
    // Do something with this information
}

那么你可以使用这个来计算它相对于你的元素的位置。

虽然很糟糕,但互联网就是一个糟糕的地方。


4

我知道这已经相当陈旧了,但是以下是我如何解决layerX问题的方法。

   function getLayerX(event) {
     return event.clientX - event.target.getBoundingClientRect().x
   }

我不确定这种方法是否适用于所有情况,但这是对我有效的方法,所以我想分享一下。


0
提供的解决方案未考虑根元素的滚动偏移量。以下是我完成此任务的代码:
[layerX, layerY] = [...(function*() {  
    for (var el = ev.target; 
         el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop); 
         el = el.offsetParent) yield el; 
    yield document.documentElement; })()
  ]
  .map(el => [ -el.offsetLeft + el.scrollLeft, -el.offsetTop + el.scrollTop ])
  .reduce( 
    (acc, coords) => [ acc[0] + coords[0], acc[1] + coords[1] ], 
    [ ev.clientX, ev.clientY] );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接