I have a SVG with three rectangles
Why are the rectangles appearing in the node-list of the console?
<script>
const rects = document.querySelectorAll("rect");
console.log(rects);
<!--
for(let i=0;i<rects.length; i++) {
console.log(`Rectangle ${i} is ${rect[i].getTotalLength()`);
}
-->
</script>
</defs>
<rect x="100" y="0" width="100" height="100" opacity="1" fill-opacity="0" stroke="#ff0043" stroke-width="1" stroke-opacity="1" />
<rect x="300" y="0" width="100" height="300" opacity="1" fill-opacity="0" stroke="#ff0043" stroke-width="1" stroke-opacity="1" />
<rect x="500" y="0" width="100" height="400" opacity="1" fill-opacity="0" stroke="#ff0043" stroke-width="1" stroke-opacity="1" />
</svg>
Please validate your HTML code to ensure that it is valid.
sure
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style>
path,rect {
stroke:#000;
stroke-dasharray: 2072;
stroke-width:3;
animation: my_animation 3s;
animation-fill-mode: forwards;
fill: red;
}
@keyframes my_animation{
0%{
stroke-dashoffset: 2072;
fill-opacity: 0;
}
80%{
stroke-dashoffset: 0;
fill-opacity: 0;
}
100%{
fill-opacity: 1;
}
}
</style>
<script>
const rects = document.querySelectorAll("rect");
console.log(rects);
<!--
for(let i=0;i<rects.length; i++) {
console.log(`Rectangle ${i} is ${rect[i].getTotalLength()`);
}
-->
</script>
</defs>
<rect x="100" y="0" width="100" height="100" opacity="1" fill-opacity="0" stroke="#ff0043" stroke-width="1" stroke-opacity="1" />
<rect x="300" y="0" width="100" height="300" opacity="1" fill-opacity="0" stroke="#ff0043" stroke-width="1" stroke-opacity="1" />
<rect x="500" y="0" width="100" height="400" opacity="1" fill-opacity="0" stroke="#ff0043" stroke-width="1" stroke-opacity="1" />
</svg>
Your script is before the rects. They dont exist at time of execution. Wrap your script in a onload, or move it below the rects.
3 Likes
I moved it below, heres the output
I’m trying to find the total length of each rect for the animation, but when I uncomment the for loop I get
heres the svg
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style>
rect {
stroke:#000;
stroke-dasharray: 2072;
stroke-width:3;
animation: my_animation 3s;
animation-fill-mode: forwards;
fill: red;
}
@keyframes my_animation{
0%{
stroke-dashoffset: 2072;
fill-opacity: 0;
}
80%{
stroke-dashoffset: 0;
fill-opacity: 0;
}
100%{
fill-opacity: 1;
}
}
</style>
</defs>
<rect x="100" y="0" width="100" height="100" opacity="1" fill-opacity="0" stroke="#ff0043" stroke-width="1" stroke-opacity="1" />
<rect x="300" y="0" width="100" height="300" opacity="1" fill-opacity="0" stroke="#ff0043" stroke-width="1" stroke-opacity="1" />
<rect x="500" y="0" width="100" height="400" opacity="1" fill-opacity="0" stroke="#ff0043" stroke-width="1" stroke-opacity="1" />
<defs>
<script>
const rectangles = document.querySelectorAll('rect');
console.log(rectangles);
console.log(rectangles.length);
for(let i=0;i<rectangles.length; i++) {
console.log(`Rectangle ${i} is ${rectangles[i].getTotalLength()});
}
</script>
</defs>
</svg>
what is wrong with the for loop?
What’s wrong with the attribute name?
This is an odd quirk of how SVG handles script tags.
You can’t use a less than symbol; SVG thinks you’re starting a tag; so it sees the code as starting a tag that reads:
<rectangles.length; i++)
and throws a fit because that’s not a valid attribute definition for an HTML tag.
The solution is to inverse the logic: Check to see that i is not greater than or equals to the length. (or the contrapositive instead: Check that the length is greater than i)
The script should be moved to the end of the body, just before the </body>
tag.
That’s where scripts belong, and fixes all of the problems that have been occurring.
Oh no, but this isn’t html, so @m_hutley has the right approach.
Here you go. Use the forEach method instead of the for loop, and the code now works.
rectangles.forEach(function (rectangle, i) {
console.log(`Rectangle ${i} is ${rectangle.getTotalLength()}`);
});
1 Like
system
Closed
December 12, 2019, 5:21pm
10
This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.