SVG:链接到包含文档中的位置

时间:2017-03-29 08:17:31

标签: html css svg

我目前正在开发一个使用基于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将来可能会发生变化。

有办法做到这一点吗?

提前致谢

1 个答案:

答案 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'
}));

Live plunker

使用PostMessage API进行过度保护的iframe的解决方法:

div {
  margin-top: 100vh;
}
<object data="file.svg"></object>
<div id="loc1">loc1</div>
<div id="loc2">loc2</div>
{{1}}