最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Uncaught TypeError: document.getElementById(...) is null - order of elements are ok, id is known - Stack Overflow

programmeradmin2浏览0评论

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="; 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?

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?

Share Improve this question asked Jan 19 at 17:21 imartiimarti 112 bronze badges 2
  • You can't directly access elements within an <object>. You would first need to wait for a load event and then access the object content. – herrstrietzel Commented Jan 19 at 17:55
  • "'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." - those two attributes apply to script elements, not to objects. – C3roe Commented Jan 20 at 8:53
Add a comment  | 

2 Answers 2

Reset to default 1

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

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>

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论