I am trying to follow the html5 drag and drop tutorial here. I could not get the dragstart event to be registered on rect element. If I change the event from draggable to mousedown it calls the handleDragStart handler. Please ignore the additional blank registration in the code.
JSFiddle here
<!DOCTYPE html>
<html><head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<style type="text/css" media="screen">
svg rect { cursor: move; }
</style>
</head><body>
<h1>SVG/HTML 5 Example</h1>
<svg id="cvs">
<rect draggable="true" x="0" y="10" width="100" height="80" fill="#69c" />
<rect x="50" y="50" width="90" height="50" fill="#c66" />
</svg>
<script type="text/javascript" src="loc.js"></script>
</body></html>
loc.js
$(document).ready(function() {
function handleDragStart(e) {
log("handleDragStart");
this.style.opacity = '0.4'; // this ==> e.target is the source node.
};
var registercb = function () {
$("#cvs > rect").each(function() {
$(this).attr('draggable', 'true');
});
$("#cvs > rect").bind('dragstart', handleDragStart);
$(window).mousedown(function (e) {
});
$(window).mousemove(function (e) {
});
$(window).mouseup(function (e) {
log("mouseup");
});
};
function log() {
if (window.console && window.console.log)
window.console.log('[XXX] ' + Array.prototype.join.call(arguments, ' '));
};
registercb();
});
I know this is an old question, I arrived here from this other question that was marked as a duplicate of this one, and wanted to add a possible solution that doesn't require jQuery or any libraries, and that works in all major browsers. It is based on this tutorial recommended by #AmirHossein Mehrvarzi.
This small solution doesn't use the drag events, just the mousedown, mouseup and mousemove. This is how it works:
When the mouse is down on the rectangle, it saves the mouse position and the active element.
When the mouse moves, the rectangle coordinates are updated with the new mouse position.
When the mouse is up, it resets the active element.
From the code in the question above:
var selectedElement = null;
var currentX = 0;
var currentY = 0;
$(document).ready(function() {
function handleDragStart(e) {
log("handleDragStart");
this.style.opacity = '0.4'; // this ==> e.target is the source node.
};
var registercb = function () {
$("#cvs > rect").mousedown(function (e) {
// save the original values when the user clicks on the element
currentX = e.clientX;
currentY = e.clientY;
selectedElement = e.target;
}).mousemove(function (e) {
// if there is an active element, move it around by updating its coordinates
if (selectedElement) {
var dx = parseInt(selectedElement.getAttribute("x")) + e.clientX - currentX;
var dy = parseInt(selectedElement.getAttribute("y")) + e.clientY - currentY;
currentX = e.clientX;
currentY = e.clientY;
selectedElement.setAttribute("x", dx);
selectedElement.setAttribute("y", dy);
}
}).mouseup(function (e) {
// deactivate element when the mouse is up
selectedElement = null;
});
};
function log() {
if (window.console && window.console.log)
window.console.log('[XXX] ' + Array.prototype.join.call(arguments, ' '));
};
registercb();
});
rect { cursor: move; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1>SVG/HTML 5 Example</h1>
<svg id="cvs">
<rect x="0" y="10" width="100" height="80" fill="#69c" />
<rect x="50" y="50" width="90" height="50" fill="#c66" />
</svg>
You can also see it on this JSFiddle: http://jsfiddle.net/YNReB/61/
If you want to add drop functionality, you can modify the mouseup function to read the element on the cursor position (with document.elementFromPoint(e.clientX, e.clientY)) and then you can perform actions on the original element and the one where it was dropped.
This behavior may be caused by several reasons:
HTML 5 drag and drop is a mess, according to this article. I know it's a bit older, but the issue still seems not to be solved
jQuery does not support the SVG DOM-model. Therefore some parts of it may work, others don't (like offset() or width()).
I'd definitely not rely on HTML5 drag & drop support right now, but rather use a library to handle this issue. If you want to work with SVG, you could try Raphaël. If you need jQuery too, maybe the SVG plugin is the way to go. Note that both projects are not actively developed at the moment.
I know this is not really a satisfactory answer, but I had to learn too, that jQuery and SVG do not go that well together. Hopefully someone proves me wrong ;).
Related
I am trying to follow the html5 drag and drop tutorial here. I could not get the dragstart event to be registered on rect element. If I change the event from draggable to mousedown it calls the handleDragStart handler. Please ignore the additional blank registration in the code.
JSFiddle here
<!DOCTYPE html>
<html><head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<style type="text/css" media="screen">
svg rect { cursor: move; }
</style>
</head><body>
<h1>SVG/HTML 5 Example</h1>
<svg id="cvs">
<rect draggable="true" x="0" y="10" width="100" height="80" fill="#69c" />
<rect x="50" y="50" width="90" height="50" fill="#c66" />
</svg>
<script type="text/javascript" src="loc.js"></script>
</body></html>
loc.js
$(document).ready(function() {
function handleDragStart(e) {
log("handleDragStart");
this.style.opacity = '0.4'; // this ==> e.target is the source node.
};
var registercb = function () {
$("#cvs > rect").each(function() {
$(this).attr('draggable', 'true');
});
$("#cvs > rect").bind('dragstart', handleDragStart);
$(window).mousedown(function (e) {
});
$(window).mousemove(function (e) {
});
$(window).mouseup(function (e) {
log("mouseup");
});
};
function log() {
if (window.console && window.console.log)
window.console.log('[XXX] ' + Array.prototype.join.call(arguments, ' '));
};
registercb();
});
I know this is an old question, I arrived here from this other question that was marked as a duplicate of this one, and wanted to add a possible solution that doesn't require jQuery or any libraries, and that works in all major browsers. It is based on this tutorial recommended by #AmirHossein Mehrvarzi.
This small solution doesn't use the drag events, just the mousedown, mouseup and mousemove. This is how it works:
When the mouse is down on the rectangle, it saves the mouse position and the active element.
When the mouse moves, the rectangle coordinates are updated with the new mouse position.
When the mouse is up, it resets the active element.
From the code in the question above:
var selectedElement = null;
var currentX = 0;
var currentY = 0;
$(document).ready(function() {
function handleDragStart(e) {
log("handleDragStart");
this.style.opacity = '0.4'; // this ==> e.target is the source node.
};
var registercb = function () {
$("#cvs > rect").mousedown(function (e) {
// save the original values when the user clicks on the element
currentX = e.clientX;
currentY = e.clientY;
selectedElement = e.target;
}).mousemove(function (e) {
// if there is an active element, move it around by updating its coordinates
if (selectedElement) {
var dx = parseInt(selectedElement.getAttribute("x")) + e.clientX - currentX;
var dy = parseInt(selectedElement.getAttribute("y")) + e.clientY - currentY;
currentX = e.clientX;
currentY = e.clientY;
selectedElement.setAttribute("x", dx);
selectedElement.setAttribute("y", dy);
}
}).mouseup(function (e) {
// deactivate element when the mouse is up
selectedElement = null;
});
};
function log() {
if (window.console && window.console.log)
window.console.log('[XXX] ' + Array.prototype.join.call(arguments, ' '));
};
registercb();
});
rect { cursor: move; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1>SVG/HTML 5 Example</h1>
<svg id="cvs">
<rect x="0" y="10" width="100" height="80" fill="#69c" />
<rect x="50" y="50" width="90" height="50" fill="#c66" />
</svg>
You can also see it on this JSFiddle: http://jsfiddle.net/YNReB/61/
If you want to add drop functionality, you can modify the mouseup function to read the element on the cursor position (with document.elementFromPoint(e.clientX, e.clientY)) and then you can perform actions on the original element and the one where it was dropped.
This behavior may be caused by several reasons:
HTML 5 drag and drop is a mess, according to this article. I know it's a bit older, but the issue still seems not to be solved
jQuery does not support the SVG DOM-model. Therefore some parts of it may work, others don't (like offset() or width()).
I'd definitely not rely on HTML5 drag & drop support right now, but rather use a library to handle this issue. If you want to work with SVG, you could try Raphaël. If you need jQuery too, maybe the SVG plugin is the way to go. Note that both projects are not actively developed at the moment.
I know this is not really a satisfactory answer, but I had to learn too, that jQuery and SVG do not go that well together. Hopefully someone proves me wrong ;).
I'm fairly new to JavaScript & JQuery, so apologies if I'm missing a trick or two.
I've figured out how to get JQuery UI draggable objects to use the grid option, and, once the page has loaded, "snap to an imaginary grid" which all draggable objects have reference to (explained in code comments). However, I can't figure out how to get this behaviour to occur .on("dragstart").
HTML:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script type="text/javascript" src="jquery-1.10.2.js"></script>
<script type="text/javascript" src="jquery-ui.js"></script>
<script type="text/javascript" src="dragger.js"></script>
</head>
<body>
<div id="parent">
<svg width="300" height="100" class="draggable" id="number1">
<rect x="0" y="0" rx="10" ry="10" width="300" height="100" style="fill:rgb(121,0,121);stroke-width:3;stroke:rgb(0,0,0);">
</svg>
<svg width="300" height="100" class="draggable" id="letterA">
<rect x="0" y="0" rx="100" ry="10" width="300" height="100" style="fill:rgb(0,121,121);stroke-width:3;stroke:rgb(255,0,0);">
</svg>
</div>
</body>
</html>
Note: There is a white gap between the two rectangles, via the second JavaScript below, this disappears once the block has been snapped to the grid. Alternatively, the 2 rectangles should be draggable onto each other and line up flush against one another to be considered snapped onto the grid.
JavaScript (dragger.js):
var roundedRemainder = function(numer, denom) {
return numer - (Math.round(numer / denom) * denom);
}
var snapPosition = function(obj, granularity) {
obj.position({
my: "left top", // Unchanging reference point on draggable object
at: "left top", // Unchanging reference point on reference object
of: "#parent", // The object that you want to move items with respect to.
using: function(position, data) {
var newPositions = {
// Get the difference between the "imaginary grid" and the current grid
left: function() {
return roundedRemainder(position.left, granularity);
},
top: function() {
return roundedRemainder(position.top, granularity);
}
}
// Move to the imaginary grid
$(this).css(newPositions);
return newPositions;
}
});
}
$(function() {
var gridSize = 50;
$(".draggable")
// Enable grid usage
.draggable({
grid: [gridSize, gridSize]
})
.on("dragstart", function(event, ui) {
var newPos = snapPosition(ui.helper, gridSize);
})
});
Proof the code in snapPosition works:
var roundedRemainder = function(numer, denom) {
return numer - (Math.round(numer / denom) * denom);
}
$(function() {
var gridSize = 50;
$(".draggable")
// Enable grid usage
.draggable({
grid: [gridSize, gridSize]
})
.position({
my: "left top", // Unchanging reference point on draggable object
at: "left top", // Unchanging reference point on reference object
of: "#parent", // The object that you want to move items with respect to.
using: function(position, data) {
var newPositions = {
// Get the difference between the "imaginary grid" and the current grid
left: function() {
return roundedRemainder(position.left, granularity);
},
top: function() {
return roundedRemainder(position.top, granularity);
}
}
// Move to the imaginary grid
$(this).css(newPositions);
}
})
});
The first JavaScript is trying to change the position of the block once dragging starts, to snap it to the imaginary grid. The second does this automatically upon loading of the page, but never again. If I were to change the imaginary grids granularity from 50 to 79, for instance, dragging would not bring the objects back onto the grid as desired.
Is there somewhere I could look to learn how to do this? Is it doable?
To clarify:
JQuery = 1.10.2 (Same as in JQuery UI demo's)
JQuery UI = 1.11.4 (Same as in JQuery UI demo's)
Browser = Firefox on Ubuntu 14.04, everything up to date
I've already been through Google, but either terms akin to "start", "drag" and "position" aren't unique enough to narrow things down, or I haven't found the right place. I've also scoured through the JQuery (UI) archives.
Many thanks in advance!
Okay, so turns out there were a few examples of ignorance on my behalf. I'll go through them below to help others as well, but if you're just after a solution, then look no further:
var roundedRemainder = function(numer, denom) {
if (denom > 1) // Only calculate when there is a chance the draggable isn't on the grid.
return numer - (Math.round(numer / denom) * denom); // Note: denom = 0 is invalid.
else
return 0; // If denom is invalid, or 1, then assume the draggable is on the grid.
}
$(function() {
var gridSize = 79;
var _this = this;
$(".draggable")
.draggable({
// Enable grid constraints
grid: [gridSize, gridSize],
// At start of dragging (aka, only do once at the beginning)
// snap the draggable object onto its parents grid.
drag: function(event, ui) {
var gridOffsetLeft;
var gridOffsetTop;
ui.helper.position({
my: "left top", // For the top left of the draggable object
at: "left top", // Link to the top left of the reference object
of: $(this).parent(), // Make the reference object the parent of the draggable object
// Calculate the grid offset from where the object ORIGINATED from
using: function(position, data) {
gridOffsetLeft = roundedRemainder(position.left, gridSize);
gridOffsetTop = roundedRemainder(position.top, gridSize);
}
});
// Calculate the total offset based off of the current
// location of the draggable object, and the previously
// calculated offset.
gridOffsetLeft -= roundedRemainder(ui.position.left, gridSize);
gridOffsetTop -= roundedRemainder(ui.position.top, gridSize);
// Apply offsets & hence snap the draggable onto the
// parents grid.
ui.position.left += gridOffsetLeft;
ui.position.top += gridOffsetTop;
}
})
});
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script type="text/javascript" src="jquery-1.10.2.js"></script>
<script type="text/javascript" src="jquery-ui.js"></script>
<script type="text/javascript" src="dragger.js"></script>
</head>
<body>
<div id="parent">
<svg width="300" height="100" class="draggable" id="number1">
<rect x="0" y="0" rx="10" ry="10" width="300" height="100" style="fill:rgb(121,0,121);stroke-width:3;stroke:rgb(0,0,0);">
</svg>
<svg width="300" height="100" class="draggable" id="letterA">
<rect x="0" y="0" rx="100" ry="10" width="300" height="100" style="fill:rgb(0,121,121);stroke-width:3;stroke:rgb(255,0,0);">
</svg>
</div>
</body>
</html>
Bugs:
The first bug was in the way I was trying to separate the positioning function away from the dragging function. Specifically, when trying to send then over. I've not really understood this yet which is why it isn't in the solution, however I did read (and lost the link) a stack overflow which mentioned using var _then = then;, or using a binding method. If I find the link I'll edit the answer.
The next bug relates to my specification of "at start". What I wanted as a method to only snap to the parent grid at the beginning of each drag. Thus, is sounded logical to use the start: or .on("dragstart", ...) functionality, as per the documentation. This lead into a preventDefault issue whereby either the start command was ignored, hence no snapping, but I could drag, or if I used event.preventDefault at the beginning of start, it would snap but no longer drag. Turns out that the drag: functionality only runs at the beginning of the drag once (please correct me if I'm wrong). By putting the snapping function back in there, another bug was solved.
Finally, my original logic for snapping to the grid was faulty. It worked when using it just the once, but as soon as it was run every time the object was dragged, it would "creep" a little bit on every drag. This is because the "snap" functionality worked from the ORIGINAL location of the dragged object to the parent. As such, just adding that difference on every time, even when the object is already snapped, caused an error. To resolve this I simply took the difference from the original to current location of the object, to an identical grid centered on the original location of the object.
(To be clear, there are 3 reference locations, the parent, the original location of the dragged object, and the current location of the dragged object).
I haven't been able to calculate the click coordinates (x and y) relative to the element triggering the event. I have not found an easy example online.
I have a simple svg (with 100px left margin) in an HTML page. It contains a group (translated 30px 30px) which has an onclick listener attached. And inside that group I have a rect with 50px width and height.
After I click any part of the group element, I get an event object with coordinates relative to the HTML page (evt.clientX and evt.clientY).
What I need to know is where exactly the user clicked inside the group element (the element holding the onclick listener).
How do I convert clientX and clientY coordinates to the group element coordinates. So say, if I click the top leftmost part of the rect it should give me x=0 and y=0.
Here is currently what I have:
<!DOCTYPE html>
<html>
<head>
<style>
body{
background:black;
}
svg{
fill:white;
background:white;
position: absolute;
top:100px;
left:100px;
}
</style>
<script>
function clicked(evt){
alert("x: "+evt.clientX+" y:"+evt.clientY);
}
</script>
</head>
<body>
<div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<g transform="translate(30 30)" onclick="clicked(evt)">
<rect x="0" y="0" width="50" height="50" fill="red"/>
</g>
</svg>
</div>
</body>
</html>
Tolokoban's solution has the limitation that it doesn't work if your viewBox deviates from the default, that is if it is different from viewBox="0 0 width height". A better solution that also takes viewBox into account is this:
var pt = svg.createSVGPoint(); // Created once for document
function alert_coords(evt) {
pt.x = evt.clientX;
pt.y = evt.clientY;
// The cursor point, translated into svg coordinates
var cursorpt = pt.matrixTransform(svg.getScreenCTM().inverse());
console.log("(" + cursorpt.x + ", " + cursorpt.y + ")");
}
(Credit goes to Smerk, who posted the code)
If the viewBox is not set or set to the default, this script will return the same values as Tolokoban's script. But if you have an SVG like <svg width="100px" height="100" viewBox="0 0 200 200">, only this version will give you the correct results.
Try to use getBoundingClientRect(): http://jsfiddle.net/fLo4uatw/
function clicked(evt){
var e = evt.target;
var dim = e.getBoundingClientRect();
var x = evt.clientX - dim.left;
var y = evt.clientY - dim.top;
alert("x: "+x+" y:"+y);
}
The proposed solutions are great, but they won't work in all scenarios.
The OP's post is titled
How to get the click coordinates relative to SVG element holding the
onclick listener?
So if you put the onclick listener onto your root svg element, whenever you click on any of its child elements, getBoundingClientRect will give you the child's Rect and you won't get the click coordinates relative to the root svg.
This was my case as I needed the coordinates relative to the root at all times, and the solution that worked for me was to use e.target.farthestViewportElement. Here's an excerpt from my (JSX) code:
const onClickSvg = e => {
const { farthestViewportElement: svgRoot } = e.target;
const dim = svgRoot.getBoundingClientRect();
const x = e.clientX - dim.left;
const y = e.clientY - dim.top;
console.log(`x: ${x}, y: ${y}`);
};
<svg onClick={onClickSvg}>...</svg>
Adding notes after many researchs (and fails!).
For a css translated svg, to get the coordinates of a clicked point for drawing.
In my case, using a mouse wheel event to translateX, so the actual rendering depends of the screen size and of the actual translated value.
I recommend for your use case to make a little drawing like the following, it will help a lot for figuring out what's going on.
Let's say my svg has for id: shoke
To get the total computed width, in pixels:
shoke.getBoundingClientRect()["width"]
Need to know the actual translateX value. (From the right, so it is a negative number, on this case)
shoke.style.transform.substr(11).slice(0,-3)
Note that it return a string and not an integer, so:
+shoke.style.transform.substr(11).slice(0,-3)
Now to get the coordinates of the mouse, related to the pixel x0 of the screen.
let pt = document.querySelector('svg').createSVGPoint();
pt.matrixTransform(shoke.getScreenCTM().inverse())["x"]
So, at the end, to obtain the precise x point:
svg_width - (svg_width + translated) + from_pixel x0 of the screen_click
Is something like this:
shoke.getBoundingClientRect()["width"] - (shoke.getBoundingClientRect()["width"] + +shoke.style.transform.substr(11).slice(0,-3)) + pt.matrixTransform(shoke.getScreenCTM().inverse())["x"]
createSVGPoint is deprecated according to Mozilla. Use static method of DOMPoint.fromPoint(svg_element);
function dom_track_click(evt) {
//<svg onclick='dom_track_click(event); >
let pt = DOMPoint.fromPoint(document.getElementById('svg_canvas'));
pt.x = evt.clientX;
pt.y = evt.clientY;
// The cursor point, translated into svg coordinates
let cursorpt = pt.matrixTransform(document.getElementById('svg_canvas').getScreenCTM().inverse());
console.log("(" + cursorpt.x + ", " + (cursorpt.y) + ")");
}
I have an SVG document where I have used javascript to implement the zoom and pan functionality [adapted from Andrea Leofreddi's SVGPan library]. The SVG itself has an anchor element which should launch a separate url. My problem is that since the onclick event has been trapped for zoom and pan the href on the anchor is not reached. How can I insulate the anchor from the onclick trap?
In the code below, when I click on the text "Kitchen Sink" I would like to launch the url attached to it rather than entering the zoom and pan mode:
Code fragments:
SVGLib.js:
...
setupHandlers(root);
function setupHandlers(root){
setAttributes(root, {
"onclick" : "handleClick(evt)"
});
root.addEventListener('DOMMouseScroll', handleMouseWheel, false);
}
function handleClick(evt) {
if(evt.preventDefault)
evt.preventDefault();
evt.returnValue = false;
var svgDoc = evt.target.ownerDocument;
var g = getRoot(svgDoc);
// Get the click location
// If key button clicked with shift key down, reset
if (evt.shiftKey == 1) {
setCTM(g, root.createSVGMatrix());
shiftX = initShiftX;
shiftY = initShiftY;
}
else {
var ctm = g.getCTM();
var ctmInv = ctm.inverse();
var newctm = g.getCTM();
// showMatrix('before: ', newctm);
shiftX = shiftX - (evt.clientX - initShiftX);
shiftY = shiftY - (evt.clientY - initShiftY);
newctm.e = shiftX * vbCTMInv.a;
newctm.f = shiftY * vbCTMInv.d;
// bring in the scale factors from the vbCTMInv -- because scaling will apply automatically via the vb transform
newctm.a = newctm.a*vbCTMInv.a;
newctm.d = newctm.d*vbCTMInv.d;
// showMatrix('after: ', newctm);
setCTM(g, newctm);
}
}
doc.html:
<html>
...
<svg>
...
<g id="g33" style="fill: none; stroke: green">
<a xlink:href="/cgi-bin/qbui/drive.pl?sqlHandle=693F1DB6-6C7F-11E1-8475-31DDD99CA768">
<text id="t2769800058" style="text-anchor: middle; font-family: Verdana; font-size: 10px" x="600" y="1300">Kitchen Sink</text>
</a>
</g>
...
</svg>
</html>
Update:
I have figured out a work-around which I can use to detect the event target and take appropriate action. The id is the SVG text element's id if "Kitchen Sink" is clicked. Of course this requires some change in the code but it is do-able.
In handleClick():
if (evt.target.id == ...) {
...
}
You could check if the href value of evt.target is has a value and if it has follow it
function handleClick(evt) {
if(evt.target.href){
window.location = evt.target.href;
}
I have a standalone SVG file and a separate Javascript file to deal with mouse events triggered from the SVG file. The projects works well with Firefox but somehow I got problems with IE when managing mouse events: I get this error message:
"clientx is null or not an object".
The SVG image is printed OK though.
Do you have any idea what's wrong with my code (see below)?
SVG document
<?xml version="1.0" standalone="no"?>
<svg width="1100" height="5990" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)" >
<script xlink:href="desc.js"/>
<g onmouseout="h(evt)">" stroke-width="1"/>
<polygon points="35,20 86,20 96,35 86,50 35,50" style="fill:grey" onmousemove="s(evt,'someTxt')" onclick="m(evt, 'NGR_a00010')"/>
<polygon points="99,20 138,20 148,35 138,50 99,50" style="fill:grey" onmousemove="s(evt,'someTxt someTxt')" onclick="m(evt, 'NGR_a00020')"/>
</g>
<rect class="tooltip_bg" id="tooltip_bg" x="0" y="0" rx="4" ry="4" width="55" height="17" visibility="hidden"/>
<text class="tooltip" id="tooltip" x="0" y="0" visibility="hidden">Tooltip</text>
</svg>
Javascript
function init(evt)
{
if ( window.svgDocument == null )
{
svgDocument = evt.target.ownerDocument;
}
tooltip = svgDocument.getElementById('tooltip');
tooltip_bg = svgDocument.getElementById('tooltip_bg');
}
function s(evt, mouseovertext)
{
var posx = 0;
var posy = 0;
if (!evt) var e = window.event;
if (evt.pageX || evt.pageY) {
posx = evt.pageX;
posy = evt.pageY;
}
else if (e.clientX || e.clientY) {
posx = evt.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft;
posy = evt.clientY + document.body.scrollTop
+ document.documentElement.scrollTop;
}
tooltip.setAttributeNS(null,"x",posx+11);
tooltip.setAttributeNS(null,"y",posy+27);
tooltip.firstChild.data = mouseovertext ;
tooltip.setAttributeNS(null,"visibility","visible");
length = tooltip.getComputedTextLength();
tooltip_bg.setAttributeNS(null,"width",length+8);
tooltip_bg.setAttributeNS(null,"x",posx+8);
tooltip_bg.setAttributeNS(null,"y",posy+14);
tooltip_bg.setAttributeNS(null,"visibility","visibile");
}
function h(evt)
{
tooltip.setAttributeNS(null,"visibility","hidden");
tooltip_bg.setAttributeNS(null,"visibility","hidden");
}
function g(evt, locus_tag)
{
window.open("http://www.ncbi.nlm.nih.gov/gene?term=" + locus_tag);
}
function m(evt, txt)
{
if (evt.type == "click" && evt.detail == 2)//if we got a double click, for some reason onblclick does not work
{
window.open("http://www.ncbi.nlm.nih.gov/gene?term=" + txt);
}
}
IE8 doesn't support SVG.
There are Javascript tools available to help with that, but natively it doesn't support it.
Of the tools I mentioned, my favourite is Raphael, but Raphael is a library for drawing the graphics; since you already have the SVG in your code, you may find a simple conversion library is more useful. Something like one of these perhaps: http://code.google.com/p/svg2vml/ or this: http://code.google.com/p/svgweb/
Since you say that the SVG images are working in your page, I would say that you're probably already using one or other of these tools (possibly one of the ones I linked above, possibly another one -- there's quite a few of them). But my guess would be that the tool you're using doesn't include support for manipulating the SVG object with Javascript.
You may therefore need to try another tool if you want this feature.
As Spudley's answer says, IE8 doesn't support SVG.
If the image is appearing on your page, thereare a few possibilities:
Something in your development stack may be converting it to a raster image (such as a PNG): right click the image and select "Properties", then see what value is reported for "Type".
You may have a browser plugin installed that renders SVGs (but does not provide the JavaScript interface). Try running IE8 in Safe Mode.
Internet Explorer 9 does support SVG, however, so an IE upgrade, where possible, will solve that problem.