我在舞台上有一个名为myBtn
的按钮实例,以及一个名为myContainer
的方形影片剪辑的实例 - 所有这些都是从flash发布的。
在myContainer
中我有一个名为mySquare
的movieclip实例,它通过传统补间动画从舞台的一个点到另一个点。
加载阶段后,我使用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;
答案 0 :(得分:1)
如果您只是在寻找舞台,可以在任何显示对象上使用stage
属性(getter),该对象返回实例所在的舞台。如果无法到达舞台,它将返回null。
var stage = evt.target.stage;
否则,您可能希望查看您的应用程序架构。例如,您可以通过将this
作为on()
方法的第3个参数传递,将事件处理程序绑定到当前范围。这会使您的startBtnOnClick
方法在您的应用范围内触发,而不是让您查看相对于点击按钮的范围。
this.myBtn.on("click", startBtnOnClick, this);
[根据发布的内容进行编辑]
您的更新显示myContainer
是您的Flash阶段的子项,它实际上是作为库JS中的SquareTrial
函数导出的(以您的FLA命名)。此类在HTML中实例化为exportRoot
。
在库中定义函数的方式有点不正统。它基本上是一个匿名函数,但更大的问题是,如果从Flash重新导出库,它将被覆盖。我建议将其移动到您包含的另一个脚本,或者实际将其包含在您的帧脚本中。
无论如何,关于实际功能。由于您使用on()
方法在范围内调用它,因此this
变量将引用SquareTrial
实例(也称为exportRoot
)。您应该可以在this.myContainer
方法中引用startBtnOnClick
。
我建议的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);
如果您决定坚持使用无范围的匿名函数,那么您可以通过全局exportRoot
变量引用您的内容:
exportRoot.myContainer.gotoAndPlay(0);
希望能够解决任何困惑。