2015-12-29 98 views
0

我有一個SVG結構如下:D3.js鼠標事件

<svg> 
    <g class="A"> 
     <rect id="A1" /> 
     <rect id="A2" /> 
     <rect id="A3" /> 
    </g> 
    <g class="B"> 
     <rect id="B1" /> 
     <rect id="B2" /> 
     <rect id="B3" /> 
    </g> 
    <g class="C"> 
     <rect id="C1" /> 
     <rect id="C2" /> 
     <rect id="C3" /> 
    </g> 
</svg> 

我試圖從一個組拖動一個元件到另一個。如果我將組中的元素(A)拖到組(B)中,但我能夠檢測到mouseover事件,但是如果我正在將組中的元素拖到組(A)中,則無法檢測到mouseover事件。這種模式貫穿於在元素被拖動之後創建的更多的兄弟組中。 IE:我可以拖動和檢測從A到C和從B到C的鼠標懸停,但是如果我將C元素拖動到A或B,它不會檢測到鼠標懸停。

我已經嘗試過pointer-events:allz-index(我相信它甚至不適用於SVG元素)。

示例代碼:https://jsfiddle.net/2pku66yu/25/

嘗試拖動一個盒子上下游。下游元素點亮,但上游元素則不亮。

+0

在黑暗中只是一個嘗試,但你試圖改變你的''標籤''? – xdhmoore

+0

同樣,如果您使用的是html minifier,它可能會爲您做上述操作並導致問題,但我不會指望出現問題。 – xdhmoore

+0

@xdhmoore爲了簡潔起見,我做到了。我使用D3來創建所有這些。 – wolfrevo

回答

0

你可以在後臺創建一個額外的組和重新設置父級上拖動節點,以便他們總是在後臺運行。是這樣的...

var svg = d3.selectAll("body").append("svg").attr("width", "100%").attr("height", "100%"); 
 

 
var data = [ {gind:0, class:"Z",elements:[]},{gind:1,class:"A",elements:[1,2,3]}, {gind:2,class:"B",elements:[1,2,3]} , {gind:3,class:"C",elements:[1,2,3]} ] 
 

 
var groups = svg.selectAll("gs").data(data).enter().append("g").attr("class",function(d){ return d.class; }).attr("transform",function(d){ return "translate("+d.gind*50+","+d.gind*50+")"}); 
 

 
var elements = groups.selectAll(".element").data(function(d){ return d.elements.map(function(i){ return { id:i , x:i*10, y:i*10 } }); }).enter().append("rect").attr("class","element").attr("transform",function(d){ 
 
console.log(d) 
 
return "translate("+d.x+","+d.y+")" 
 
}).attr("width",10).attr("height",10).style("fill","#cccccc") 
 

 
var draghandle = d3.behavior.drag().origin(Object).on("drag", dragfunc).on("dragstart", dragstart).on("dragend", dragend); 
 
var dragging_elem = false; 
 

 
elements.on("mouseover",function(d){ 
 
\t d3.select(this).style("fill","red"); 
 
}).on("mouseout",function(d){ d3.select(this).style("fill","#cccccc") }).call(draghandle) 
 

 
var prevParent; 
 
var z = document.getElementsByClassName("Z")[0]; 
 

 
function dragstart(d) { 
 
    prevParent = d3.select(this).node().parentNode; 
 
    d3.select(z).attr("transform", prevParent.getAttribute("transform")); 
 
    z.appendChild(d3.select(this).node()); 
 
} 
 
function dragend(d) { 
 
    prevParent.appendChild(d3.select(this).node()); 
 
} 
 
function dragfunc(d){ \t 
 
    d.x = d3.event.x 
 
    d.y = d3.event.y 
 
    d3.select(this).attr("transform","translate("+d3.event.x+","+d3.event.y+")"); 
 
}
html, body { 
 
    width: 100%; 
 
    height: 100%; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

+0

感謝您的想法!這可能是我的真實代碼更好的解決方案! – wolfrevo

0

找到一份像樣的解決方案,以上面的例子中,看到新的代碼:https://jsfiddle.net/2pku66yu/47/

var mouse_loc = d3.mouse(svg.node()) 
    var prev = d3.select(this).style("pointer-events"); 
    d3.select(this).style("pointer-events","none"); 

    var el = document.elementFromPoint(mouse_loc[0]+5, mouse_loc[1]+5); 

    e2 = document.createEvent('MouseEvent'); 
    e2.initMouseEvent("mouseover",e.bubbles,e.cancelable,e.view, e.detail,e.screenX,e.screenY,e.clientX,e.clientY,e.ctrlKey,e.altKey,e.shiftKey,e.metaKey,e.button,e.relatedTarget); 

    if (el) { 
     el.dispatchEvent(e2); 
    } 

    d3.select(this).style("pointer-events","all");