0

I have the following Node class which I am using to create a custom element node-element.

class Node extends SVGCircleElement{
    static get observedAttributes() {
        return ["coordinates"];
      }
    constructor()
    {
        super();
        this.attributeMap = {coordinates:(coordinates)=>this.updateCoordinates(coordinates)}
    }
    connectedCallback(){
        this.initNode();
    }
    updateCoordinates(coordinates)
    {
        this.setAttribute("cx",`${coordinates.x}`);
        this.setAttribute("cy",`${coordinates.y}`);
        this.setAttribute("r",50);
    }
    initNode()
    {
        this.className="node";
    }
    attributeChangedCallback(name,oldValue,newValue)
    {
        if(oldValue!==newValue)
        {
            this.attributeMap[name](JSON.parse(newValue))
        }
    }
}

I register this element using:-

customElements.define('node-element',Node);

I am creating this element as follows:-

let newNode = document.createElement("node-element");

This is where I get the following error:-

Uncaught TypeError: Illegal constructor
    at new Node (index.js:9)
    at SVGSVGElement.drawNode (index.js:43)

Line 43 corresponds to the createElement code.

Lakshya Thakur
  • 8,030
  • 1
  • 12
  • 39

1 Answers1

2

Would love to be proven wrong, just spent 2 months on an SVG project

AFAIK, you can NOT extend SVG elements

You can only create Custom Elements in the HTML Namespace http://www.w3.org/1999/xhtml

SVG Elements are in the SVG Namespace http://www.w3.org/2000/svg

From the docs: https://html.spec.whatwg.org/multipage/custom-elements.html#element-definition

If the element interface for extends and the HTML namespace is HTMLUnknownElement,
then throw a "NotSupportedError" DOMException.

and

if namespace is not the HTML namespace, return null

The ongoing W3C discussion on allowing other namespaces is here: https://github.com/w3c/webcomponents/issues/634


The HTML Namespace has restrictions too

Apple/Safari implemented the Autonomous Custom Elements (extend from HTMLElement)

but refuses to implement Customized Built-In Elements (extend any Built-In element from the HTML Namespace)


If you want to generate SVG, you have to extend HTMLElement and generate the whole SVG tag:

<svg xmlns='http://www.w3.org/2000/svg' viewBox='V'><circle cx='X' cy='Y' r='R'/></svg>

Related Custom Element SVG StackOverflow Question and Answers

Danny '365CSI' Engelman
  • 16,526
  • 2
  • 32
  • 49
  • Aww shoots man. Thanks for clarifying this. I have a big svg element, inside which I want to draw various nodes (circles) whenever I click on any point inside the svg. I was able to achieve this feature just using absolute positioning on divs but I got to know that svg is better for stuff like this but no custom element support sucks. – Lakshya Thakur May 25 '20 at 13:29
  • So, back to oldskool, you can do ``createElement('circle')`` and append it to the SVG. Or create it as String and set the innerHTML on an existing SVG group ```` – Danny '365CSI' Engelman May 25 '20 at 13:35
  • The last link loops back to here. – Peter Mortensen Aug 23 '20 at 12:10