简体   繁体   English

svg标记内的Javascript

[英]Javascript inside of svg tag

I am trying to generate a line chart using SVG. 我正在尝试使用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. 一切都很好,除非我尝试以本页上Javascript生成的变量的形式将圆或其他项目插入SVG中。

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. 我在页面上的JavaScript中已为变量y_axis_Max design_x_Value design_y_Value分配了值。

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. 显然,一种有效的代码在标签外部有JavaScript,而另一种在标签内部没有JavaScript。 There must be a way to do this. 必须有一种方法可以做到这一点。

Thanks 谢谢

You might set attributes from JS: 您可以从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. 编写代码的方式非常类似于PHP的工作方式:遍历一个文件,当遇到脚本部分时,对它们进行解释,并用其结果替换脚本标签内容,以生成更改的序列化形式。 That is a typical server-side production. 那是典型的服务器端生产。

Javascript in contrast is interpreted client-side. 相反,JavaScript是客户端解释的。 The file is used to deserialize the file into a representation object, the DOM (document object model). 该文件用于将文件反序列化为表示对象DOM(文档对象模型)。 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() : 这是HTML5规范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. 在某些情况下,此方法可能会在运行解析器时影响HTML解析器的状态,从而导致DOM与文档源不对应。 In other cases, the call can clear the current page first, as if document.open() had been called. 在其他情况下,该调用可以首先清除当前页面,就像已调用document.open()一样。 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. 如果您的SVG是一个独立文件,则该方法调用根本不会起作用。

Your second example isn't valid XML or HTML. 第二个示例不是有效的XML或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. <script>标记是HTML标记,与其他标记一样,必须放置为另一个标记的子代,而不是位于标记标记内。

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. 我在他的答案中使用的是Kosh Very提供的代码,但不是将其显示为隐藏最终标记结构的可执行代码段,而是将其写在文件中。 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() . 请注意,脚本的一部分位于<svg>结束标记之后,因为只有这样DOM才包含被document.querySelector()引用的<text><circle>元素。

<!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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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