#1
  1. Retired
    Devshed Supreme Being (6500+ posts)

    Join Date
    Feb 2002
    Location
    Finland
    Posts
    9,115
    Rep Power
    2496

    Angry Create button to simulate event called through addEventListener


    Hi all, long time since I last posted on these forums :-)
    Hope this is not to obvious a question but it is beginning to drive me nuts.

    I am trying to make a simple mp3 player in HTML with some JavaScript thrown in.
    I managed to get the code to work as expected, but I want to add a "next" button...

    Currently play, pause and volume buttons work, but to get a next button requires, I think,
    to run some functions that are called through init()

    So, in the head of the document I have the following JS...
    (code is not mine, credit in the html > title :-)

    Code:
    <title>HTML5 Audio with playlists by lastrose</title>
    
    <script type='text/javascript'>
    
    $(document).ready(function () {
    var audio;
    var playlist;
    var tracks;
    var current;
    
    init();
    function init() {
        current = 0;
        audio = $('#audio');
        playlist = $('.playlist');
        tracks = playlist.find('a');
        len = tracks.length - 1;
        audio[0].volume = .75;
        audio[0].play();  
        playlist.find('a').click(function (e) {
            e.preventDefault();
            link = $(this);
            current = link.parent().index();
            run(link, audio[0]);
        });
        audio[0].addEventListener('ended', function (e) {
            current++;
            if (current > len) {
                current = 0;
                link = playlist.find('a')[0];
            } else {
                link = playlist.find('a')[current];
            }
            run($(link), audio[0]);
        });
    	
    }
    
    function run(link, player) {
        player.src = link.attr('href');
        par = link.parent();
        par.addClass('active').siblings().removeClass('active');
        audio[0].load();
        audio[0].play();
        }
    })
    
    </script>
    My "player" generates the following code.

    Code:
        <audio id="audio" preload="auto" tabindex="0" type="audio/mpeg" controls="">
            <source type="audio/mp3" src="../Music/dyslexia.mp3">
            Sorry, your browser does not support HTML5 audio.
        </audio>
        <dl id="playlist">
            <dt class="active playlist"><a href="../Music/dyslexia.mp3">Dyslexia</a></dt>
    		<dd>Some description, read it out and provide a <a href="#">link</a></dd>
            <dt class="playlist"><a href="../Music/can-the-president-be-impeached.mp3">Impeached</a></dt>
    		<dd>Some more description, read it out and provide a <a href="#">link</a></dd>
            <dt class="playlist"><a href="../Music/trump_again.mp3">Trump again</a></dt>
    		<dd>Even more description, read it out and provide a <a href="#">link</a></dd>
        </dl>
    This works fine, although doesn't start automatically on mobile browser, but that's another story.
    Anyway, I have then added some buttons to the HTML code.

    Code:
    <div> 
      <button onclick="document.getElementById('audio').play()">Play</button> 
      <button onclick="document.getElementById('audio').pause()">Pause</button> 
      <button id="next" onclick="document.getElementById('audio').next()">Next</button> 
      <button onclick="document.getElementById('audio').volume += 0.1">Vol+ </button> 
      <button onclick="document.getElementById('audio').volume -= 0.1">Vol- </button> 
    </div>
    As I say play, pause, volume works, but how would I add a "next" button.
    I believe it would call something like the "ended" event.

    I've been searching for days, and not been able to get anything working: JavaScript noob unfortunately...
    Thanks in advance for any pointers in the right direction.
    Last edited by jabba_29; April 12th, 2017 at 01:47 AM. Reason: removed file locations

    Cheers,
    Jamie

    >_ My Music Blog | Losing weight @notsoheavyblog | My Tweets

    __________________

    Let the might of your compassion arise to bring a quick end
    to the flowing stream of the blood and tears .....
    Please hear my anguished words of truth.

    __________________
  2. #2
  3. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2009
    Location
    Jakarta, Indonesia.
    Posts
    277
    Rep Power
    36
    Hi
    The following might work. I haven't tested it though:
    PHP Code:
    $('#next').click(function(e){
      
    e.preventDefault();
      
      
    //find a DT element next to currently active DT
      //if it's at end of list, get 1st DT 
      
    var $nextDT playlist.find('.active').next();
      if(!
    $nextDT)
        
    $nextDT playlist.find('.playlist')[0];
      
      
    //stop current audio playback
      //play audio with updated track
      
    audio[0].pause();
      
    run($nextDT.find('a'), audio[0]);
    }); 
    You need to define it within $(document).ready(function(){}) block
    right after run() definition.

    And the onclick attribute wouldn't be needed. This should suffice:
    PHP Code:
    <button id="next">Next</button
  4. #3
  5. Retired
    Devshed Supreme Being (6500+ posts)

    Join Date
    Feb 2002
    Location
    Finland
    Posts
    9,115
    Rep Power
    2496

    Arrow


    Thank you @hdewantara - this is the first snippet that has come close to working. Unfortunately it doesn't quite work yet.
    Maybe it is to do with the placement of the snippet.

    From the code above, the $(document).ready(function(){} block ends just before the run() definition.
    If I place the code directly after, then nothing happens at all when I click.

    If I place the code within the document ready block, ( above run() ) then clicking the button works to the extent that it changes,
    but I get errors and nothing plays.

    Code:
    undefined:1 
    GET file:///C:/Users/Jamie/Desktop/undefined net::ERR_FILE_NOT_FOUND 
    player.html:1 
    Uncaught (in promise) DOMException: Failed to load because no supported source was found.
    Appreciate your help.

    Cheers,
    Jamie

    >_ My Music Blog | Losing weight @notsoheavyblog | My Tweets

    __________________

    Let the might of your compassion arise to bring a quick end
    to the flowing stream of the blood and tears .....
    Please hear my anguished words of truth.

    __________________
  6. #4
  7. Forgotten Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    15,971
    Rep Power
    9615
    The next button and onended should work the same way, right? Rather than have one call the other (next button triggering "the current track ended" is weird, and onended triggering a button click is weird) have them both call the same function (next button triggers a next track function, onended triggers a next track function).

    So basically move the onended code into a function, have the event handler call that, and have the next button's onclick handler call that too.

    Comments on this post

    • hdewantara agrees : good point!
  8. #5
  9. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2009
    Location
    Jakarta, Indonesia.
    Posts
    277
    Rep Power
    36
    Hi Jamie
    From the code above, the $(document).ready(function(){} block ends just before the run() definition.
    No it doesn't, from the look of the code you've posted.

    Code:
    undefined:1 
    GET file:///C:/Users/Jamie/Desktop/undefined net::ERR_FILE_NOT_FOUND 
    player.html:1 
    Uncaught (in promise) DOMException: Failed to load because no supported source was found.
    Hmm, maybe we've passed the wrong parameter to run(). I've just realized there're 2 anchors <a> inside a DT.
    Probably this one below would work? (changes in red):
    Code:
    $('#next').click(function(e){
      e.preventDefault();
      
      //find a DT element next to currently active DT
      //if it's at end of list, get 1st DT 
      var $nextDT = playlist.find('.active').next();
      if(!$nextDT)
        $nextDT = playlist.find('.playlist')[0];
      
      //stop current audio playback
      //play audio with updated track
      audio[0].pause();
      run($nextDT.find('a')[0], audio[0]);
    });
    By the way, I think @requinix has a good point.

    Hendra
  10. #6
  11. Retired
    Devshed Supreme Being (6500+ posts)

    Join Date
    Feb 2002
    Location
    Finland
    Posts
    9,115
    Rep Power
    2496
    Hi, thanks both for comments.
    No it doesn't, from the look of the code you've posted.
    Yes, you are correct.
    I started writing the post then fiddled around more with the code and forgot to remove that statement.

    Code:
    Uncaught TypeError: Cannot read property 'attr' of undefined
    The snippet adding the [0] did nothing, but I will see if I can figure out how to do what requinix suggested.
    It does make sense, just need to work out how to implement.
    Last edited by jabba_29; April 14th, 2017 at 05:53 AM.

    Cheers,
    Jamie

    >_ My Music Blog | Losing weight @notsoheavyblog | My Tweets

    __________________

    Let the might of your compassion arise to bring a quick end
    to the flowing stream of the blood and tears .....
    Please hear my anguished words of truth.

    __________________

IMN logo majestic logo threadwatch logo seochat tools logo