在Chrome Canary中,layerX和layerY已被弃用,但我们应该使用什么代替?
我发现offsetX,但在Firefox中不起作用。因此为了在webkit上获取layerX而不会出现警告,我已经这样做:
var x = evt.offsetX || evt.layerX,
y = evt.offsetY || evt.layerY;
但是这似乎相当复杂!这真的是我们应该在所有浏览器中使layerX工作的方法吗?
在Chrome Canary中,layerX和layerY已被弃用,但我们应该使用什么代替?
我发现offsetX,但在Firefox中不起作用。因此为了在webkit上获取layerX而不会出现警告,我已经这样做:
var x = evt.offsetX || evt.layerX,
y = evt.offsetY || evt.layerY;
但是这似乎相当复杂!这真的是我们应该在所有浏览器中使layerX工作的方法吗?
这里有一个函数可以从点击事件中计算出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指出了用于创建此函数的两个函数。
你确定layerX和layerY已经被弃用了吗?
根据我的经验,它们仍然存在,主要是因为其他浏览器没有实现相关的offsetX和offsetY属性:
不过在webkit和mozilla中有很多讨论:
https://bugs.webkit.org/show_bug.cgi?id=21868 和 https://bugzilla.mozilla.org/show_bug.cgi?id=674292 简而言之,它们都没有得出是否删除它的结论,所以目前它们还没有被删除。
较新的IE版本提供了一个别名,映射到x和y属性(由于缺乏“声望”,我不能在stack overflow上发布更多链接)。
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
}
那么你可以使用这个来计算它相对于你的元素的位置。
虽然很糟糕,但互联网就是一个糟糕的地方。
我知道这已经相当陈旧了,但是以下是我如何解决layerX问题的方法。
function getLayerX(event) {
return event.clientX - event.target.getBoundingClientRect().x
}
我不确定这种方法是否适用于所有情况,但这是对我有效的方法,所以我想分享一下。
[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] );
var x = y = 0
,因为这会将y
声明为全局变量。 - fmvilas