为什么音频停止播放滚动

Why does audio stop playing on scroll?

本文关键字:播放 滚动 音频 为什么      更新时间:2023-09-26

下面是我想要实现的代码:

http://codepen.io/golfecholima/pen/GJqEOm

它是位于右下角的一个小音频bug。当用户滚动过页面上的某个元素时,<audio src="">会发生变化。这是jQuery:

// BRING IN YOUR AUDIO FILES HERE
var audioOne = 'https://d63kb4t2ifcex.cloudfront.net/201505horton/mp3/Horton_ImNotThisPicture.mp3';  // replace these with your audio files 
var audioTwo = 'https://d63kb4t2ifcex.cloudfront.net/201505horton/mp3/Horton_WeHadBackThen.mp3';  // replace these with your audio files
var audioThree = 'https://d63kb4t2ifcex.cloudfront.net/201505horton/mp3/Horton_IveNeverBeen.mp3';  // replace these with your audio files
var audioFour = 'https://d63kb4t2ifcex.cloudfront.net/201505horton/mp3/Dukakis_OneOfTheValuesofFurlough.mp3';  // replace these with your audio files
// SET YOUR SCROLL BREAKPOINTS HERE 
var breakOne = 0;
var breakTwo = $('.audio-two').offset().top - $(window).height();
var breakThree = $('.audio-three').offset().top - $(window).height();
var breakFour = $('.audio-four').offset().top - $(window).height();

// SET YOUR AUDIO FILE TITLES
var titleOne = 'LISTEN: The first audio file';
var titleTwo = 'LISTEN: The second audio file';
var titleThree = 'LISTEN: The third audio file';
var titleFour = 'LISTEN: The fourth audio file';
// DO THE STUFF
var audioElement = document.createElement('audio');
    audioElement.setAttribute('src', audioOne);
    audioElement.setAttribute('preload', 'auto');
    //audioElement.load()
    $.get();
    audioElement.addEventListener("load", function() {
    audioElement.play();
    }, true);
    // controls the playing of the audio
    $('.audioBug').click(function() {
        if ($(this).hasClass('playing')) {
            audioElement.pause();
            $(this).removeClass('playing');
        } else {
            audioElement.play();
            $(this).addClass('playing');
        }
    });
    // collapses the bug 5 seconds after loading
    function removeBumper() {
        setTimeout(function() {
            $('.audioBug > h6').fadeOut(500, function() {
                $('.audioBug').animate({width: '4rem'}, 'fast');
            });
        }, 5000);
    }
    //hovering over the bug expands it to reveal the audio title. 
    $('.audioBug').hover(function() {
        $(this).animate({width: '28rem'}, 'fast');
        $('.audioBug > h6').fadeIn('slow');
    }, function() {
        setTimeout(function() {
            $('.audioBug > h6').fadeOut(500, function() {
                $('.audioBug').animate({width: '4rem'}, 'slow');
            });
        }, 1000);
    });
    //page loads, audio bug expands to reveal title, then collapses again
    setTimeout(function previewBug() {
        $('.audioBug').animate({width: '28rem'}, 'fast');
    }, 1000);
    setTimeout(function() {
        $('.audioBug > h6').fadeIn(300, function() {
            removeBumper();
        });
    }, 2700);
    //scrolling through set ranges changes the audio file/title and expands the bug anew
    $(window).scroll(function() {
        if ($(this).scrollTop() > breakOne && $(this).scrollTop() < breakTwo) {
            audioElement.setAttribute('src', audioOne);
            $('.audioBug > h6').text(titleOne);
        } 
        else if ($(this).scrollTop() > breakTwo && $(this).scrollTop() < breakThree) {
            audioElement.setAttribute('src', audioTwo);
            $('.audioBug > h6').text(titleTwo);
        } 
        else if ($(this).scrollTop() > breakThree && $(this).scrollTop() < breakFour) {
            audioElement.setAttribute('src', audioThree);
            $('.audioBug > h6').text(titleThree);
        } 
        else if ($(this).scrollTop() > breakFour) {
            audioElement.setAttribute('src', audioFour);
            $('.audioBug > h6').text(titleFour);
        }
    });

它的功能是我所期望的,除了一旦你开始滚动音频停止,即使下一个断点还没有达到。我的理解是,.scroll()触发任何时间有滚动活动。因此,我可以看到,如果函数不断检查哪个文件应该在适当的位置,这将破坏播放。

有什么办法可以防止这种情况发生吗?我已经看到了一些ajax的东西,它们看起来可能是正确的想法,但我太笨了,还没有发现。

我试过setTimeout,但似乎没有帮助。

(我知道悬停有点不稳定——不用担心)

当src属性在滚动期间不断设置时,浏览器将终止当前音频并开始加载"新"源(即使它是相同的)。

这里有一个简单的方法可以解决这个特定的问题,检查当前源是否等于被检查的源:

$(window).scroll(function() {
  if ($(this).scrollTop() > breakOne && $(this).scrollTop() < breakTwo &&
     audioElement.src !== audioOne) {  // CHECK that it's not the same as current source
    audioElement.setAttribute('src', audioOne);
    $('.audioBug > h6').text(titleOne);
  } else if ($(this).scrollTop() > breakTwo && $(this).scrollTop() < breakThree && audioElement.src !== audioTwo) {
    audioElement.setAttribute('src', audioTwo);
    $('.audioBug > h6').text(titleTwo);
  } else if ($(this).scrollTop() > breakThree && $(this).scrollTop() < breakFour  && audioElement.src !== audioThree) {
    audioElement.setAttribute('src', audioThree);
    $('.audioBug > h6').text(titleThree);
  } else if ($(this).scrollTop() > breakFour  && audioElement.src !== audioFour) {
    audioElement.setAttribute('src', audioFour);
    $('.audioBug > h6').text(titleFour);
  }
});

修改CodePen

虽然代码中还有其他问题,但这应该有助于由于不断重新加载新源而导致的音频停止。

一种不需要太多改变的方法是在滚动事件中添加switch_audio函数,该函数将被调用,而不是调用setAttribute。在那个函数中,你验证是否需要更改音频,如果需要,你就更改它。像这样:

 if ($(this).scrollTop() > breakOne && $(this).scrollTop() < breakTwo) {
    set_audio(audioOne, titleOne);           
  } 

和你的功能:

function set_audio(which_audio, which_title){
    if(audioElement.src != which_audio){
        audioElement.setAttribute('src', which_audio);
        $('.audioBug > h6').text(which_title);
    }
}