gct
gct

Reputation: 14573

Selecting elements by attribute in javascript, where attribute name has colon?

I'm trying to write a quick blurb of javascript to animate layers from the SVG files generated by Inkscape. Inkscape is nice enough to set the inkscape:groupmode attribute to "layer" for layer groups:

<g
   transform="translate(-12.681101,-9.7947913)"
   id="g2179"
   inkscape:groupmode="layer"
   inkscape:label="Frame 2"
   style="display:inline"
>

So I wrote a little script to find all those nodes, hide them, and then show them one by one in a loop with a delay:

<script type="text/javascript">
    <![CDATA[
        var layers;
        var current = 0;

        // show one at a time
        function animate() {
            if (layers.length > 0) {
                layers[current].style.display = "none";
                current = (current+1) % layers.length;
                layers[current].style.display = "inline";
            }
        }

        // on load, get layers and hide them
        function init() {
            layers = document.querySelectorAll("g[inkscape\\:groupmode='layer']");
            alert(layers.length);

            // hide all layers
            for (var ii=0; ii < layers.length; ii++) {
                layers[ii].style.display = "none";
            }

            setInterval(animate, 500);
        }
    ]]>
  </script>

Where init() is called by onload on the svg element:

<svg onload="init()">

Unfortunately, the querySelectorAll call returns a layers array that's empty (alert shows '0'). I can query all the group elements by removing the attribute identifier, but that's not what I want.

How do I select just the elements that are layers?

Edit: Full example, this pops up "0" in Firefox 71.0, and Chrome 79.0.3945.79 on Linux:

<svg
   onload="init()"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="79.63958mm"
   height="79.63958mm"
   viewBox="0 0 79.63958 79.63958">

  <script type="text/javascript">
    <![CDATA[
        var layers;
        var current = 0;

        // show one at a time
        function animate() {
            if (layers.length > 0) {
                layers[current].style.display = "none";
                current = (current+1) % layers.length;
                layers[current].style.display = "inline";
            }
        }

        // on load, get layers and hide them
        function init() {
            layers = document.querySelectorAll("g[inkscape\\:groupmode='layer']");
            alert(layers.length);

            // hide all layers
            for (var ii=0; ii < layers.length; ii++) {
                layers[ii].style.display = "none";
            }

            setInterval(animate, 500);
        }
    ]]>
  </script>

  <g
     inkscape:label="Frame 1"
     inkscape:groupmode="layer"
     id="layer1"
     transform="translate(-12.681101,-9.7947913)"
     style="display:inline">
  </g>
</svg>

Upvotes: 0

Views: 346

Answers (1)

Alessandro Aguilar
Alessandro Aguilar

Reputation: 401

You can't select get element by that type of querySelector, but you can try filtering, the G elements that you need

const g = document.querySelectorAll('g')
const layers = Array.from(g)
    .filter(g => g.getAttribute('inkscape:groupmode') === 'layer')

Upvotes: 3

Related Questions