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 |2 Answers
Reset to default 1You 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>
<object>
. You would first need to wait for a load event and then access the object content. – herrstrietzel Commented Jan 19 at 17:55