When to use get/setAttributeNS() ?

DJ_AM_Juicebox
DJ_AM_Juicebox used Ask the Experts™
on
Hi,

I'm not sure when/how to use set/getAttributeNS(), or just normal set/getAttribute(). Here's my case:

  var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  svg.setAttribute('width', "400px");
  svg.setAttribute('height', "400px");

now I'm trying to set the points of a polygon, which is where I'm having problems:

  var polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');

which of the three variants do I use to set the points?:

   var points = "10,10 20,20 30,30";
   polygon.setAttributeNS('http://www.w3.org/2000/svg', "points", points);
   polygon.setAttributeNS(null, "points", points);
   polygon.setAttribute("points", points);

but I'm getting bad results. When I set using setAttribute(), the commas in my string seem to get stripped somehow. When I use the NS variants, my polygon does not appear on the screen.

I basically need to know which combination of get/set to use,

Thanks
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
This works fine for me on FireFox
function init(e) {
	var polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');

	var points = "10,10 20,20 30,30";
	polygon.setAttributeNS(null, "points", points);

	e.target.ownerDocument.documentElement.appendChild(polygon);
}

Open in new window

You thinking its not working might be the fact that your points are in a straight line. Try this code instead. Save it as "testing.svg" and open it with FireFox. It should make a small upside down triangle on the top left corner of the page
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
    "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
    <!ATTLIST svg
              xmlns:a3 CDATA #IMPLIED
              a3:scriptImplementation CDATA #IMPLIED>
    <!ATTLIST script
              a3:scriptImplementation CDATA #IMPLIED>
]>
<svg viewBox="0 0 400 400" preserveAspectRatio="none"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xmlns:a3="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
     a3:scriptImplementation="Adobe"
     onload="init(evt)">
    <script type="text/ecmascript" a3:scriptImplementation="Adobe"><![CDATA[
		// init function
        function init(e) {
			if (window.svgDocument == null)
                svgDocument = e.target.ownerDocument;
				
       		var polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon'); 
 
        	var points = "10,10 30,10 20,28"; //cordinates for a triangle
       	 	polygon.setAttributeNS(null, "points", points);
			polygon.setAttributeNS(null, "fill", "none");
			polygon.setAttributeNS(null, "stroke", "green");

        	svgDocument.documentElement.appendChild(polygon); 
		}
    ]]></script>


</svg>

Open in new window

Or maybe it was because your "stroke" attribute was not added.
Success in ‘20 With a Profitable Pricing Strategy

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Using setAttribute works fine for me too. (This again might have been because your 3 points were in a straight line that you thought only the first set of points were working)
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
    "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
    <!ATTLIST svg
              xmlns:a3 CDATA #IMPLIED
              a3:scriptImplementation CDATA #IMPLIED>
    <!ATTLIST script
              a3:scriptImplementation CDATA #IMPLIED>
]>
<svg viewBox="0 0 400 400" preserveAspectRatio="none"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xmlns:a3="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
     a3:scriptImplementation="Adobe"
     onload="init(evt)">
    <script type="text/ecmascript" a3:scriptImplementation="Adobe"><![CDATA[
		// init function
        function init(e) {
			if (window.svgDocument == null) svgDocument = e.target.ownerDocument;
				
       		var polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon'); 
 
        	var points = "10,10 30,10 20,28"; //cordinates for a triangle
       	 	polygon.setAttribute("points", points);
			polygon.setAttribute("fill", "none");
			polygon.setAttribute("stroke", "green");

        	svgDocument.documentElement.appendChild(polygon); 
		}
    ]]></script>


</svg>

Open in new window

Author

Commented:
Hi all,

Yes bad example coordinate list - I am using the point list which makes a triangle now. I've attached my test script in full, you can dump it to an html file and run it.

Setting the point list seems to work, but when run in Safari or Chrome, the point list is somehow going bad - this works ok in FF or Opera though. I'm just useing get/setAttribute. The idea is to just push the polygon points to the right 1 pixel on every mouse move.

In Safari and Chrome, when you click the shape, then move the mouse, you'll see the polygon move to the right one pixel, then the points go sour and the shape disappears altogether.

If anyone can see what I'm doing wrong, that'd be awesome, it's been like 36 hours of banging my head against the wall with this!

Thanks
<html>
  <head>
    <script>
    
        var gDraggedShape = null;
    
        function onClickPolygon(e) {
            gDraggedShape = document.getElementById("mypoly");
        }
        
        function onMouseMove(e) {
            if (gDraggedShape != null) {
                gDraggedShape.updatePoints(1, 0); // just push to the right, 1 pixel.
            }
        }
        
        function onMouseUp(e) {
            gDraggedShape = null;
        }
        
        window.onload = function() {
            document.onmousemove = onMouseMove;
            document.onmouseup = onMouseUp;

            var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            svg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
            svg.setAttribute('version', '1.1');
            svg.setAttribute('width', '800px');
            svg.setAttribute('height', '400px');
            document.body.appendChild(svg);
            
            var polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
            polygon.setAttribute("id", "mypoly"); 
            polygon.setAttribute("fill","red");
            polygon.setAttribute("stroke","black");
            polygon.setAttribute("stroke-width","5");
            polygon.setAttribute("points", "10,10 300,101 200,280");
            polygon.onmousedown=onClickPolygon;
            polygon.updatePoints = function(x,y) {
                var pointsNew = "";
                var points = this.getAttribute("points");
                var pairs = points.split(" ");
                for (var i = 0; i < pairs.length; i++) {
                    var pair = pairs[i].split(",");
                    pointsNew += parseInt(pair[0]) + x;
                    pointsNew += ",";
        	        pointsNew += parseInt(pair[1]) + y;
			        if (i < pairs.length - 1) {
                        pointsNew += " ";
                    }
                }
                
                this.setAttribute("points", pointsNew);
            };
            svg.appendChild(polygon);
        }
        
    </script>
</head>

<body>
</body>

</html>

Open in new window

Author

Commented:
I guess this is a bug with webkit:

  https://bugs.webkit.org/show_bug.cgi?id=29870

looks like the same behavior, for some reason the commas are stripped from the string when setting the attribute.

I hate this stuff!

Thanks
Ahhh yeah those nasty browser specific bugs. Sorry it didn't turn out better for you. Thanks for the points.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial