如何在mouseEvent的情况下仅触发一次函数

时间:2010-10-31 08:21:48

标签: flex flash actionscript-3 audio mp3

我正在尝试使用flash创建一个简单的MP3播放器。使用包含歌曲列表的XML文件加载歌曲。我有“播放”按钮,实例名称为“PlayBtn”。我有一个名为“playctrl”的actionscript文件,其内容如下:

package classes
{
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.events.*;
    import flash.events.MouseEvent;
    import flash.net.URLRequest; 

    public class playctrl
    {
        private var MusicLoading:URLRequest;                        
        private var music:Sound;
        private var sc:SoundChannel;
        private var currentSound:Sound;
        private static var CurrentPos:Number;                               
        private var xml:XML;
        private var songlist:XMLList;                               
        private static var currentIndex:Number;                     

        public function playctrl()
        {
            music = new Sound();
            currentSound= music;
            CurrentPos = 0;
            currentIndex = 0;   
        }

        public function success(e:Event):void 
        {
            xml = new XML(e.target.data);
            songlist = xml.song;
            MusicLoading = new URLRequest(songlist[0].file);
            music.load(MusicLoading);
        }

        public function playSong(e:Event):void 
        {
            if(sc != null)
                sc.stop();

            sc = currentSound.play(CurrentPos);
            trace("HELLO !!!");
        }

    }
}

我有一个名为“play.as”的第二个文件,其内容如下:

import classes.playctrl;

var obj:playctrl = new playctrl();
var XMLLoader:URLLoader = new URLLoader();          //XML Loader

XMLLoader.addEventListener(Event.COMPLETE, obj.success);
XMLLoader.load(new URLRequest("playlist.xml"));

PlayBtn.addEventListener(MouseEvent.CLICK, obj.playSong);

然而,在单击播放按钮时,我注意到函数playSong()被调用了7-8次(通过在函数内部打印错误消息来检查)导致音频输出重叠并且播放器因此而崩溃。触发MouseEvent.CLICK时,只应调用该函数一次。请帮忙......

2 个答案:

答案 0 :(得分:0)

编辑:

你的问题的标题有点误导,我给你的答案是标题中表达的问题的解决方案。

看看你的代码,我会考虑分离问题,一方面你要加载歌曲数据,另一方面你要控制声音。我会为每个问题实现单独的类。如果您为播放器控件创建一个单独的类,您将能够在该类中调度事件,而不会在整个应用程序中冒泡并多次调用您的函数。

//上一个答案 您可以通过实现在声音停止或播放时设置的布尔值来实现此目的。

无论如何,这是另一种过滤不必要点击的方法

 private function playSong(event:MouseEvent ):void
 {
     // set up a conditional to identify your button , 
     // here's an example...
     if( event.currentTarget.name is "PlayBtn" )
     {
         //do whatever
         //then...
         event.stopImmediatePropagation();
      }

  }

这就是说,在你的情况下,这听起来有点像快速修复,因为MouseEvent不应该多次触发播放功能......

调试代码是有意义的,以便了解鼠标单击后调度多个事件的原因

 private var _isPlaying:Boolean;

 public function playSong(e:Event):void 
 {
   if(sc != null)
   {
      sc.stop();
      _isPlaying = false;
   }

   if( !_isPlaying )
   {
      sc = currentSound.play(CurrentPos);
      _isPlaying = true;
      trace("HELLO !!!");
   }
 }

答案 1 :(得分:0)

有趣的是,声音对象没有内置的“isPlaying”布尔属性(奇怪),所以你可以创建自己的。

var isPlaying:Boolean

function playSong():void
     {
     if(!isPlaying)
       sound.play();
     }

function stopSong():void
     {
     if(isPlaying)
       {
       channel.stop();
       isPlaying = false;
       }

只是一个注释:按照惯例,类名是大写的驼峰案例,而实例名称是非大写的驼峰案例。所以你的playctrl.as类文件应该(或可能)是PlayCtrl.as,你的PlayBtn实例应该(或可能)是playBtn。