javascript – 如何添加点击以形成循环?
作者:互联网
我将文本数组传递给我的circleCreate函数,该函数为每个文本创建一个楔形.我要做的是向每个楔形添加一个点击事件,因此当用户点击一个楔形时,它会抛出每个楔形文本的警报.
但它不起作用.只有外圈提醒文字.它总是说同样的文字.两个内圈都警告未定义.
http://jsfiddle.net/Yushell/9f7JN/
var layer = new Kinetic.Layer();
function circleCreate(vangle, vradius, vcolor, vtext) {
startAngle = 0;
endAngle = 0;
for (var i = 0; i < vangle.length; i++) {
// WEDGE
startAngle = endAngle;
endAngle = startAngle + vangle[i];
var wedge = new Kinetic.Wedge({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: vradius,
angleDeg: vangle[i],
fill: vcolor,
stroke: 'black',
strokeWidth: 1,
rotationDeg: startAngle
});
/* CLICK NOT WORKING
wedge.on('click', function() {
alert(vtext[i]);
});*/
layer.add(wedge);
}
stage.add(layer);
}
解决方法:
这是使用异步JavaScript代码(如事件处理程序)遇到的典型问题. circleCreate()函数中的for循环使用一个变量i,它为每个wedge递增.这是很好的你使用我创建楔形的地方:
angleDeg: vangle[i],
但是在click事件处理程序中使用它会失败:
alert(vtext[i]);
这是为什么?
当您使用新的Kinetic.Wedge()调用创建楔形时,这将直接在循环内完成.此代码同步运行;它使用i的值,因为它存在于循环的这个特定迭代运行的那一刻.
但是单击事件处理程序在那时不运行.如果你从不点击,它可能根本不运行.当您单击一个楔形时,它的事件处理程序在原始循环完成运行很久之后被调用.
那么,当事件处理程序运行时,i的值是多少?它是最初运行时代码留在其中的任何值.当i等于vangle.length时,这个for循环退出 – 换句话说,我超过了数组的末尾,因此vangle [i]是未定义的.
通过简单地为每个循环迭代调用一个函数,您可以使用闭包轻松解决此问题:
var layer = new Kinetic.Layer();
function circleCreate(vangle, vradius, vcolor, vtext) {
startAngle = 0;
endAngle = 0;
for (var i = 0; i < vangle.length; i++) {
addWedge( i );
}
stage.add(layer);
function addWedge( i ) {
startAngle = endAngle;
endAngle = startAngle + vangle[i];
var wedge = new Kinetic.Wedge({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: vradius,
angleDeg: vangle[i],
fill: vcolor,
stroke: 'black',
strokeWidth: 1,
rotationDeg: startAngle
});
wedge.on('click', function() {
alert(vtext[i]);
});
layer.add(wedge);
}
}
现在发生的是调用addWedge()函数为每个循环迭代单独捕获i的值.如您所知,每个函数都可以拥有自己的局部变量/参数,而addWedge()内部的i是该函数的本地函数 – 具体而言,该函数的每个单独调用都是本地的. (注意,因为addWedge()是它自己的函数,所以该函数中的i与外circleCreate()函数中的i不同.如果这是令人困惑的,可以给它一个不同的名称.)
一个更好的方法
这就是说,我建议采用不同的方法来构建数据.当我阅读你的代码时,角度和文本数组引起了我的注意:
var anglesParents = [120, 120, 120];
var parentTextArray = ['Parent1', 'Parent2', 'Parent3'];
对于儿童和孙子,有相似但较长的阵列对.
您可以将这些数组中的值与circleCreate()中的vtext [i]和vangle [i]引用一起使用.
一般情况下,除非有特殊原因要使用这样的并行数组,否则如果将它们组合成单个对象数组,代码将变得更加清晰:
[
{ angle: 120, text: 'Parent1' },
{ angle: 120, text: 'Parent2' },
{ angle: 120, text: 'Parent3' }
]
对于嵌套的圆圈,我们可以更进一步,将所有三个环组合成一个大的对象数组,描述整套嵌套环.你有这些数组的地方:
var anglesParents = [120, 120, 120];
var anglesChildren = [120, 60, 60, 60, 60];
var anglesGrandchildren = [
33.33, 20, 23.33, 43.33, 22.10, 25.26,
12.63, 28, 32, 33, 27, 36, 14.4, 9.6
];
var grandchildrenTextArray = [
'GrandCHild1', 'GrandCHild2', 'GrandCHild3', 'GrandCHild4',
'GrandCHild5', 'GrandCHild6', 'GrandCHild7', 'GrandCHild8',
'GrandCHild9', 'GrandCHild10', 'GrandCHild11', 'GrandCHild12',
'GrandCHild13', 'GrandCHild14', 'GrandCHild15', 'GrandCHild16'
];
var childrenTextArray = [
'Child1', 'Child2', 'Child3', 'Child4', 'Child5'
];
var parentTextArray = ['Parent1', 'Parent2', 'Parent3'];
这将是:
var rings = [
{
radius: 200,
color: 'grey',
slices: [
{ angle: 33.33, text: 'GrandChild1' },
{ angle: 20, text: 'GrandChild2' },
{ angle: 23.33, text: 'GrandChild3' },
{ angle: 43.33, text: 'GrandChild4' },
{ angle: 22.10, text: 'GrandChild5' },
{ angle: 25.26, text: 'GrandChild6' },
{ angle: 12.63, text: 'GrandChild7' },
{ angle: 28, text: 'GrandChild8' },
{ angle: 32, text: 'GrandChild9' },
{ angle: 33, text: 'GrandChild10' },
{ angle: 27, text: 'GrandChild10' },
{ angle: 36, text: 'GrandChild12' },
{ angle: 14.4, text: 'GrandChild13' },
{ angle: 9.6, text: 'GrandChild14' }
]
},
{
radius: 150,
color: 'darkgrey',
slices: [
{ angle: 120, text: 'Child1' },
{ angle: 60, text: 'Child2' },
{ angle: 60, text: 'Child3' },
{ angle: 60, text: 'Child4' },
{ angle: 60, text: 'Child5' }
]
},
{
radius: 100,
color: 'lightgrey',
slices: [
{ angle: 120, text: 'Parent1' },
{ angle: 120, text: 'Parent2' },
{ angle: 120, text: 'Parent3' }
]
}
];
现在这比原来的更长,所有角度:和text:属性名称,但是这些东西压缩得非常好,服务器和浏览器使用的gzip压缩.
更重要的是,它有助于简化和澄清代码并避免错误.您是否碰巧注意到您的角度孩子和孙子的文字阵列长度不一样?
标签:kineticjs,javascript,canvas 来源: https://codeday.me/bug/20190831/1778580.html