skip to Main Content

I know this is not new and I’ve found a couple of hints how to solve it. But I cannot get rid of it. This is my simple code:

<!doctype html>
<html lang="de">
    <head>
        <title>SVG Test</title>
    </head>
    <body>
        <h1>Select a circle</h1>
        <object id="svg-object" data="circle.svg" width="200" height="200"></object>

        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400">
            <circle id="circle" class="svg-element" cx="50" cy="50" r="40" />
        </svg>

        <script>
            // do this if selected
            function handleClick(elementId) {
                alert('"' + elementId + '" selected');
            }

            // event listener
            document.getElementById("circle").addEventListener("click", function () {
                handleClick("circle");
            });

            // event listener
            document.getElementById("circle_in_svg").addEventListener("click", function () {
                handleClick("circle_in_svg");
            });
        </script>
    </body>
</html>

This shows two circles.
The svg-file "circle.svg" has exactly the same content as the three lines below <object ….>. Only the id is changed from "circle" to "circle_in_svg".

So, this is the situation:

  • < script >… is below < object >… i.e. "circle_in_svg" should be known.
  • The two circles are shown in the correct order: first the circle in the file, second the circle inline.
  • ‘defer’ or ‘async’ doesn’t help. Btw: omitting both means for me: load the file and proceed after the file is loaded, so the id should be available.

After loading this page I get the error (F12 in mozilla): "Uncaught TypeError: document.getElementById(…) is null". And as a matter of course it doesn’t work as intended…

Any help?

2

Answers


  1. For the SVG element in the HTML document you just refer to the function name in the addEventListener, and then the element is the e.target and it has an id property.

    And for the SVG element inside the <object>, you need to wait for circle.svg to load and then you can access the document (contentDocument) and find the circle_in_svg. It is important that this is running from a web server, not from the file system to work.

    <!doctype html>
    <html lang="de">
    
    <head>
      <title>SVG Test</title>
      <script type="text/javascript">
        document.addEventListener('DOMContentLoaded', e => {
          let object = document.getElementById('svg-object');
    
          object.addEventListener('load', e => {
            e.target.contentDocument.getElementById("circle_in_svg")
              .addEventListener("click", handleClick);
          });
        });
      </script>
    </head>
    
    <body>
      <h1>Select a circle</h1>
      <object id="svg-object" data="circle.svg" width="200" height="200"></object>
    
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400">
        <circle id="circle" class="svg-element" cx="50" cy="50" r="40" />
      </svg>
      <script>
        // do this if selected
        function handleClick(event) {
          alert('"' + event.target.id + '" selected');
        }
    
        // event listener
        document.getElementById("circle").addEventListener("click", handleClick);
      </script>
    </body>
    
    </html>
    Login or Signup to reply.
  2. You are trying to find element with id circle_in_svg but you have only circle id and svg-object. So you need to change id for your object element to circle_in_svg or change id to find to svg-object

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search