单击按钮时访问根阶段实例
Access root stage instance when button is clicked
我在舞台上有一个名为 myBtn
的按钮实例,还有一个名为 myContainer
的方形影片剪辑实例 - 所有这些都是从 Flash 发布的。
在 myContainer
中,我有一个名为 mySquare
的动画片段实例,它通过经典补间动画从舞台的一个点到另一个点。
加载舞台后,我使用 this.myBtn.on("click", startBtnOnClick)
向按钮添加事件侦听器,函数 startBtnOnClick(evt)
确实被成功调用。
我想要实现的是告诉 myContainer
在单击按钮时开始播放,为此我目前需要使用:
evt.target.parent.parent.myContainer.gotoAndPlay(0)
这行得通,但在这里似乎不是最佳做法。
哪种方法更合适?
代码是在我使用 HTML5 文档类型从 Adobe Flash 发布时生成的。我添加的是 startBtnOnClick()
函数定义并将事件处理程序分配给 myBtn
实例
编辑:
发布时创建了两个文件。为了播放电影,您打开 html 文件。
SquareTrial.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SquareTrial</title>
<script src="http://code.createjs.com/easeljs-0.8.1.min.js"></script>
<script src="http://code.createjs.com/tweenjs-0.6.1.min.js"></script>
<script src="http://code.createjs.com/movieclip-0.8.1.min.js"></script>
<script src="SquareTrial.js"></script>
<script>
var canvas, stage, exportRoot;
function init() {
canvas = document.getElementById("canvas");
exportRoot = new lib.SquareTrial();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
stage.update();
createjs.Ticker.setFPS(lib.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
}
</script>
</head>
<body onload="init();" style="background-color:#D4D4D4">
<canvas id="canvas" width="550" height="400" style="background-color:#FFFFFF"></canvas>
</body>
</html>
和SquareTrial.js:
(function (lib, img, cjs, ss) {
var p; // shortcut to reference prototypes
// library properties:
lib.properties = {
width: 550,
height: 400,
fps: 24,
color: "#FFFFFF",
manifest: []
};
// functions:
function startBtnOnClick(evt)
{
console.log("startBtnOnClick called.");
console.log("stage:");
console.log(stage);
console.log("stage.myContainer:");
console.log(stage.myContainer);
console.log("this.myContainer:");
console.log(this.myContainer);
}
// symbols:
(lib.MySquare = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#000000").ss(1,1,1).p("AoWoWIQtAAIAAQtIwtAAg");
this.shape.setTransform(53.5,53.5);
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#6633FF").s().p("AoWIXIAAwtIQtAAIAAQtg");
this.shape_1.setTransform(53.5,53.5);
this.addChild(this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-1,-1,109,109);
(lib.MyBtn = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#000000").ss(1,1,1).p("AprjWITXAAIAAGtIzXAAg");
this.shape.setTransform(62,21.5);
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#0099FF").s().p("AprDXIAAmtITXAAIAAGtg");
this.shape_1.setTransform(62,21.5);
this.addChild(this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-1,-1,126,45);
(lib.MyContainer = function(mode,startPosition,loop) {
this.initialize(mode,startPosition,loop,{});
// Layer 1
this.mySquare = new lib.MySquare();
this.mySquare.setTransform(53.5,53.5,1,1,0,0,0,53.5,53.5);
this.timeline.addTween(cjs.Tween.get(this.mySquare).to({x:397.5},47).wait(1));
}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(-0.5,-0.5,108,108);
// stage content:
(lib.SquareTrial = function() {
this.initialize();
// button
this.myContainer = new lib.MyContainer();
this.myContainer.setTransform(102.5,99.5,1,1,0,0,0,53.5,53.5);
this.myBtn = new lib.MyBtn();
this.myBtn.setTransform(111,337.5,1,1,0,0,0,62,21.5);
//this.myBtn.on("click", startBtnOnClick); //<< does not work
this.myBtn.on("click", startBtnOnClick, this);
this.addChild(this.myBtn,this.myContainer);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(323.5,245.5,125,314);
})(lib = lib||{}, images = images||{}, createjs = createjs||{}, ss = ss||{});
var lib, images, createjs, ss;
如果你只是在寻找舞台,你可以在任何显示对象上使用stage
属性 (getter),其中return是舞台实例继续存在。达不到舞台return null
var stage = evt.target.stage;
否则,您可能需要查看您的应用程序架构。例如,您可以通过将 this
作为 on()
方法的第三个参数传递,将您的事件处理程序绑定到当前范围。这将使您的 startBtnOnClick
方法在您的应用程序范围内触发,而不是让您查找相对于单击按钮的范围。
this.myBtn.on("click", startBtnOnClick, this);
[根据发布的内容编辑]
您的更新显示 myContainer
是您的 Flash 阶段的子级,它实际上作为库 JS(以您的 FLA 命名)中的 SquareTrial
函数导出。此 class 在 HTML.
中实例化为 exportRoot
您在库中定义函数的方式有点不正统。它基本上是一个匿名函数,但更大的问题是如果您 re-export 来自 Flash 的库,它将被覆盖。我建议要么将它移动到您包含的另一个脚本中,要么实际上将它包含在您的框架脚本中。
总之,进入实际功能。由于您使用 on()
方法在范围内调用它,因此 this
变量将引用 SquareTrial
实例(也称为 exportRoot
)。您应该能够在 startBtnOnClick
方法中引用 this.myContainer
。
我建议的stage
getter并不理想,因为EaselJS阶段只包含exportRoot
。它还需要作为 this.stage
访问。您使用的 stage
引用 确实 存在,但它是在 index.html.
中创建的全局变量
因此,使用新方法,您应该能够做到这一点:
// In your frame script:
this.myBtn.on("click", startBtnOnClick, this);
// In your function callback
console.log(this); // Should be the instance, and NOT window.
this.myContainer.gotoAndPlay(0);
如果您决定坚持使用 un-scoped 匿名函数,那么您可以通过全局 exportRoot
变量引用您的内容:
exportRoot.myContainer.gotoAndPlay(0);
希望消除任何困惑。
我在舞台上有一个名为 myBtn
的按钮实例,还有一个名为 myContainer
的方形影片剪辑实例 - 所有这些都是从 Flash 发布的。
在 myContainer
中,我有一个名为 mySquare
的动画片段实例,它通过经典补间动画从舞台的一个点到另一个点。
加载舞台后,我使用 this.myBtn.on("click", startBtnOnClick)
向按钮添加事件侦听器,函数 startBtnOnClick(evt)
确实被成功调用。
我想要实现的是告诉 myContainer
在单击按钮时开始播放,为此我目前需要使用:
evt.target.parent.parent.myContainer.gotoAndPlay(0)
这行得通,但在这里似乎不是最佳做法。
哪种方法更合适?
代码是在我使用 HTML5 文档类型从 Adobe Flash 发布时生成的。我添加的是 startBtnOnClick()
函数定义并将事件处理程序分配给 myBtn
实例
编辑:
发布时创建了两个文件。为了播放电影,您打开 html 文件。
SquareTrial.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SquareTrial</title>
<script src="http://code.createjs.com/easeljs-0.8.1.min.js"></script>
<script src="http://code.createjs.com/tweenjs-0.6.1.min.js"></script>
<script src="http://code.createjs.com/movieclip-0.8.1.min.js"></script>
<script src="SquareTrial.js"></script>
<script>
var canvas, stage, exportRoot;
function init() {
canvas = document.getElementById("canvas");
exportRoot = new lib.SquareTrial();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
stage.update();
createjs.Ticker.setFPS(lib.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
}
</script>
</head>
<body onload="init();" style="background-color:#D4D4D4">
<canvas id="canvas" width="550" height="400" style="background-color:#FFFFFF"></canvas>
</body>
</html>
和SquareTrial.js:
(function (lib, img, cjs, ss) {
var p; // shortcut to reference prototypes
// library properties:
lib.properties = {
width: 550,
height: 400,
fps: 24,
color: "#FFFFFF",
manifest: []
};
// functions:
function startBtnOnClick(evt)
{
console.log("startBtnOnClick called.");
console.log("stage:");
console.log(stage);
console.log("stage.myContainer:");
console.log(stage.myContainer);
console.log("this.myContainer:");
console.log(this.myContainer);
}
// symbols:
(lib.MySquare = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#000000").ss(1,1,1).p("AoWoWIQtAAIAAQtIwtAAg");
this.shape.setTransform(53.5,53.5);
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#6633FF").s().p("AoWIXIAAwtIQtAAIAAQtg");
this.shape_1.setTransform(53.5,53.5);
this.addChild(this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-1,-1,109,109);
(lib.MyBtn = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#000000").ss(1,1,1).p("AprjWITXAAIAAGtIzXAAg");
this.shape.setTransform(62,21.5);
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#0099FF").s().p("AprDXIAAmtITXAAIAAGtg");
this.shape_1.setTransform(62,21.5);
this.addChild(this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-1,-1,126,45);
(lib.MyContainer = function(mode,startPosition,loop) {
this.initialize(mode,startPosition,loop,{});
// Layer 1
this.mySquare = new lib.MySquare();
this.mySquare.setTransform(53.5,53.5,1,1,0,0,0,53.5,53.5);
this.timeline.addTween(cjs.Tween.get(this.mySquare).to({x:397.5},47).wait(1));
}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(-0.5,-0.5,108,108);
// stage content:
(lib.SquareTrial = function() {
this.initialize();
// button
this.myContainer = new lib.MyContainer();
this.myContainer.setTransform(102.5,99.5,1,1,0,0,0,53.5,53.5);
this.myBtn = new lib.MyBtn();
this.myBtn.setTransform(111,337.5,1,1,0,0,0,62,21.5);
//this.myBtn.on("click", startBtnOnClick); //<< does not work
this.myBtn.on("click", startBtnOnClick, this);
this.addChild(this.myBtn,this.myContainer);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(323.5,245.5,125,314);
})(lib = lib||{}, images = images||{}, createjs = createjs||{}, ss = ss||{});
var lib, images, createjs, ss;
如果你只是在寻找舞台,你可以在任何显示对象上使用stage
属性 (getter),其中return是舞台实例继续存在。达不到舞台return null
var stage = evt.target.stage;
否则,您可能需要查看您的应用程序架构。例如,您可以通过将 this
作为 on()
方法的第三个参数传递,将您的事件处理程序绑定到当前范围。这将使您的 startBtnOnClick
方法在您的应用程序范围内触发,而不是让您查找相对于单击按钮的范围。
this.myBtn.on("click", startBtnOnClick, this);
[根据发布的内容编辑]
您的更新显示 myContainer
是您的 Flash 阶段的子级,它实际上作为库 JS(以您的 FLA 命名)中的 SquareTrial
函数导出。此 class 在 HTML.
exportRoot
您在库中定义函数的方式有点不正统。它基本上是一个匿名函数,但更大的问题是如果您 re-export 来自 Flash 的库,它将被覆盖。我建议要么将它移动到您包含的另一个脚本中,要么实际上将它包含在您的框架脚本中。
总之,进入实际功能。由于您使用 on()
方法在范围内调用它,因此 this
变量将引用 SquareTrial
实例(也称为 exportRoot
)。您应该能够在 startBtnOnClick
方法中引用 this.myContainer
。
我建议的stage
getter并不理想,因为EaselJS阶段只包含exportRoot
。它还需要作为 this.stage
访问。您使用的 stage
引用 确实 存在,但它是在 index.html.
因此,使用新方法,您应该能够做到这一点:
// In your frame script:
this.myBtn.on("click", startBtnOnClick, this);
// In your function callback
console.log(this); // Should be the instance, and NOT window.
this.myContainer.gotoAndPlay(0);
如果您决定坚持使用 un-scoped 匿名函数,那么您可以通过全局 exportRoot
变量引用您的内容:
exportRoot.myContainer.gotoAndPlay(0);
希望消除任何困惑。