看起来这个漏洞可能会在 Firefox 的核心代码中存在较长一段时间,这里有一个 99% 可用的补丁:
if(/Firefox\/\d+[\d\.]*/.test(navigator.userAgent)
&& typeof window.DragEvent === 'function'
&& typeof window.addEventListener === 'function') (function(){
var cx, cy, px, py, ox, oy, sx, sy, lx, ly;
function update(e) {
cx = e.clientX; cy = e.clientY;
px = e.pageX; py = e.pageY;
ox = e.offsetX; oy = e.offsetY;
sx = e.screenX; sy = e.screenY;
lx = e.layerX; ly = e.layerY;
}
function assign(e) {
e._ffix_cx = cx; e._ffix_cy = cy;
e._ffix_px = px; e._ffix_py = py;
e._ffix_ox = ox; e._ffix_oy = oy;
e._ffix_sx = sx; e._ffix_sy = sy;
e._ffix_lx = lx; e._ffix_ly = ly;
}
window.addEventListener('mousemove', update, true);
window.addEventListener('dragover', update, true);
window.addEventListener('dragstart', assign, true);
window.addEventListener('drag', assign, true);
window.addEventListener('dragend', assign, true);
var me = Object.getOwnPropertyDescriptors(window.MouseEvent.prototype),
ue = Object.getOwnPropertyDescriptors(window.UIEvent.prototype);
function getter(prop,repl) {
return function() {return me[prop] && me[prop].get.call(this) || Number(this[repl]) || 0};
}
function layerGetter(prop,repl) {
return function() {return this.type === 'dragover' && ue[prop] ? ue[prop].get.call(this) : (Number(this[repl]) || 0)};
}
Object.defineProperties(window.DragEvent.prototype,{
clientX: {get: getter('clientX', '_ffix_cx')},
clientY: {get: getter('clientY', '_ffix_cy')},
pageX: {get: getter('pageX', '_ffix_px')},
pageY: {get: getter('pageY', '_ffix_py')},
offsetX: {get: getter('offsetX', '_ffix_ox')},
offsetY: {get: getter('offsetY', '_ffix_oy')},
screenX: {get: getter('screenX', '_ffix_sx')},
screenY: {get: getter('screenY', '_ffix_sy')},
x: {get: getter('x', '_ffix_cx')},
y: {get: getter('y', '_ffix_cy')},
layerX: {get: layerGetter('layerX', '_ffix_lx')},
layerY: {get: layerGetter('layerY', '_ffix_ly')}
});
})();
请注意,尽管OP的问题仅涉及到“dragend”,但这是适用于所有受影响事件的修复方法。
它从“mousemove”和“dragover”事件中获取鼠标的最后准确坐标,并将其注入到受影响的“dragstart”、“drag”和“dragend”事件中。
请注意,这并不是一个完美的修复方法。x / y坐标可能会稍微偏差。由于“drag”事件在“dragover”之前发生,因此它执行时使用来自上一事件帧的坐标。
dragend
事件适用于源元素,即被拖动的元素。使用drop
事件的clientX
和clientY
来获取目标元素的坐标,而不是使用dragend
。 - JayclientX
和clientY
而不是x
和y
。 - user1935043