One complete answer, due to @herrstrietzel above, is to embed the svg in an html page which responds to a uri query. We can avoid using a server by faking the response in javascript.
Given answer.html
below, visiting answer.html?sq=black brings the black square into view, as required.
answer.html:
<!DOCTYPE html>
<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
body
{
width: 20em;
height: 10em;
text-align: left;
}
</style>
<script type="text/javascript">
function init()
{
var sp = location.search;
if (sp.substr(1,2)=='sq')
{
targ = sp.substr(4);
// alert(targ);
scrollToSVGEl(targ);
}
}
function scrollToSVGEl(targetId) {
let target = targetId ? document.getElementById(targetId) : '';
if (!target) return false;
let {
top,
left
} = target.getBoundingClientRect()
let x = left + window.scrollX;
let y = top + window.scrollY;
window.scrollTo({
top: y,
left: x,
behavior: 'smooth'
});
}
// override default link behaviour
let links = document.querySelectorAll('.aSvg')
links.forEach(lnk => {
lnk.addEventListener('click', e => {
e.preventDefault();
targetId = e.currentTarget.href.split('#').slice(-1)
window.location.hash = targetId;
scrollToSVGEl(targetId)
})
})
</script>
</head>
<body onload=init()>
<svg
xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
version="1.1" width="6000" height="6000" y="0" x="0">
<rect id="black" fill="black" height="100" width="100" y="50" x="5500">
</rect>
<text y="50" x="5500">black</text>
<rect id="red" fill="red" height="100" width="100" y="5500" x="5500">
</rect>
<text y="5500" x="5500">red</text>
<g id="green">
<rect fill="green" height="100" width="100" y="5500" x="50">
</rect>
<text y="5500" x="50">green</text>
</g>
</svg>
</body>
</html>