我目前正在开发一个使用基于SVG的地图的网站,其中包含可点击的点。理想情况下,我希望这些地图指向HTML文档中包含它的位置(每个区域一个)。
HTML:
<object type="image/svg+xml" data="https://ffu.jmaris.me/carte.svg">
Your browser does not support SVG
</object>
<div id="region1" class="region"> Stuff ...</div>
<div id="region2" class="region"> Stuff ...</div>
<div id="region3" class="region"> Stuff ...</div>
<div id="region4" class="region"> Stuff ...</div>
CSS:
.region {display:none;}
.region div:target{display:block;}
我希望能够在不使用绝对路径的情况下指向我的SVG内的page.html#region2(因为它当前在开发服务器上运行,此外,在部署之后,URL将来可能会发生变化。
有办法做到这一点吗?
提前致谢
答案 0 :(得分:2)
你必须在这里依赖javascript。
<object>
内的锚点(<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" width="100" height="100" viewBox="0 0 100 100">
<a id="loc1" xlink:href="#">
<rect x="0" y="0" width="20" height="20" fill="green"/>
</a>
<a id="loc2" xlink:href="#">
<rect x="50" y="0" width="20" height="20" fill="red"/>
</a>
<script>
var anchors = document.querySelectorAll('a');
anchors.forEach(function(a){
a.addEventListener('click', function(e){
// where anchor's id represent parent doc element's ids.
window.parent.location.hash = this.id;
});
});
</script>
</svg>
)会更改对象文档的位置,因此我们无法直接使用它。
但是,如果您的文件共享相同的源,并且您没有在像stacksnippets™这样的过度保护的iframe中运行整个文件,则可以非常轻松地访问父文档:
window.onmessage = e => {
// you may want to be sure this is the message you want
window.location.hash = e.data;
}
// here it would be saved as an external file
document.querySelector('object').data = URL.createObjectURL(new Blob([`
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100" height="100" viewBox="0 0 100 100">
<a id="loc1" xlink:href="#">
<rect x="0" y="0" width="20" height="20" fill="green"/>
</a>
<a id="loc2" xlink:href="#">
<rect x="50" y="0" width="20" height="20" fill="red"/>
</a>
<script>
var anchors = document.querySelectorAll('a');
anchors.forEach(function(a){
a.addEventListener('click', function(e){
// post our #id
window.parent.postMessage( this.id, '*' );
});
});
<\/script>
</svg>
`], {
type: 'image/svg+xml'
}));
使用PostMessage API进行过度保护的iframe的解决方法:
div {
margin-top: 100vh;
}
<object data="file.svg"></object>
<div id="loc1">loc1</div>
<div id="loc2">loc2</div>
{{1}}