在 ActionScript 中删除事件监听器的问题
我对 Flash 并不陌生,但对 ActionScript 有点菜鸟,尝试在 Flash Pro(或者更确切地说是 Animate CC)中构建一个应用程序,该应用程序将(希望)教授用户音乐理论(如何读乐谱等)。我想要的是将不同的课程放在不同的帧上,并设置单独的“屏幕”,用户可以滑动浏览。我使用了 Adob​​e 在其滑动图库模板中提供的滑动代码的多个副本。
在第 5 帧上,我使用了以下内容:
stop()
Multitouch.inputMode = MultitouchInputMode.GESTURE;
var currentGalleryItem:Number = 1;
var totalGalleryItems:Number = 10;
stage.addEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameB);
function fl_SwipeToGoToNextPreviousFrameB(event:TransformGestureEvent):void
{
if(event.offsetX == 1)
{
if(currentGalleryItem > 1){
currentGalleryItem--;
slideRight();
}
}
else if(event.offsetX == -1)
{
if(currentGalleryItem < totalGalleryItems){
currentGalleryItem++;
slideLeft();
}
}
}
var slideCounter:Number = 0;
function slideLeft(){
lsn112.addEventListener("enterFrame", moveGalleryLeft);
}
function slideRight(){
lsn112.addEventListener("enterFrame", moveGalleryRight);
}
function moveGalleryLeft(evt:Event){
lsn112.x -= 128;
slideCounter++;
if(slideCounter == 10){
lsn112.removeEventListener("enterFrame", moveGalleryLeft);
slideCounter = 0;
}
}
function moveGalleryRight(evt:Event){
lsn112.x += 128;
slideCounter++;
if(slideCounter == 10){
lsn112.removeEventListener("enterFrame", moveGalleryRight);
slideCounter = 0;
}
}
Home112.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndStopAtFrame_22);
function fl_ClickToGoToAndStopAtFrame_22(event:MouseEvent):void
{
gotoAndStop(2);
}
stop()
第 6 帧几乎相同,只是变量、函数等的名称不同:
stop()
Multitouch.inputMode = MultitouchInputMode.GESTURE;
var currentGalleryItemA:Number = 1;
var totalGalleryItemsA:Number = 11;
stage.addEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameA);
function fl_SwipeToGoToNextPreviousFrameA(event:TransformGestureEvent):void
{
if(event.offsetX == 1)
{
if(currentGalleryItemA > 1){
currentGalleryItemA--;
slideRightA();
}
}
else if(event.offsetX == -1)
{
if(currentGalleryItemA < totalGalleryItemsA){
currentGalleryItemA++;
slideLeftA();
}
}
}
var slideCounterA:Number = 0;
function slideLeftA(){
lsn113.addEventListener("enterFrame", moveGalleryLeftA);
}
function slideRightA(){
lsn113.addEventListener("enterFrame", moveGalleryRightA);
}
function moveGalleryLeftA(evt:Event){
lsn113.x -= 128;
slideCounterA++;
if(slideCounterA == 10){
lsn113.removeEventListener("enterFrame", moveGalleryLeftA);
slideCounterA = 0;
}
}
function moveGalleryRightA(evt:Event){
lsn113.x += 128;
slideCounterA++;
if(slideCounterA == 10){
lsn113.removeEventListener("enterFrame", moveGalleryRightA);
slideCounterA = 0;
}
}
Home113.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndStopAtFrame_23);
function fl_ClickToGoToAndStopAtFrame_23(event:MouseEvent):void
{
gotoAndStop(2);
}
stop()
还有一个按钮,它是正在滑动的影片剪辑“lsn112”的一部分。不知道这是否相关,但代码是:
stop();
fwdtest.addEventListener(MouseEvent.CLICK, GoRootNext112);
function GoRootNext112(event:MouseEvent):void
{
MovieClip(root).nextFrame();
}
它在某种程度上工作正常,但我认为事件侦听器没有被正确删除。当用户滑动浏览图库时,它会按预期工作。然后他们可以移动到下一个图库,它也按预期工作。到目前为止没有错误。但是,如果他们返回菜单,然后返回图库,我会收到错误代码 1009:
TypeError: Error #1009: Cannot access a property or method of a null object reference. at MusicTheorySwipe_fla::MainTimeline/slideRightA()[MusicTheorySwipe_fla.MainTimeline::frame6:32] at MusicTheorySwipe_fla::MainTimeline/fl_SwipeToGoToNextPreviousFrameA()[MusicTheorySwipe_fla.MainTimeline::frame6:16] at runtime::ContentPlayer/simulationSendGestureEvent() at runtime::SimulatedContentPlayer/clientSocketDataHandler()
让我感到困惑的是,我此时正在使用第 5 帧,但我收到引用第 6 帧的错误。在我看来,即使我在第 5 帧上,Flash 也试图向第 6 帧中的事件侦听器发送手势,我猜这是由于事件侦听器未被删除。但是,由于我是代码新手,我不知道何时应该在不破坏代码的情况下删除事件监听器。
这是包含相关 .fla、.swf 和 .xml 文件的 zip 链接。 http://speedy.sh/5JP7c/MusicTheorySwipe.zip
由于这是我想在许多帧上使用的方法,因此非常感谢您花时间并帮助解决此问题。
编辑
好的,我已尽可能简化代码,以尝试消除任何嫌疑。
第 5 帧:
Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipeA);
var currentGalleryItemA:Number = 1;
var totalGalleryItemsA:Number = 5;
function onSwipeA (e:TransformGestureEvent):void{
//User swiped towards right
if (e.offsetX == 1) {
if(currentGalleryItemA > 1){
currentGalleryItemA--;
lsn113.x += 1280;
}
}
//User swiped towards left
if (e.offsetX == -1) {
if(currentGalleryItemA < totalGalleryItemsA){
currentGalleryItemA++;
lsn113.x -= 1280;
if(currentGalleryItemA == totalGalleryItemsA){
nextFrame()
}
}
}
}
stop();
第 6 帧:
stage.removeEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipeA);
Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipeB);
var currentGalleryItemB:Number = 1;
var totalGalleryItemsB:Number = 11;
function onSwipeB (e:TransformGestureEvent):void{
//User swiped towards right
if (e.offsetX == 1) {
if(currentGalleryItemB > 1){
currentGalleryItemB--;
lsn112.x += 1280;
}
}
//User swiped towards left
if (e.offsetX == -1) {
if(currentGalleryItemB < totalGalleryItemsB){
currentGalleryItemB++;
lsn112.x -= 1280;
}
if(currentGalleryItemB == totalGalleryItemsB){
nextFrame()
}
}
}
stop();
这就是现在所有的操作脚本,但它仍然不起作用。有什么想法吗?
在第 2 帧切换到第 6 帧时,检查舞台是否有事件侦听器 fl_SwipeToGoToNextPreviousFrameA(),如果有,则将其删除。这应该可以修复您的错误。
您需要在几帧处移除侦听器。
在 frame2 上编写所有代码之后的这些行
stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameA);
stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameB);
在 frame5 上定义侦听器之前编写此行
stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameA);
在 frame6 上定义侦听器之前编写此行
stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameB);
并从任何其他可以从 frame5 和 frame6 跳转的帧中移除这两者。