简体   繁体   中英

Javascript inside of svg tag

I am trying to generate a line chart using SVG. All is fine except when I try to insert circles or other items into the SVG in the form of variable generated by Javascript on this page.

I have the variables y_axis_Max design_x_Value design_y_Value that I have assigned values to in JavaScript earlier on the page.

For example this code inside of ... to write text on the page dynamically works:

<text x="100" y="100" dx="-30"dy="10">
    <SCRIPT LANGUAGE="JavaScript">
    document.write(""+ y_axis_Max +"")</SCRIPT>
</text>

This code to dynamically create a circle does not work:

<circle id="pointB" cx="
<SCRIPT LANGUAGE="JavaScript">
document.write(""+ design_x_Value +"")</SCRIPT>
" cy="
<SCRIPT LANGUAGE="JavaScript">
document.write(""+ design_y_Value +"")</SCRIPT>
" r="3" stroke="black" stroke-width="3" fill="black"/>

Obviously the one that works has the JavaScript outside the tag and the one that does not has the JavaScript inside the tag. There must be a way to do this.

Thanks

You might set attributes from JS:

 var y_axis_Max = 100, design_x_Value = 50, design_y_Value = 20; var text = document.querySelector('text'); text.textContent = y_axis_Max; var point = document.querySelector('#pointB'); point.setAttribute('cx', design_x_Value); point.setAttribute('cy', design_y_Value); 
 <svg viewBox="0 0 300 100"> <text x="10" y="20"></text> <circle id="pointB" r="3" stroke="black" stroke-width="3" fill="black"/> </svg> 

The way you you write your code looks very much like how PHP works: go through a file, and when you encounter script parts, interpret them, and replace the script tag content with their result to produce an altered, serialized form. That is a typical server-side production.

Javascript in contrast is interpreted client-side. The file is used to deserialize the file into a representation object, the DOM (document object model). Scripts are interpreted against that model, as far as that model could be built at the time script is encountered, but always against the whole model.

That your first script worked is only incedental, and dependent on a lot of things not going wrong. Here is what the HTML5 spec has to say about document.write() :

Warning! This method has very idiosyncratic behavior. In some cases, this method can affect the state of the HTML parser while the parser is running, resulting in a DOM that does not correspond to the source of the document. In other cases, the call can clear the current page first, as if document.open() had been called. In yet more cases, the method is simply ignored, or throws an exception. To make matters worse, the exact behavior of this method can in some cases be dependent on network latency, which can lead to failures that are very hard to debug. For all these reasons, use of this method is strongly discouraged.

If your SVG had been a stand-alone file, the method call would not have worked at all.

Your second example isn't valid XML or HTML. The <script> tag is a HTML tag like any other, and must be positioned as the child of another tag, not inside the tag markup.

The correct form looks like this. I am using the code provided by Kosh Very in his answer, but instead of showing it as a executable snippet that hides the structure of the final markup, here it is like it would be written out in a file. Note that part of the script is positioned after the <svg> closing tag, because only then the DOM contains the <text> and <circle> elements that are referenced with document.querySelector() .

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript">
var y_axis_Max = 100, design_x_Value = 50, design_y_Value = 20;
        </script>
    </head>
    <body>
        <svg viewBox="0 0 300 100">
           <text x="10" y="20">100</text>
           <circle id="pointB" r="3" stroke="black" stroke-width="3" fill="black" cx="50" cy="20"></circle>
        </svg>
        <script type="text/javascript">
var text = document.querySelector('text');
text.textContent = y_axis_Max;

var point = document.querySelector('#pointB');

point.setAttribute('cx', design_x_Value);
point.setAttribute('cy', design_y_Value);
        </script>
    </body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM