Skip to main content
April 27, 2019
Question

Question - How to trigger javascript hyperlinks in an SVG?

  • April 27, 2019
  • 1 reply
  • 2345 views

I need to present facsimile copies of articles I've written, with clickable links, on my portfolio webpage.The approach that seems likeliest to work is imagemaps in svgs, because the hyperlink retains its position on the image as the image responds to different screen sizes.


Using svgs, I've succeeded in making responsive images with links, embedded in another page. Now my problem is to make those links trigger a javascript plugin (Floatbox) that presents overlays.

The overlays are important, because they're my best option for keeping readers on the page. I don't want them opening new pages to read a footnote. I want them to be able to glance at important but secondary material, close it, and return to what they were reading before.

I can't get the javascript calls required for such overlays to work, and in fact I keep breaking the imported .svg when I try to change the code.

Ordinarily, I'd trigger such a link with something like this:

    <a href="LinkFromFacsimileStoryImage.html" class="floatbox" data-fb-

    options="width:80% height:80% scrolling:yes">LinkName</a>

Suffice it to say that I have no idea why adobe isn't presenting the code. I followed the guidelines for pasting it in, and it is showing up on my screen as I edit the draft. But I don't see it when I post the question.
So here's what the page ought to be presenting:

          <a href="website/" class="floatbox" data-fb-
          options="width:80% height:80% scrolling:yes">Website Function</a>

The code doesn't work in an .svg. In hopes that some browsers may actually present the code, here's how I have a sample page set up now, with a greatly truncated representation of the imported image, just for context, and the link presented in its native (unaltered) state:

    <!doctype html>

    <html>

    <head>

    <meta charset="UTF-8">

    <title>Declaration</title>

    <link type="text/css" rel="stylesheet" href="floatbox/floatbox.css" />

    <script type="text/javascript" src="floatbox/floatbox.js"></script>

    </head>

    <body>

        <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"

    viewBox="0 0 882.5 245.9" style="enable-background:new 0 0 882.5 245.9;" xml:space="preserve">

    <style type="text/css">

    .st0{opacity:0.35;fill:#FFFFFF;stroke:#000000;stroke-miterlimit:10;}

    </style>

    <image style="overflow:visible;" width="750" height="209" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAu4AAADRCAYAAACTrj

    WiZHqpWs2ra3VpcUIHa9SXqqpTl7bIMTyBQNNl13NkAT59pgAWq1evp/A/lH6dv6rBKPAAAAAElF

    TkSuQmCC" transform="matrix(1.1767 0 0 1.1767 0 0)">

    </image>

    <a xlink:href="https://www.loc.gov/resource/rbc0001.2004pe76546/?sp=1" >

    <rect x="94.5" y="67.5" class="st0" width="773" height="55"/>

    </a>

    </svg>

    </body>

    </html>

In case they don't, my mockup of the state of the project as it stands now may be found at https://codepen.io/ChrisRichard/pen/qwLMEL

However, it doesn't look like I can post the plugin's javascript and CSS there because they're proprietary. I'll see what I can do about alternatives on that. Meanwhile, somebody could certainly edit in a different javascript call that I and others could extrapolate from, and I've saved the project as a template to facilitate that.

I should point out that there's a lot I don't know about the language of coding. I'm self-taught. So the more specific the suggestions, the better.

Thanks in advance for any suggestions.

This topic has been closed for replies.

1 reply

B i r n o u
Legend
April 27, 2019

well, I must admit that your mail being pretty long, I'm not sure to quite understand what is your aim... so sorry if I missed your point and answer beside your question.

having hyperlink in SVG , being hyperlink, or JavScript driven, is pretty easy.

two points

one, if it's a pure hyperlink, you need to use a binding to the xlink namespace and use an xlink:href attribute instead of a simple href

second, if it's a JavaScript firing, you first need to load the associative script, be sure that the script load after the document (if needed and if you don't use an event attribute)

you can also use illustrator to handle everything (except the pure javascript file)

here is an SVG file, and a JS file

SVG

<?xml version="1.0" encoding="utf-8"?>

<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"

     viewBox="0 0 977 196" style="enable-background:new 0 0 977 196;" xml:space="preserve">

<style type="text/css">

    .st0{fill:#72B7AE;}

    .st1{font-family:'MyriadPro-Regular';}

    .st2{font-size:30.5828px;}

    .st3{fill:#86BA68;}

    .st4{fill:#DBAE56;}

</style>

<defs>

    <script  xlink:href="scripts.js"  language="JavaScript">

    </script>

</defs>

<g id="hyperlink">

    <g>

        <rect x="24.5" y="23.5" class="st0" width="252" height="148"/>

        <path d="M276,24v147H25V24H276 M277,23H24v149h253V23L277,23z"/>

    </g>

    <text transform="matrix(1 0 0 1 90.1709 97.3389)" class="st1 st2">hyperlink</text>

</g>

<g id="JavaScript">

    <g onclick="clikedJavaScript(&quot;From Attribute&quot;)">

        <rect x="364.5" y="23.5" class="st3" width="252" height="148"/>

        <path d="M616,24v147H365V24H616 M617,23H364v149h253V23L617,23z"/>

    </g>

    <text onclick="clikedJavaScript(&quot;From Attribute&quot;)" transform="matrix(1 0 0 1 430.688 82.3389)"><tspan x="0" y="0" class="st1 st2">JavaScript</tspan><tspan x="-30.9" y="36.7" class="st1 st2">event attribute</tspan></text>

</g>

<g id="Listener">

    <g>

        <rect x="697.5" y="23.5" class="st4" width="252" height="148"/>

        <path d="M949,24v147H698V24H949 M950,23H697v149h253V23L950,23z"/>

    </g>

    <text transform="matrix(1 0 0 1 763.688 82.3389)"><tspan x="0" y="0" class="st1 st2">JavaScript</tspan><tspan x="-22.1" y="36.7" class="st1 st2">event listener</tspan></text>

</g>

</svg>

JS (file called scripts.js)

function clikedJavaScript(arg){

    alert("cliked on object " + arg)

}

window.onload = function(){

    var node = document.querySelector('#Listener')

    node.addEventListener("click",function(){clikedJavaScript("From Listener")})

}

April 27, 2019

Well, thanks for taking this on. I recognize that it was a long post, and especially confusing because the website wouldn't display the code even though I used the format it stipulates. I'm also afraid that some of your response is going over my head. I'll try to explain where I'm confused here.

So I'm loading this .svg, imported from Illustrator, into an html page. I'll truncate most of the base64 encoded image, including just enough of it to show where it goes in the page as a whole, but to look at the whole thing, go to https://codepen.io/ChrisRichard/pen/qwLMEL

Here's the abbreviated version:

          <!doctype html>

     <html>

     <head>

     <meta charset="UTF-8">

     <title>Declaration</title>

     <link type="text/css" rel="stylesheet" href="floatbox/floatbox.css" />

     <script type="text/javascript" src="floatbox/floatbox.js"></script>

     </head>

     <body>

     <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"

     xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"

     viewBox="0 0 882.5 245.9" style="enable-background:new 0 0 882.5 245.9;" xml:space="preserve">

     <style type="text/css">

     .st0{opacity:0.35;fill:#FFFFFF;stroke:#000000;stroke-miterlimit:10;}

     </style>

     <image style="overflow:visible;" width="750" height="209" xlink:href="data:image/png;

     base64,iVBORw0KGgoAAAANSUhEUgAAAu4AAADRCAYAAACTrj

     WiZHqpWs2ra3VpcUIHa9SXqqpTl7bIMTyBQNNl13NkAT59pgAWq1evp/A/lH6dv6rBKPAAAAAElF

     TkSuQmCC" transform="matrix(1.1767 0 0 1.1767 0 0)">

     </image>

     <a xlink:href="https://www.loc.gov/resource/rbc0001.2004pe76546/?sp=1" >

     <rect x="94.5" y="67.5" class="st0" width="773" height="55"/>

     </a>

     </svg>
     </body>
     </html>

Ordinarily, I'd trigger such a link with something like this:

     <a href="LinkFromFacsimileStoryImage.html" class="floatbox" data-fb- options="width:80% height:80% 
     scrolling:yes">LinkName</a>

  But that doesn't work here. I can't figure out how to trigger the javascript. in fact, when I try to write that code into the .svg, it breaks the image.

I think you're telling me to do this:

          <!doctype html>

          <html>

          <head>

          <meta charset="UTF-8">

          <title>Declaration</title>

          <link type="text/css" rel="stylesheet" href="floatbox/floatbox.css" />

          <script type="text/javascript" src="floatbox/floatbox.js"></script>

          </head>

          <body>

         <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"

          viewBox="0 0 882.5 245.9" style="enable-background:new 0 0 882.5 245.9;" xml:space="preserve">

          <style type="text/css">

.          st0{opacity:0.35;fill:#FFFFFF;stroke:#000000;stroke-miterlimit:10;}

          </style>

          <defs>

           <script  xlink:href="floatbox/floatbox.js"  language="JavaScript">

            </script>

      

At this point I'd need to load an external stylesheet, too, but despite repeated Google searches, I can't figure out how.

Ordinarily, that stylesheet would be loaded on a regular html page as

          <link type="text/css" rel="stylesheet" href="floatbox/floatbox.css" />

How would I do it in the svg?  

Also, after this point in your explanation, I'm really confused. I gather that at least some of this code is supposed to load after the image does, but I'm confused about position.

I'm including my original code again, with the image still truncated but without any effort to insert new commands. Could you show me where they should go?

          <!doctype html>

          <html>

          <head>

          <meta charset="UTF-8">

          <title>Declaration</title>

          <link type="text/css" rel="stylesheet" href="floatbox/floatbox.css" />

          <script type="text/javascript" src="floatbox/floatbox.js"></script>

          </head>

          <body>

         <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"

          viewBox="0 0 882.5 245.9" style="enable-background:new 0 0 882.5 245.9;" xml:space="preserve">

          <style type="text/css">

          .st0{opacity:0.35;fill:#FFFFFF;stroke:#000000;stroke-miterlimit:10;}

          </style>

      

          <image style="overflow:visible;" width="750" height="209" xlink:href="data:image/png;
          base64,iVBORw0KGgoAAAANSUhEUgAAAu4AAADRCAYAAACTrj
          WiZHqpWs2ra3VpcUIHa9SXqqpTl7bIMTyBQNNl13NkAT59pgAWq1evp/A/lH6dv6rBKPAAAAAElF
          TkSuQmCC" transform="matrix(1.1767 0 0 1.1767 0 0)">

          </image>

          <a xlink:href="https://www.loc.gov/resource/rbc0001.2004pe76546/?sp=1" >

          <rect x="94.5" y="67.5" class="st0" width="773" height="55"/>

          </a>

          </svg>

          </body>

          </html>

And one final question. Some of the facsimile documents I'm talking about are very long, with  as many as 75 links to supporting documents. Would I have to insert the seemingly complex code you've outlined for every link, and could any of it be treated as boilerplate, or would each link require extensive individual modification?

I've also put up a second codepen showing how floatbox works: https://codepen.io/ChrisRichard/pen/WWPVPO

Thanks in advance and again, sorry for the very long post. I don't know how else to describe the problem or seek a solution.

Nancy OShea
Community Expert
Community Expert
April 27, 2019

This is not that complictaed.

#1 I've never used floatbox.  Almost every site I work with contains jQuery so I'm useing a popular jQuery pluign called Fancybox 3 for this demo.  If  used commercially, you must buy a license (single use = $29). https://fancyapps.com/fancybox/3/#license

#2 I am using an SVG path and data-src to pull images into the Fancybox viewer.  See Fancybox documentation for more info.

https://fancyapps.com/fancybox/3/docs/

Here is the entire code.

<!doctype html>

<html lang="en">

<head>

<meta charset="utf-8">

<title>Responsive SVG Image Map</title>

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1">

<!--latest Fancybox CSS-->

<link href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.2.5/jquery.fancybox.min.css" rel="stylesheet">

<style>

.container {

width: 70%;

margin: 0 auto

}

#myMap {

position: relative;

width: 100%;

padding-bottom: 77%;

vertical-align: middle;

margin: 0;

overflow: hidden;

}

#myMap svg {

display: inline-block;

position: absolute;

top: 0;

left: 0;

}

#myMap rect:hover { opacity: 1.0;}

</style>

</head>

<body>

<div class="container">

<h3>Responsive SVG Image Map with <a href="http://fancyapps.com/fancybox/3/" target="_blank">Fancybox 3 lightbox viewer</a></h3>

<p>Resize browser window & click or tap on vector shapes below. </p>

<figure id="myMap">

<svg version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" viewBox="0 0 1200 808" preserveAspectRatio="xMinYMin meet">

<!--bitmap background image-->

<image width="1200" height="800" xlink:href="https://dummyimage.com/1200x800.jpg"> </image>

<!--vector path & data-src-->

<rect path

data-fancybox="gallery" class="fancybox" data-slide="1" data-src="https://c1.staticflickr.com/1/357/31876784275_12286240d4_h.jpg" x="50" y="28" fill="#ff0" opacity="0.4" width="300" height="750" />

<!--2nd vector path & data-src-->

<rect path

data-fancybox="gallery" class="fancybox" data-slide="2" data-src="https://c1.staticflickr.com/9/8148/29324593462_abebaddc38_k.jpg"

x="440" y="28" fill="#f00" opacity="0.4" width="300" height="750"/>

<!--3rd vector path & data-src-->

<rect path

data-fancybox="gallery" class="fancybox" data-slide="3" data-src="https://c2.staticflickr.com/6/5499/30972532232_051e1dc57e_h.jpg" x="825" y="28" fill="#0ff" opacity="0.4" width="300" height="750"/>

</svg>

</figure>

</div>

<!--jQuery Core JS-->

<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>

<!--Fancybox 3 JS-->

<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.2.5/jquery.fancybox.min.js"></script>

<script>

//Invoke fancybox on page load

$( document ).ready( function () {

            $( '.fancybox' )

        } );

    </script>

</body>

</html>

Nancy O'Shea— Product User & Community Expert