2017-06-13 102 views
0

它可以像Chrome和MSIE中預期的那樣工作。出於某種原因,事件觸發內部矩形元素以及SVG元素(我認爲)。這裏是醬(這是整個頁面):爲什麼在Firefox中閃爍?

<html> 
<body> 

    <svg width="400" height="400" style="overflow: hidden; border: 1px solid gray" id="mySVG"> 
     <rect x="10" y="10" width="100" height="100" fill="red" id="myRect"></rect> 
    </svg> 

    <script> 
     svg = document.getElementById('mySVG'); 
     rect = document.getElementById('myRect'); 

     svg.onmousemove = function (e) 
     { 
      if (e.currentTarget.toString().indexOf('SVGSVGElement') >= 0) { 

       var x = e.offsetX, 
        y = e.offsetY; 

       if (x && y) { 
        console.log(x) 
        rect.setAttribute('x', x - 50); 
        rect.setAttribute('y', y - 50); 
       } 
      } 
     }; 
    </script> 

</body> 
</html> 

回答

0

Firefox和Chrome以不同的方式實現事件。如果你console.log(e.target.id, x)可以被觀察到。 Firefox的日誌是這樣的:

mySVG 394 
myRect 35 
mySVG 372 
myRect 36 
mySVG 354 
mySVG 353 
myRect 48 

如果矩形不是鼠標下,offsetX相對於svg元計算。然後,矩形在鼠標下移動,並且下一個事件之一(取決於它們發射的快速度)被分派到rect元素,並且相對於此計算offsetX。由於偵聽器將矩形相對於svg移動,它將跳轉到左上角,並且在下一個事件中,它不再位於鼠標下方,並且該事件再次被分派到svg

鉻日誌

mySVG 400 
myRect 392 
myRect 383 
myRect 375 
myRect 368 
myRect 363 

當第一個事件被調度到svg元素,所有後續事件被派往rect。原因是offsetX總是相對於svg元素進行計算,無論鼠標是否在rect之上。

Considerung的CSSOM定義offsetX

回報,其中

我要說的是事件發生點相對於目標節點的填充邊緣的原點位置的x座標Firefox的實現更有意義。

最好的解決辦法,找到相對座標可能是

// matrix contains offset relative to browser window 
// as properties e and f 
var ctm = svg.getScreenCTM(); 
// mouse positions relative to browser window 
var x = e.clientX - ctm.e, 
    y = e.clientY - ctm.f; 

跨SVG工作和HTML元素是d3this internal function的一般解。

+0

但事件處理程序綁定到SVG元素 - 所以它會在鼠標圍繞SVG元素移動時觸發 - 所以不應該將offsetX和offsetY作爲鼠標相對於座標的座標 - 就像它們在Chrome中一樣MSIE(11)?即使鼠標超過了矩形,是否可以獲得與整個畫布相關的偏移量?這是通過offsetParents並添加X和Y座標的問題嗎? – Richard

+0

事件處理程序被綁定到'svg',但是在'rect'上發生的事件一直冒泡到'svg'。 'e.target'爲你提供事件發送的原始元素,'e.currentTarget'是處理程序所連接的元素。 – ccprog

+0

改爲使用offsetParent/offsetLeft和offsetTop代替:https://www.rgraph.net/tests/svg-getmousexy.html – Richard