问题描述
请看看这个小提琴:
如您所见,我想在其上触发事件时转换SVG元素。您可以点击箭头,它应该工作,因为它使用嵌入在SVG范围内的JavaScript代码:
< svg id =my-svgwidth =20cmheight =20cmviewBox =0 0 600 600
xmlns =http://www.w3.org/2000/svgversion =1.1 >
< desc>示例显示如何使用SVGTransform对象转换svg元素
< / desc>
< script type =application / ecmascript> <![CDATA [
function transformMe(evt){
// svg root元素来访问createSVGTransform()函数
var svgroot = evt.target.parentNode;
//已经点击的元素的SVGTransformList
var tfmList = evt.target.transform.baseVal;
//为每个变换创建一个独立的变换对象
var translate = svgroot.createSVGTransform();
translate.setTranslate(50,5);
var rotate = svgroot.createSVGTransform();
rotate.setRotate(10,0,0);
var scale = svgroot.createSVGTransform();
scale.setScale(0.8,0.8);
//通过将SVGTranform对象
//附加到与元素
tfmList.appendItem(translate)相关联的SVGTransformList来应用转换;
tfmList.appendItem(rotate);
tfmList.appendItem(scale);
}
]]> < /脚本>
< polygon fill =orangestroke =black
stroke-width =5
points =100,225 100,115 130,115 70,15 70,15 10,115 40,115 40,225
onclick =transformMe(evt)/>
...
< / svg>
这是有效的,但我想让我的JavaScript代码与 SVG分开
元素。根据,我应该能够通过使用顶部
范围引用JavaScript函数。这就是我为矩形做的:
< rect x =200y =100width = 100height =100
fill =yellowstroke =blackstroke-width =5
onclick =top.transformMe(evt)/>
但是,在控件中单击矩形会出现以下错误:
错误:权限被拒绝访问属性transformMe@ http://fiddle.jshell.net/arasbm/Tyxea/14/show/:1
有人可以告诉我如何解决这个问题。在这个例子中我已经证明了真正的问题是:使用除这些元素之外的JavaScript代码处理SVG元素上的事件的正确方法是什么? 解决方案小提琴代码中的问题是JSFiddle安排您的代码的方式。
首先,Javascript被评估在函数体中,因此您的方法transformMe不会成为全局函数。添加
window.transformMe = transformMe
在您的Javascript结尾,以便该函数成为一个全局。
然后在小提琴中,代码运行在一个iframe也许你的页面是不同的),顶是指顶级文件,在jsfiddle.net的情况下,你正在尝试进行跨域JS调用。您可以看到这一点,如果您开启开发工具的小提琴:控制台提供正确的提示。
最后但并非最不重要的是,相信你需要顶参考。相反,您可以简单地调用全局函数(只需使用IE,Chrome和FF进行测试,然后它为我工作)。
Please take a look at this fiddle: http://jsfiddle.net/arasbm/Tyxea/14/
As you can see I want to transform SVG elements when an event is triggered on them. You can click on arrow and it should work, because it uses the JavaScript code embeded inside the SVG scope:
<svg id="my-svg" width="20cm" height="20cm" viewBox="0 0 600 600"
xmlns="http://www.w3.org/2000/svg" version="1.1">
<desc>Example showing how to transform svg elements
using SVGTransform objects</desc>
<script type="application/ecmascript"> <![CDATA[
function transformMe(evt) {
// svg root element to access the createSVGTransform() function
var svgroot = evt.target.parentNode;
// SVGTransformList of the element that has been clicked on
var tfmList = evt.target.transform.baseVal;
// Create a seperate transform object for each transform
var translate = svgroot.createSVGTransform();
translate.setTranslate(50,5);
var rotate = svgroot.createSVGTransform();
rotate.setRotate(10,0,0);
var scale = svgroot.createSVGTransform();
scale.setScale(0.8,0.8);
// apply the transformations by appending the SVGTranform objects
// to the SVGTransformList associated with the element
tfmList.appendItem(translate);
tfmList.appendItem(rotate);
tfmList.appendItem(scale);
}
]]> </script>
<polygon fill="orange" stroke="black"
stroke-width="5"
points="100,225 100,115 130,115 70,15 70,15 10,115 40,115 40,225"
onclick="transformMe(evt)"/>
...
</svg>
This works, but I would like to have my JavaScript code separate from SVG
element. According to this W3C document I should be able to have call a javascript function by refering to it using top
scope. That is what I have done for the rectangle:
<rect x="200" y="100" width="100" height="100"
fill="yellow" stroke="black" stroke-width="5"
onclick="top.transformMe(evt)"/>
However clicking on the rectangle gives the following error in console:
Error: Permission denied to access property 'transformMe' @ http://fiddle.jshell.net/arasbm/Tyxea/14/show/:1
Can someone tell me how to solve this problem. The real question I have that is demonstrated in this example is: what is the proper way to handle events on SVG elements with JavaScript code that is outside those elements?
解决方案 The problem in the fiddle code is the way JSFiddle arranges your code.
First, the Javascript is evaluated in a function body and thus your method transformMe does not become a global function. Add
window.transformMe = transformMe
at the end of your Javascript so that the function becomes a global.
Then again in the fiddle the code runs in an iframe (maybe your page is different) and "top" refers to the top document and in the case of jsfiddle.net you are thus trying to make a cross-domain JS call. You can see this if you run the fiddle with the developer tools turned on: the console gives the right hints.
Last but not least in the current browser implementations I don't believe you need the "top" reference at all. Instead you can simply call global functions (just tested it with IE, Chrome, and FF and it worked for me).
这篇关于SVG错误:拒绝访问属性“someFunction”的权限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!