单击链接后 jQuery 音频停止

Posted

技术标签:

【中文标题】单击链接后 jQuery 音频停止【英文标题】:jQuery Audio Stop once Link is clicked 【发布时间】:2013-03-09 05:44:38 【问题描述】:

我有两个 jQuery 脚本正在运行:一个用于音频 mp3 播放器,另一个用于在 LightBox 中显示 YouTube 视频。现在,如果有人单击要播放的音频文件,即使单击视频的链接,它也会继续播放。

我希望音频停止播放,这样当灯箱打开时,我可以自动播放视频并且用户可以观看。

音频播放器实现:

<head>
<link rel="stylesheet" href="libs/css/styles.css" />
<script src="libs/jquery/jquery.js"></script>
<script src="src/jquery.ubaplayer.js"></script>
<script>
   jQuery.noConflict();
   jQuery(function()
            jQuery("#ubaPlayer").ubaPlayer(
            codecs: [name:"MP3", codec: 'audio/mpeg;']
            );
        );
</script>
</head>

<body>
<a class="audioButton" href="mp3/dontthinktwice.mp3">
        Don't Think Twice - Bob Dylan</a>
</body>

音频播放器脚本:

(function($) 
var defaults = 
    audioButtonClass: "audioButton",
    autoPlay: null,
    codecs: [
        name: "OGG",
        codec: 'audio/ogg; codecs="vorbis"'
    , 
        name: "MP3",
        codec: 'audio/mpeg'
    ],
    continuous: false,
    extension: null,
    flashAudioPlayerPath: "libs/swf/player.swf",
    flashExtension: ".mp3",
    flashObjectID: "audioPlayer",
    loadingClass: "loading",
    loop: false,
    playerContainer: "player",
    playingClass: "playing",
    swfobjectPath: "libs/swfobject/swfobject.js",
    volume: 0.5
,
    currentTrack, isPlaying = false,
    isFlash = false,
    audio, $buttons, $tgt, $el, playTrack, resumeTrack, pauseTrack, methods = 
        play: function(element) 
            $tgt = element;
            currentTrack = _methods.getFileNameWithoutExtension($tgt.attr("href"));
            isPlaying = true;
            $tgt.addClass(defaults.loadingClass);
            $buttons.removeClass(defaults.playingClass);

            if (isFlash) 
                if (audio) 
                    _methods.removeListeners(window);
                
                audio = document.getElementById(defaults.flashObjectID);
                _methods.addListeners(window);
                audio.playFlash(currentTrack + defaults.extension);
             else 
                if (audio) 
                    audio.pause();
                    _methods.removeListeners(audio);
                
                audio = new Audio("");
                _methods.addListeners(audio);
                audio.id = "audio";
                audio.loop = defaults.loop ? "loop" : "";
                audio.volume = defaults.volume;
                audio.src = currentTrack + defaults.extension;
                audio.play();
            
        ,

        pause: function() 
            if (isFlash) 
                audio.pauseFlash();
             else 
                audio.pause();
            

            $tgt.removeClass(defaults.playingClass);
            isPlaying = false;
        ,

        resume: function() 
            if (isFlash) 
                audio.playFlash();
             else 
                audio.play();
            
            $tgt.addClass(defaults.playingClass);
            isPlaying = true;
        ,

        playing: function() 
            return isPlaying;
        
    ,

    _methods = 
        init: function(options) 
            var types;

            //set defaults
            $.extend(defaults, options);
            $el = this;

            //listen for clicks on the controls
            $(".controls").bind("click", function(event) 
                _methods.updateTrackState(event);
                return false;
            );
            $buttons = $("." + defaults.audioButtonClass);

            types = defaults.codecs;
            for (var i = 0, ilen = types.length; i < ilen; i++) 
                var type = types[i];
                if (_methods.canPlay(type)) 
                    defaults.extension = [".", type.name.toLowerCase()].join("");
                    break;
                
            

            if (!defaults.extension || isFlash) 
                isFlash = true;
                defaults.extension = defaults.flashExtension;
            

            if (isFlash) 
                $el.html("<div id='" + defaults.playerContainer + "'/>");
                $.getScript(defaults.swfobjectPath, function() 
                    swfobject.embedSWF(defaults.flashAudioPlayerPath, defaults.playerContainer, "0", "0", "9.0.0", "swf/expressInstall.swf", false, false, 
                        id: defaults.flashObjectID
                    , _methods.swfLoaded);
                );
             else 
                if (defaults.autoPlay) 
                    methods.play(defaults.autoPlay);
                
            
        ,

        updateTrackState: function(evt) 
            $tgt = $(evt.target);
            if (!$tgt.hasClass("audioButton")) 
                return;
            
            if (!audio || (audio && currentTrack !== _methods.getFileNameWithoutExtension($tgt.attr("href")))) 
                methods.play($tgt);
             else if (!isPlaying) 
                methods.resume();
             else 
                methods.pause();
            
        ,

        addListeners: function(elem) 
            $(elem).bind(
                "canplay": _methods.onLoaded,
                "error": _methods.onError,
                "ended": _methods.onEnded
            );
        ,

        removeListeners: function(elem) 
            $(elem).unbind(
                "canplay": _methods.onLoaded,
                "error": _methods.onError,
                "ended": _methods.onEnded
            );
        ,

        onLoaded: function() 
            $buttons.removeClass(defaults.loadingClass);
            $tgt.addClass(defaults.playingClass);

            audio.play();
        ,

        onError: function() 
            $buttons.removeClass(defaults.loadingClass);
            if (isFlash) 
                _methods.removeListeners(window);
             else 
                _methods.removeListeners(audio);
            
        ,

        onEnded: function() 
            isPlaying = false;
            $tgt.removeClass(defaults.playingClass);
            currentTrack = "";
            if (isFlash) 
                _methods.removeListeners(window);
             else 
                _methods.removeListeners(audio);
            

            if (defaults.continuous) 
                var $next = $tgt.next().length ? $tgt.next() : $(defaults.audioButtonClass).eq(0);
                methods.play($next);
            

        ,

        canPlay: function(type) 
            if (!document.createElement("audio").canPlayType) 
                return false;
             else 
                return document.createElement("audio").canPlayType(type.codec).match(/maybe|probably/i) ? true : false;
            
        ,

        swfLoaded: function() 
            if (defaults.autoPlay) 
                setTimeout(function() 
                    methods.play(defaults.autoPlay);
                , 500);
            
        ,

        getFileNameWithoutExtension: function(fileName) 
            //this function take a full file name and returns an extensionless file name
            //ex. entering foo.mp3 returns foo
            //ex. entering foo returns foo (no change)
            var fileNamePieces = fileName.split('.');
            fileNamePieces.pop();
            return fileNamePieces.join(".");
        
    ;

$.fn.ubaPlayer = function(method) 
    if (methods[method]) 
        return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
     else if (typeof method === "object" || !method) 
        return _methods.init.apply(this, arguments);
     else 
        $.error("Method " + method + " does not exist on jquery.ubaPlayer");
    
;

灯箱实现:

<head>
<script type="text/javascript" src="videobox/js/mootools.js"></script>
<script type="text/javascript" src="videobox/js/swfobject.js"></script>
<script type="text/javascript" src="videobox/js/videobox.js"></script>
<link rel="stylesheet" href="videobox/css/videobox.css" type="text/css" media="screen" /></head>

<body>
<a href="http://www.youtube.com/watch?v=2sAnENc6ObI" rel="vidbox" title="The Rainbox Connection - Live at the Berklee Performance Center"><img src="playbtn.png" name="fakeplay" id="fakeplay">The Rainbow Connection (Video)</a>
</body>

灯箱脚本:

var Videobox = 
init: function (options) 
    // init default options
    this.options = Object.extend(
        resizeDuration: 400,    // Duration of height and width resizing (ms)
        initialWidth: 250,      // Initial width of the box (px)
        initialHeight: 250,     // Initial height of the box (px)
        defaultWidth: 625,      // Default width of the box (px)
        defaultHeight: 350, // Default height of the box (px)
        animateCaption: true,   // Enable/Disable caption animation
        flvplayer: 'swf/flvplayer.swf'
    , options || );

    this.anchors = [];
    $A($$('a')).each(function(el)
        if(el.rel && el.href && el.rel.test('^vidbox', 'i')) 
            el.addEvent('click', function (e) 
      e = new Event(e);
      e.stop();
      this.click(el);
            .bind(this));
            this.anchors.push(el);
        
, this);

    this.overlay = new Element('div').setProperty('id', 'lbOverlay').injectInside(document.body);
    this.center = new Element('div').setProperty('id', 'lbCenter').setStyles(width: this.options.initialWidth+'px', height: this.options.initialHeight+'px', marginLeft: '-'+(this.options.initialWidth/2)+'px', display: 'none').injectInside(document.body);

    this.bottomContainer = new Element('div').setProperty('id', 'lbBottomContainer').setStyle('display', 'none').injectInside(document.body);
    this.bottom = new Element('div').setProperty('id', 'lbBottom').injectInside(this.bottomContainer);
    new Element('a').setProperties(id: 'lbCloseLink', href: '#').injectInside(this.bottom).onclick = this.overlay.onclick = this.close.bind(this);
    this.caption = new Element('div').setProperty('id', 'lbCaption').injectInside(this.bottom);
    this.number = new Element('div').setProperty('id', 'lbNumber').injectInside(this.bottom);
    new Element('div').setStyle('clear', 'both').injectInside(this.bottom);

    var nextEffect = this.nextEffect.bind(this);
    this.fx = 
        overlay: this.overlay.effect('opacity', duration: 500).hide(),
        center: this.center.effects(duration: 500, transition: Fx.Transitions.sineInOut, onComplete: nextEffect),
        bottom: this.bottom.effect('margin-top', duration: 400)
    ;

,

click: function(link) 

        return this.open (link.href, link.title, link.rel);

,
open: function(sLinkHref, sLinkTitle, sLinkRel) 
    this.href = sLinkHref;
    this.title = sLinkTitle;
    this.rel = sLinkRel;
    this.position();
    this.setup();
    this.video(this.href);
    this.top = Window.getScrollTop() + (Window.getHeight() / 15);
    this.center.setStyles(top: this.top+'px', display: '');
    this.fx.overlay.start(0.8);
    this.step = 1;
    this.center.setStyle('background','#fff url(loading.gif) no-repeat center');
    this.caption.innerHTML = this.title;
    this.fx.center.start('height': [this.options.contentsHeight]);
,

setup: function()
    var aDim = this.rel.match(/[0-9]+/g);
    this.options.contentsWidth = (aDim && (aDim[0] > 0)) ? aDim[0] : this.options.defaultWidth;
    this.options.contentsHeight = (aDim && (aDim[1] > 0)) ? aDim[1] : this.options.defaultHeight;

,

position: function()
this.overlay.setStyles('top': window.getScrollTop()+'px', 'height': window.getHeight()+'px');
,

video: function(sLinkHref)
    if (sLinkHref.match(/youtube\.com\/watch/i)) 
  this.flash = true;
        var hRef = sLinkHref;
        var videoId = hRef.split('=');
        this.videoID = videoId[1];
        this.so = new SWFObject("http://www.youtube.com/v/"+this.videoID, "flvvideo", this.options.contentsWidth, this.options.contentsHeight, "0");
        this.so.addParam("wmode", "transparent");
    
    else if (sLinkHref.match(/metacafe\.com\/watch/i)) 
  this.flash = true;
        var hRef = sLinkHref;
        var videoId = hRef.split('/');
        this.videoID = videoId[4];
        this.so = new SWFObject("http://www.metacafe.com/fplayer/"+this.videoID+"/.swf", "flvvideo", this.options.contentsWidth, this.options.contentsHeight, "0");
        this.so.addParam("wmode", "transparent");
    
    else if (sLinkHref.match(/google\.com\/videoplay/i)) 
  this.flash = true;
        var hRef = sLinkHref;
        var videoId = hRef.split('=');
        this.videoID = videoId[1];
        this.so = new SWFObject("http://video.google.com/googleplayer.swf?docId="+this.videoID+"&hl=en", "flvvideo", this.options.contentsWidth, this.options.contentsHeight, "0");
        this.so.addParam("wmode", "transparent");
    
    else if (sLinkHref.match(/ifilm\.com\/video/i)) 
      this.flash = true;
        var hRef = sLinkHref;
        var videoId = hRef.split('video/');
        this.videoID = videoId[1];
        this.so = new SWFObject("http://www.ifilm.com/efp", "flvvideo", this.options.contentsWidth, this.options.contentsHeight, "0", "#000");
        this.so.addVariable("flvbaseclip", this.videoID+"&");
        this.so.addParam("wmode", "transparent");
    
    else if (sLinkHref.match(/\.mov/i)) 
      this.flash = false;
        if (navigator.plugins && navigator.plugins.length) 
      this.other ='<object id="qtboxMovie" type="video/quicktime" codebase="http://www.apple.com/qtactivex/qtplugin.cab" data="'+sLinkHref+'"  ><param name="src" value="'+sLinkHref+'" /><param name="scale" value="aspect" /><param name="controller" value="true" /><param name="autoplay" value="true" /><param name="bgcolor" value="#000000" /><param name="enablejavascript" value="true" /></object>';
   else 
    this.other = '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab"   id="qtboxMovie"><param name="src" value="'+sLinkHref+'" /><param name="scale" value="aspect" /><param name="controller" value="true" /><param name="autoplay" value="true" /><param name="bgcolor" value="#000000" /><param name="enablejavascript" value="true" /></object>';
  
    
    else if (sLinkHref.match(/\.wmv/i) || sLinkHref.match(/\.asx/i)) 
    this.flash = false;
     this.other = '<object NAME="Player" WIDTH="'+this.options.contentsWidth+'" HEIGHT="'+this.options.contentsHeight+'" align="left" hspace="0" type="application/x-oleobject" CLASSID="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6"><param NAME="URL" VALUE="'+sLinkHref+'"><param><param NAME="AUTOSTART" VALUE="false"></param><param name="showControls" value="true"></param><embed WIDTH="'+this.options.contentsWidth+'" HEIGHT="'+this.options.contentsHeight+'" align="left" hspace="0" SRC="'+sLinkHref+'" TYPE="application/x-oleobject" AUTOSTART="false"></embed></object>'
    
    else if (sLinkHref.match(/\.flv/i)) 
     this.flash = true;
     this.so = new SWFObject(this.options.flvplayer+"?file="+sLinkHref, "flvvideo", this.options.contentsWidth, this.options.contentsHeight, "0", "#000");
    
    else 
      this.flash = true;
        this.videoID = sLinkHref;
        this.so = new SWFObject(this.videoID, "flvvideo", this.options.contentsWidth, this.options.contentsHeight, "0");
    
,

nextEffect: function()
    switch (this.step++)
    case 1:
        this.fx.center.start('width': [this.options.contentsWidth], 'marginLeft': [this.options.contentsWidth/-2]);
        break;
        this.step++;
    case 2:
        this.center.setStyle('background','#fff');
        this.flash ? this.so.write(this.center) : this.center.setHTML(this.other) ;
        this.bottomContainer.setStyles(top: (this.top + this.center.clientHeight)+'px', height: '0px', marginLeft: this.center.style.marginLeft, width: this.options.contentsWidth+'px',display: '');
        if (this.options.animateCaption)
            this.fx.bottom.set(-this.bottom.offsetHeight);
            this.bottomContainer.style.height = '';
            this.fx.bottom.start(0);
            break;
        
        this.bottomContainer.style.height = '';
        this.step++;
    
,

close: function()
    this.fx.overlay.start(0);
    this.center.style.display = this.bottomContainer.style.display = 'none';
    this.center.innerHTML = '';
    return false;


;
window.addEvent('domready', Videobox.init.bind(Videobox));

【问题讨论】:

您的灯箱实现是什么样的?请提供代码 我可以在音频播放器的脚本中添加什么东西,当点击 时会发出停止信号?也许使用某个类? 是的,让我做点什么。 【参考方案1】:

你可以试试这样的:

$('a[rel=vidbox]').click(function () 

    if ($("#ubaPlayer").ubaPlayer("playing") === true) 
        $("#ubaPlayer").ubaPlayer("pause");
    
    return false;
);

小提琴here.

一点建议;如果您使用 mootools 来单独使用 Videobox,那么您应该考虑切换到 jQuery 灯箱。 Videobox 在自定义和回调支持方面似乎非常有限(查看它的源代码)。 Fancybox 和 Colorbox (jQuery) 等插件提供了更大的灵活性。

【讨论】:

我尝试了 Fancybox 和 Colorbox,但我始终无法让它们中的任何一个正常工作。最近,每次我用 Fancybox 嵌入视频时,它都会填满整个屏幕。 可能是因为实现错误。如果你能用你的 fancybox 实现发布一个 jsfiddle,我可以提供帮助。 另外,我无法让上述解决方案在上下文中工作。它只是继续播放。 可能与 Videobox 冲突。如果可以,请发布您的代码的 jsfiddle 供我处理。 终于修好了,伙计们!谢谢一百万!

以上是关于单击链接后 jQuery 音频停止的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery 单击另一个音频文件时停止/暂停音频

如何停止音频警报?

jquery停止子触发父事件

按钮单击音频启动和停止 JS

GridView 上的 jQuery 函数在页面回发后停止工作(鼠标悬停,单击)

通过单击图像切换音频“开始/停止”