A solution is offered in various places, including here and it works fine in Firefox and Chrome. But it breaks in IE (I'm using IE 11).
The basic idea is to do this in the mouseover
listener
this.parentNode.appendChild(this);
Since a node can only have one parent, the original reference is deleted before re-appending at the end of the child nodes.
Normally the mouseover
event only fires once on initial mouseover
, but, the append
seems to reset the event for the element in IE so the event fires again on the next mousemove
. This causes the mouseover
event to behave like mousemove
and also stops mouseout from working.
In IE there are no mouseout
events reported
It can be fixed by fiddling around removing the event from the element first and then re-attaching it after a timeout, but is there another way?
(function () {
d3.selection.prototype.moveToFront = function () {
return this.each(function () {
this.parentNode.appendChild(this);
});
};
var log = d3.select('#output'), counter = 0
var svg = d3.select("body").append('svg');
var data = d3.range(10);
var circles = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr({
cx: function (d, i) { return d * 20 + 100 },
cy: 50,
r: 20,
fill: "#aaa",
stroke: "#000"
})
.on("mouseover", function () {
var sel = d3.select(this);
sel.moveToFront();
logEvent();
})
.on("mouseout", logEvent);
function logEvent() {
var e = d3.event, node,
message = counter++ + ' ' + e.type + ': ' + e.target.tagName + ' ---> ' + e.currentTarget.tagName
console.log(message)
node = log.html(log.html() + '<p class="' + e.type + '">' + message + '</p>').node();
node.scrollTop = node.scrollHeight;
}
})()
#output {
height: 100px;
overflow:scroll;
}
p {
margin:0;
}
.mouseover {
color: red;
}
.mouseout {
color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="output"></div>