在 SVG 中包含 JavaScript
我正在尝试通过将 JavaScript 嵌入到 SVG 中,使用 JavaScript 创建交互式 SVG 代码。我不知道这是否是正确的方法:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg"
onkeypress="move()">
<script type="text/javascript">
<![CDATA[
var x;
var y;
function move()
{
x = new Number(svg.getElementsByTagName("circle")[0].getAttribute("cx"));
y = new Number (svg.getElementsByTagName("circle")[0].getAttribute("cy"));
switch (event.keyCode)
{
case 119:
y--;
y = y.toString();
svg.getElementsByTagName("circle").setAttribute("cy",y);
break;
case 115:
y++;
y = y.toString();
svg.getElementsByTagName("circle").setAttribute("cy",y);
break;
case 97:
x--;
x = x.toString();
svg.getElementsByTagName("circle").setAttribute("cx",x);
break;
case 100:
x++;
x = x.toString();
svg.getElementsByTagName("circle").setAttribute("cx",x);
break;
default:
}
}
]]>
</script>
<rect x="0" y="0" height="500" width="500" style="stroke-width:1; stroke:black; fill:white"></rect>
<circle cx="250" cy="250" r="50" stroke="red" stroke-width="1" fill="red"></circle>
</svg>
它应该有一个与 wasd 一起移动的球,但球没有移动。我做错了什么?
I am trying to create an interactive SVG code with JavaScript, by embedding the JavaScript in the SVG. I don't know if this is the right way to do this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg"
onkeypress="move()">
<script type="text/javascript">
<![CDATA[
var x;
var y;
function move()
{
x = new Number(svg.getElementsByTagName("circle")[0].getAttribute("cx"));
y = new Number (svg.getElementsByTagName("circle")[0].getAttribute("cy"));
switch (event.keyCode)
{
case 119:
y--;
y = y.toString();
svg.getElementsByTagName("circle").setAttribute("cy",y);
break;
case 115:
y++;
y = y.toString();
svg.getElementsByTagName("circle").setAttribute("cy",y);
break;
case 97:
x--;
x = x.toString();
svg.getElementsByTagName("circle").setAttribute("cx",x);
break;
case 100:
x++;
x = x.toString();
svg.getElementsByTagName("circle").setAttribute("cx",x);
break;
default:
}
}
]]>
</script>
<rect x="0" y="0" height="500" width="500" style="stroke-width:1; stroke:black; fill:white"></rect>
<circle cx="250" cy="250" r="50" stroke="red" stroke-width="1" fill="red"></circle>
</svg>
It is supposed to have a ball that moves with wasd, but the ball doesn't move. What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是我写的一个工作版本:
一些注意事项:
编辑:如果您无法根据上面的代码弄清楚如何执行此操作,请发布任何不适合您的代码。
事件
对象;这是老IE的废话。使用传递给事件处理程序的事件对象。编辑:如果您在代码中引用
事件
,且没有使用该名称的参数或局部变量,则您假设将有一个全局事件
对象集。相反,请参阅我为您编写的代码,其中显示事件处理程序传递了一个event
对象。通过为其指定一个名称(例如我将其命名为evt
),您将收到一个特定于您的事件处理程序的事件对象。x
和y
变量,因此无需重新获取cx
和cy
属性每次按键。编辑:在您的原始代码和您接受的答案中,您已在事件处理程序之外声明了
var x
,并且您有x = ...
在事件处理程序的开头,然后在其中一个事件处理程序中使用x++
。您可以每次重新获取x
的当前值(就像您所做的那样),然后setAttribute(...,x+1)
,或者(就像我所做的那样) )您只能在事件处理程序之前获取属性值一次,然后假设每次处理按键事件时该值都是正确的。编辑:在 SVG 标记中,您有:
。在 HTML 中将行为与标记混合是一个非常糟糕的主意,在 SVG 中也是一个坏主意。不要使用
onfoo="..."
属性来描述元素上发生事件时应该发生的情况,而是使用addEventListner()
通过代码附加事件处理程序,无需编辑 SVG 标记。在将数字设置为属性之前,无需将数字强制转换为字符串。
如果您希望它在所有浏览器中工作,请使用
keydown
和我上面提供的 ASCII 事件代码,而不是keypress
和您使用的奇数。编辑:您在另一篇文章中抱怨说无法执行此操作,因为您希望在按住该键时重复处理事件处理程序。请注意,您想要的行为是通过我在 Chrome、Safari、Firefox 和 IE 中的示例代码实现的(我没有 Opera 来测试)。换句话说,
keydown
按您想要的方式工作,无论您认为它应该如何表现。编辑 2:如果您想在文档顶部包含一个脚本块,那么在创建所有元素之前,您可以执行如下操作:
外部函数将仅运行一次页面已加载,因此您可以确定元素存在以引用它们。
Here is a working version as I would write it:
Some notes:
Edit: If you cannot figure out how to do this given my code above, post any code that is not working for you.
event
object; that's old IE nonsense. Use the event object passed to your event handler.Edit: If you reference
event
in your code with no parameter or local variable by that name, you are assuming that there will be a globalevent
object set. Instead, see the code I wrote for you, which shows that the event handler is passed anevent
object. By giving that a name, such as I gave it the nameevt
, you are receiving an event object specific to your event handler.x
andy
variables, there's no need to re-get thecx
andcy
attributes each key press.Edit: In your original code and the answer you accepted, you have declared
var x
outside your event handler, and you havex = ...
at the start of your event handler, and thenx++
in one of the event handlers. You can either re-get the current value ofx
each time (as you did) and thensetAttribute(...,x+1)
, or (as I did) you can only fetch the value of the attribute once before the event handlers and then assume that this value is correct each time you handle the key event.Edit: In your SVG markup you have:
<svg ... onkeypress="move()">
. Mixing your behavior with your markup is a really bad idea in HTML, and a bad idea in SVG. Instead of usingonfoo="..."
attributes to describe what should happen when an event occurs on an element, instead useaddEventListner()
to attach the event handlers via code, without editing your SVG markup.There's no need to coerce the numbers to strings before setting them as attributes.
Use
keydown
and the ASCII event codes I supplied above instead ofkeypress
and the odd numbers you were using if you want it to work in all browsers.Edit: You complained in another post that you cannot do this because you want the event handler to be processed repeatedly as the key is held down. Note that your desired behavior is achieved with my sample code in Chrome, Safari, Firefox, and IE (I don't have Opera to test). In other words
keydown
works as you wanted, despite how you thought it should behave.Edit 2: If you want to include a script block at the top of your document, before all elements have necessarily been created, you can do something like the following:
The outer function will only run once the page has loaded, so you can be sure that the elements exist to reference them.
您可以通过在 svg 标签中声明 script 标签来将脚本 js 添加到 svg 代码中:
you can add script js into svg code by declare script tag into svg tag:
这适用于 Chrome。您遇到了一些错误,例如有时仅对 getElementsByTagName 建立索引。另外一个大问题是 onkeypress 属性没有绑定。
This works in Chrome. You had a few errors, like indexing getElementsByTagName only sometimes. Plus the big problem was that the onkeypress attribute wasn't binding.
简单示例
Simple Example