Challenges with personalized music player

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <style type="text/CSS">
            #custom{
                font-family: monospace;
                font-size: 16px;
                max-width: 650px;
                border-style: solid;
                border-color: black;
                border-width: 1px;
                border-radius: 5px;
                padding: 8px;
                padding-bottom: 15px;
                padding-left: 12px;
                padding-right: 12px;
            }
            img{
                margin-top: 3px;
                float: left;
            }
            #bar, #currentTime, #duration, #skip{
                display: inline-block;
            }
            #currentTime, #duration, #skip{
                margin: 0px;
                padding: 0px;
                margin-top: 3px;
                margin-left: 10px;
            }
            #bar{
                margin-top: 10px;
                height: 14px;
                width: 400px;
                background: lightgrey;
                border-radius: 50px;
                margin-left: 9px;

            }
            #slider{
                height: 14px;
                width: 15px;
                background: black;
                border-radius: 50px;
            }
        </style>
    </head>
    <body onLoad="count()">
        <script type="text/javascript">
            var track = 0;
            function count(){       
                var music = document.getElementById("myAudio");
                var duration = music.duration;
                var durationInMins = Math.floor(duration/60);
                var durationInSecs = Math.floor(duration-(durationInMins*60));
                    if(durationInSecs < 10){
                        var durationInSecs = "0" + durationInSecs;
                    }
                    if(durationInMins < 10){
                        var durationInMins = "0" + durationInMins;
                    }
                document.getElementById("duration").innerHTML = durationInMins + ":" + durationInSecs;
                var timer = setInterval( 
                    function(){
                        var music = document.getElementById("myAudio");
                        var currentTime = music.currentTime;
                        if(currentTime > 60){
                            var min = Math.floor(currentTime/60);
                            var sec = Math.floor(currentTime-(min*60)); 
                        }else{
                            var min = "0";
                            var sec = Math.floor(music.currentTime);                        
                        }
                        if(sec < 10){
                            var sec = "0" + sec;
                        }
                        if(min < 10){
                            var min = "0" + min;
                        }
                        document.getElementById("currentTime").innerHTML = min + ":" + sec;                     
                        var percent = 100 * (music.currentTime/duration) - 2;
                        document.getElementById("slider").style.marginLeft=percent + "%";
                    }
                , 1000);
                }
            function toggleP(){
                var music = document.getElementById("myAudio");
                if(music.paused == true){
                    music.play();
                }else if(music.paused == false){
                    music.pause();
                }
            }
            function skip(){
                var trackList = ["http://fidelak.free.fr/reprises/The%20Doors%20-%20People%20are%20Strange.mp3", "http://mp3light.net/assets/songs/14000-14999/14781-december-1963-oh-what-a-night-four-seasons--1411568407.mp3"];
                if(go == "back"){
                    track = track - 1;
                }
                if(go == "forward"){
                    track = track + 1;
                }
                var aa = clearInterval("timer");
                var music = document.getElementById("myAudio");
                music.pause();
                music.src=trackList[track];
                music.load();
                var a = setTimeout(function(){music.play(); count();} , 6000);
            }
        </script>
        <audio id="myAudio" src="http://fidelak.free.fr/reprises/The%20Doors%20-%20People%20are%20Strange.mp3">
        </audio>
        <br>
        <div id="custom">
            <img onClick="toggleP()" src="img/media-play-pause-resume.png" height="30px"/>
            <p id="currentTime">00:00</p>
            <div id="bar">
                <div id="slider"></div>
            </div>
            <p id="duration">00:00</p>
            <p id="skip"><strong><a onClick="go = 'back'; skip()"><<</a> <a onClick="go = 'forward'; skip()">>></a><strong></p>
        </div>
    </body>

Seek feedback and fixes for slider behavior after skipping songs. Also, discuss challenges in aligning the duration bar without affecting other elements. Any guidance on this matter would be highly appreciated. Thank you!

Answer №1

Check out this jsBin demo!

Avoid using inline JS in your HTML! It can make your code difficult to debug. Keep your logic separate from your presentation/template.

Let's start with understanding how variables work. Once you declare a var, there's no need to redeclare the same variable using var again within your code. Simply use or modify it. Declare all your variables at the top like so:

function getElementById(id){return document.getElementById(id);}

var musicElement = getElementById("myAudio"),
    trackInfoElement = getElementById("trackInfo"),
    durationElement = getElementById("duration"),
    currentTimeElement = getElementById("currentTime"),
    sliderElement = getElementById("slider"),
    prevButtonElement = getElementById("prev"),
    nextButtonElement = getElementById("next"),
    toggleElement = getElementById("toggle"),
    currentTime,
    trackList = [],
    currentTrackIndex = -1,
    totalTracks = trackList.length;

...and you're good to go. Avoid repeating variable declarations throughout your code.

If you want to provide more information to the user, consider storing data in Objects with desired properties:

trackList = [
  {
    artist : "The Doors",
    fileName : "People Are Strange",
    file : "http://fidelak.free.fr/reprises/The%20Doors%20-%20People%20are%20Strange.mp3"
  },
  // Additional track objects here...
]

This way, you can access audio paths and display additional track information to the user.

Remember the principle of Don't Repeat Yourself. Create functions that help abstract repetitive calculations and return formatted time values:

function formatTime(t) { 
  var minutes = ~~(t / 60),
      seconds = ~~(t % 60);
  return (minutes < 10 ? "0"+minutes : minutes) + ':' + (seconds < 10 ? "0"+seconds : seconds); 
}

Create specific functions for progress tracking, play/pause functionality, handling previous and next tracks, and setting up event listeners accordingly.

With all these functions in place, simply add the necessary event listeners:

// Event listeners setup
prevButtonElement.addEventListener("click", handleSkip);
nextButtonElement.addEventListener("click", handleSkip);
toggleElement.addEventListener("click", handlePlayPause);
musicElement.addEventListener("timeupdate", updateProgress);
musicElement.addEventListener("ended", handlePlayPause);

// Automatically start playing
nextButtonElement.click();

No need for a separate interval function when you have

musicElement.addEventListener("timeupdate", updateProgress)
taking care of it.

Answer №2

The skipping could potentially be due to the ongoing interval from the previous song that was never properly halted.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to convert an object with values into an array containing those values

To process the JSON data and convert it into an array with the same values for insertion into my PostgreSQL database using pool.query(message, values), where values should be an array if multiple are present. Currently, my object structure is as follows: { ...

Enhancing Your Website with WordPress Customizer API: Introducing Kirki's Repeater Image Feature

Allow me to clarify this situation as thoroughly as I can. To begin with, I am utilizing a toolkit known as Kirki to enhance the WordPress Customizer API Within my theme, there is a section that features a 4-column layout of services, each accompanied by ...

Axios - Error: Promise Rejected - The request was unsuccessful with a 500 status code

The Axios post request in my code for adding new articles is not going through, and I am encountering an error: Failed to load resource: the server responded with a status of 500 (Internal Server Error) createError.js:17 Uncaught (in promise) Error: Requ ...

Encountering an issue with the npm start command in my React application

After using npx create-react-app basic to create a React app, I navigated to the basic folder and attempted to start it with npm start. However, I encountered the following error: npm start <a href="/cdn-cgi/l/email-protection" class="__cf_email__" ...

Ways to split images and text in list items using CSS

Can the text be formatted in a specific location on the page, separate from the image and heading? This is the HTML code I am currently using: <div class="tab-pane container fade" id="environmental"> <div class="row"> <div class="c ...

Can you determine the height of an image if only the width and border width are provided?

Currently delving into the world of HTML and CSS, I've successfully configured the img element's width and border width using a style element. However, one aspect that is still puzzling me is how the height is calculated in this scenario. I&apos ...

Add a fresh column in the table that includes modified values from an existing column, affected by a multiplication factor provided through a text input

I'm currently working on a Laravel website where I have a pricing table sourced from a database. The Retail Price column in this table serves as the base for calculating and populating a Discount Price column using a multiplier specified in a text inp ...

When refreshing the page, the authentication token set in the Vuex store using axios in Nuxt.js/Vue.js gets reset

Here is the code snippet I am using to manage login, logout, user retrieval, and token setting for all axios requests as an auth header. While this code works perfectly during client-side rendering - such as logging in, storing the token in cookies, etc. ...

The data stored in LocalStorage disappears when the page is refreshed

I'm facing an issue with the getItem method in my localStorage within my React Form. I have added an onChange attribute: <div className = 'InputForm' onChange={save_data}> I have found the setItem function to save the data. Here is ...

How can I write the code to enable dragging the button for navigating to the next page?

<a draggable="true" class="user" id="leonardo" ondragstart="dragUser(this, event)" aria-selected="undefined"> IPD</a> If I want the button to navigate to the next page when dragged, what code should I write? ...

Issues with angular-strap popover's onBeforeShow function not functioning as expected in Angular

I am currently utilizing the angular-strap popover feature. To learn more about it, visit According to the documentation, when an onBeforeShow function is provided, it should be called before the popover is displayed. However, I am experiencing issues wit ...

Localization support is working partially in a Node Express application that uses Handlebars for templating

Whenever I visit a URL with the ?lang=en query parameter, the English translation is never used. However, the Hungarian text changes work perfectly fine, displaying text to test on Hungarian in the default "hu" language without any issues. What could be ca ...

Position the second line of text to align in MUI

I am facing an issue with aligning the text on the second line. It should match up with the text on the first line. For reference, you can check out the Codesandbox by CLICKING HERE <Card sx={{ maxWidth: 200 }}> <CardMedia component="i ...

What is the best way to link function calls together dynamically using RXJS?

I am seeking a way to store the result of an initial request and then retrieve that stored value for subsequent requests. Currently, I am utilizing promises and chaining them to achieve this functionality. While my current solution works fine, I am interes ...

Numerous pie charts created from data retrieved through multiple ajax requests

Hey there! I'm looking to create 3 pie charts side by side, each based on a different dataset retrieved through separate ajax calls. The first chart will be generated from the results of one call, the second from another, and the third from yet anothe ...

Manipulating links using JQuery: avoiding the binding of new links

I need to update a website with 50 pages that currently doesn't use ajax, making it cumbersome to make edits since changes have to be made on all 50 pages individually. After removing duplicate HTML from all 50 pages, I'm facing some issues: fu ...

SlickGrid checkbox formatter/editor experiencing issues with data consistency

Exploring the functionalities of SlickGrid'seditors/formatters, I delved into how these features could potentially alter the data object utilized for constructing the grid (as modifications within the table are usually reflected in the original data o ...

How can I customize the dropdown list arrow to match my own design?

Is there a simple way to substitute the standard arrow in the dropdown menu with a custom arrow image? ...

I am looking to remove identical innerText values from two arrays using JavaScript

Is it possible to use JavaScript to remove the "added" className of an element with the same innerText when the delete button (.btn-wrap>li>button) is clicked? <div class="table"> <ul> <li class="added">l ...

Is there a sweet TypeScript class constructor that can take in its own instance as an argument?

I have a scenario where I need to read in instances of Todo from a CSV file. The issue is that Papaparse does not handle dynamic conversion on dates, so I'm currently dropping the object into its own constructor to do the conversion: class Todo { ...