转自:http://stackoverflow.com/questions/26019127/svg-element-loses-event-handlers-if-moved-around-the-dom
<html>
<head>
<title>detail.jsp</title>
<script type="text/javascript" src="http://cyxinda.blog.163.com/blog/./jquery-1.10.2.js"> </script>
<script type="text/javascript" src="http://cyxinda.blog.163.com/blog/./d3.js">
</script>
<script type="text/javascript">
$(document).ready(function(){
//prototype. move to front
d3.selection.prototype.moveToFront = function () {
return this.each(function () {
this.parentNode.appendChild(this);
});
};
//prototype. delegated events
d3.selection.prototype.delegate = function(event, targetselector, handler) {
var self = this;
return this.on(event, function() {
var eventTarget = d3.event.target,
target = self.selectAll(targetselector);
target.each(function(){
//only perform event handler if the eventTarget and intendedTarget match
if (eventTarget === this) {
handler.call(eventTarget, eventTarget.__data__);
} else if (eventTarget.parentNode === this) {
handler.call(eventTarget.parentNode, eventTarget.parentNode.__data__);
}
});
});
};
var testmessage = document.getElementById("testmessage");
//add event listeners insead of .on()
//EG: onmouseover/out of ANY <g> within #svg:
d3.select('#svg').delegate('mouseover','g',function(){
console.log('mouseover',this);
testmessage.innerHTML = "mouseover #"+this.id;
}).delegate('mouseout','g',function(){
console.log('mouseout',this);
testmessage.innerHTML = "mouseout #"+this.id;
});
/* Note: Adding another .delegate listener REPLACES any existing listeners of this event on this node. Uncomment this to see.
//EG2 onmouseover of just the #g3
d3.select('#svg').delegate('mouseover','#g3',function(){
console.log('mouseover of just #g3',this);
testmessage.innerHTML = "mouseover #"+this.id;
});
//to resolve this just delegate the listening to another parent node eg:
//d3.select('body').delegate('mouseover','#g3',function(){...
*/
//initial move to front for testing. OP states that the listener is lost after the element is moved in the DOM.
d3.select('#g2').moveToFront();
});
</script>
<style type="text/css">
.highlight{background-color:yellow;padding:2px;}
svg {height:300px; width:300px;}
rect {fill: pink;}
#g2 rect {fill: green;}
</style>
</head>
<body id="body">
<svg id="svg">
<g id="g1"><rect x="0px" y="0px" width="100px" height="100px" /></g>
<g id="g2"><rect x="50px" y="50px" width="100px" height="100px" /></g>
<g id="g3"><rect x="100px" y="100px" width="100px" height="100px" /></g>
</svg>
<div id="testmessage"></div>
</body>
</html>
<html>
<head>
<title>detail.jsp</title>
<script type="text/javascript" src="http://cyxinda.blog.163.com/blog/./jquery-1.10.2.js"> </script>
<script type="text/javascript" src="http://cyxinda.blog.163.com/blog/./d3.js">
</script>
<script type="text/javascript">
$(document).ready(function(){
//prototype. move to front
d3.selection.prototype.moveToFront = function () {
return this.each(function () {
this.parentNode.appendChild(this);
});
};
//prototype. delegated events
d3.selection.prototype.delegate = function(event, targetselector, handler) {
var self = this;
return this.on(event, function() {
var eventTarget = d3.event.target,
target = self.selectAll(targetselector);
target.each(function(){
//only perform event handler if the eventTarget and intendedTarget match
if (eventTarget === this) {
handler.call(eventTarget, eventTarget.__data__);
} else if (eventTarget.parentNode === this) {
handler.call(eventTarget.parentNode, eventTarget.parentNode.__data__);
}
});
});
};
var testmessage = document.getElementById("testmessage");
//add event listeners insead of .on()
//EG: onmouseover/out of ANY <g> within #svg:
d3.select('#svg').delegate('mouseover','g',function(){
console.log('mouseover',this);
testmessage.innerHTML = "mouseover #"+this.id;
}).delegate('mouseout','g',function(){
console.log('mouseout',this);
testmessage.innerHTML = "mouseout #"+this.id;
});
/* Note: Adding another .delegate listener REPLACES any existing listeners of this event on this node. Uncomment this to see.
//EG2 onmouseover of just the #g3
d3.select('#svg').delegate('mouseover','#g3',function(){
console.log('mouseover of just #g3',this);
testmessage.innerHTML = "mouseover #"+this.id;
});
//to resolve this just delegate the listening to another parent node eg:
//d3.select('body').delegate('mouseover','#g3',function(){...
*/
//initial move to front for testing. OP states that the listener is lost after the element is moved in the DOM.
d3.select('#g2').moveToFront();
});
</script>
<style type="text/css">
.highlight{background-color:yellow;padding:2px;}
svg {height:300px; width:300px;}
rect {fill: pink;}
#g2 rect {fill: green;}
</style>
</head>
<body id="body">
<svg id="svg">
<g id="g1"><rect x="0px" y="0px" width="100px" height="100px" /></g>
<g id="g2"><rect x="50px" y="50px" width="100px" height="100px" /></g>
<g id="g3"><rect x="100px" y="100px" width="100px" height="100px" /></g>
</svg>
<div id="testmessage"></div>
</body>
</html>