1

这是与brainjam找到相对于元素的指针位置的解决方案相关的后续内容。

作为参考,这是他的解决方案:

function mouseMoveHandler(e)
{
    var style = getComputedStyle(c,null) ;
    var borderTop = style.getPropertyValue("border-top-width") ;
    var borderLeft = style.getPropertyValue("border-left-width") ;
    var paddingTop = style.getPropertyValue("padding-top") ;
    var paddingLeft = style.getPropertyValue("padding-left") ;
    var offsetX = e.offsetX || e.layerX || 0 ;
    var offsetY = e.offsetY || e.layerY || 0; 
    var x = offsetX ;
    var y = offsetY ;
    if(window.navigator.userAgent.indexOf("Opera") === -1){ 
        x -= parseInt(paddingLeft,10) ;
        y -= parseInt(paddingTop,10) ;
        if(window.navigator.userAgent.indexOf("MSIE") === -1){
            x -= parseInt(borderLeft,10)  ;
            y -= parseInt(borderTop,10)  ;    
        }
    }
    // do something with x, y
}

现在我对这段代码有一些担忧:

  1. 此代码使用 offsetX/offsetY。据我所知,DOM 2 级事件规范为 MouseEvent 指定了唯一的属性 clientX/clientY 和 screenX/screenY。据我所知,DOM 3 级草稿事件规范只为 MouseEvent 指定了相同的两个属性。offsetX/offsetY 在技术上是“非标准”的,还是我在这里遗漏了什么?假设它会继续存在是否安全?

  2. 我有一些像这样的文件:

我可以通过修改viewport.

我如何更新视口的变换:

// matrix is the updated transformation of the viewport
var transform = svg_base.createSVGTransformFromMatrix(matrix);
viewport.transform.baseVal.initialize(transform);

在 Chrome 和 Firefox 中,这工作得非常好。但是,在 IE10 和 Opera 12 中,存在偏移值不断“跳跃”的问题。请注意,据我所知,这仅在涉及此转换更新过程时才会发生。将其注释掉,似乎 offsetX/offsetY 值表现良好。

如果我选择左下角并将其向上拖动,这是来自 IE10 的 offsetx/offsetY 值的简短日志:

64, 128
 65, 127
 66, 128
 67, 125
 64, 127
 67, 122
 64, 127
 67, 119
 64, 128
 67, 118
 64, 126
 67, 115
 64, 126
 67, 112
 64, 126
 67, 109
 64, 126
 67, 106

请注意,当我稳定地向上移动鼠标时坐标是如何跳动的(并且略微向右移动,尽管这不是故意的)。这会导致闪烁效果,最终视口将与预期的移动操作不同步。我的问题是为什么会在 IE10/Opera 而不是 Firefox/Chrome 中发生这种情况?有没有更好的方法来获取鼠标指针相对于 svg_base 元素的位置?或者有没有更好的方法来更新视口变换矩阵?

4

1 回答 1

2

在对 FireFox、Chrome、IE10 和 Opera(最常用的现代桌面浏览器,由于无法访问而减去 Safari)进行了一些测试后,我开发了一个基于quirksmode.org解决方案的替代方案。

我实际上不确定这在所有情况下有多强大,或者它在旧浏览器中的表现如何。据我所知,绝大多数代码都是“符合标准的”,除了一个例外是使用 pageX/pageY 来支持旧浏览器(不确定这适用于哪些,这是 quirksmode.org 实现的一部分) .

// params:
//  - elem: the element to get pointer coords relative to
//  - e: MouseEvent object
function mousePosRelElement(elem, e)
{
    var x = 0;
    var y = 0;

    var bounds = elem.getBoundingClientRect();

    // not actually sure which browsers use pageX/pageY, just left in from quirksmode implementation
    if(e.pageX !== undefined && e.pageY !== undefined)
    {
        x = e.pageX - bounds.left - document.body.scrollLeft - document.documentElement.scrollLeft;
        y = e.pageY - bounds.top - document.body.scrollTop - document.documentElement.scrollTop;
    }
    else if(e.clientX !== undefined && e.clientY !== undefined)
    {
        x = e.clientX - bounds.left;
        y = e.clientY - bounds.top;
    }

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

欢迎和鼓励提出意见和建议。

于 2013-05-16T06:15:07.233 回答