指向相对于具有动态DOM的元素的指针位置

时间:2013-05-15 20:34:52

标签: javascript html internet-explorer svg opera

这是与brainjam's solution相关的后续行动,用于查找相对于元素的指针位置。

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

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。据我所知,the DOM level 2 events specifications为MouseEvent指定了唯一的属性clientX / clientY和screenX / screenY。据我所知,DOM level 3 draft events specifications只为MouseEvent指定了相同的两个属性。 offsetX / offsetY在技术上是“非标准的”,还是我在这里遗漏了什么?假设它会坚持下去是否安全?

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

                      

  3. 我可以通过修改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元素的位置?或者有更好的方法来更新视口转换矩阵吗?

1 个答案:

答案 0 :(得分:2)

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

我实际上并不确定在所有情况下这是多么强大,或者它在旧浏览器中的表现如何。据我所知,绝大多数代码都是“标准兼容”,只有一个例外是使用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};
}

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