jQuery Function malfunctioning after initial click

I have developed a function that plays and pauses music. It is designed to be simple and lightweight for small audio samples, with basic play and stop functionalities. The issue I'm encountering is that after playing the music for the second time, the classes are not switching correctly for pausing.

Below is the jQuery code snippet:

var isPlaying = false;
function playMusic(){
    var audioElement = document.createElement('audio');
    var audioElementSrc = $(this).attr('data-audio-src');               

    if (isPlaying != true)
    {
        isPlaying = true;
        audioElement.setAttribute('src', audioElementSrc);
        $.get();
        audioElement.addEventListener("loadeddata", function(){
            audioElement.play();                
        }, true);
        audioElement.addEventListener("ended", function() {
            isPlaying = false;    
        });  
        $(this).addClass('pause');
        $(this).removeClass('play'); 
        $('.pause').click(function() {
            audioElement.pause();
            isPlaying = false
            $(this).removeClass('pause');
            $(this).addClass('play');
        });             
    }
    else
    {
        return false;
    }           
}

$(function(e){
    $('.play').click(playMusic);  
});

You can view the jsfiddle Here which showcases the issue - when you click on stop and then try to play again, the classes do not switch as expected.

Answer №1

You have definitely made things more complicated by using plain JavaScript functions and replacing the audio element every time the play button is clicked.

Try incorporating more jQuery into your code and storing the audio element - it will make things much simpler

$(function (e) {
    $('.play').click(function() {
        var self = $(this).toggleClass('pause play');

        if (!this.audio) {
            this.audio = $('<audio />', {src : self.data('audio-src')}).on({
                loadeddata : function() {
                    this.play();
                },
                ended : function() {
                    self.toggleClass('pause play');
                }
            }).get(0);
        }else{
            this.audio[this.audio.paused ? 'play' : 'pause']();
        }
    });
});

FIDDLE

Answer №2

Upon reviewing the play code, I came across the following:

$('.pause').click(function() {
  audioElement.pause();
  isPlaying = false
  $(this).removeClass('pause');
  $(this).addClass('play');
});

The issue here is that this code is changing an element with the class .pause, which ends up overriding the function it's contained in! Additionally, the main if statement appears as follows:

if (isPlaying != true)
{
// Play code here           
}
else
{
return false;
}

What you actually need is:

    if (isPlaying != true)
    {
    // Play code here           
    }
    else
    {
    // Pause code here
    }

With these changes implemented, your new code will be structured like so:

 var isPlaying = false;
            function playTune(){
                    var audioTrack = document.createElement('audio');
                    var trackSource = $(this).attr('data-track-source');               

                    if (isPlaying != true)
                    {
                        isPlaying = true;
                        audioTrack.setAttribute('src', trackSource);
                        $.get();
                        audioTrack.addEventListener("loadeddata", function(){
                        audioTrack.play();                
                        }, true);
                         audioTrack.addEventListener("ended", function() {
                         isPlaying = false;    
                        });  
                        $(this).addClass('pause');
                        $(this).removeClass('play');            
                    }
                    else
                    {
                        audioTrack.pause(); 
                        isPlaying = false
                        $(this).removeClass('pause');
                        $(this).addClass('play');
                    }           
                }

            $(function(e){
                $('.play').click(playTune);  
            });

Answer №3

Avoid placing the code snippet within this section as it may cause issues. Instead, consider adding the pause function at the beginning only once using a delegate like this:

$(".songPlayer").delegate('.pause','click', function());

The issue arises from attaching the event on pause multiple times, leading to it being called repeatedly with each click.

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

PHP echo functions are not functioning properly in a dynamically loaded PHP page through jQuery's .load function

Within my WordPress installation, I have index.php and desktop.php files. The goal is to load desktop.php into #tLoad only if the browser window width is greater than 800px. While this works fine, I am encountering issues when trying to use PHP functions a ...

Accessing the current frame of a video in JavaScript or jQuery

Currently, I am experimenting with the HTML video tag to play a video. Instead of retrieving the "currentTime" of the video, I am interested in obtaining the current frame using either jQuery or JavaScript. Despite my efforts in calculating the frame rate ...

Exploring the JSON structure

Struggling to come up with a solution as I am limited by certain restrictions. I need to create a mobile navigation system using a JSON object provided by the proprietary server. The only allowed framework is jQuery 1.12.4, no other frameworks or updated v ...

What is the process for transforming information from a database into a clickable hyperlink?

My course list includes the following: SE1111 SE2222 SE3333 I want to display this list on my webpage and have it redirect to a page where the course name is saved for future use. Here's what I've tried so far: <div id="join_courses" clas ...

Flexbox keeps elements on the same line without breaking

I'm currently delving into flexbox and aiming to create a layout similar to the one shown below: https://i.sstatic.net/epnkU.png Here is the code I have come up with: .container { display: flex; gap: 26px; } .flex50 { flex: 50%; ...

div table with varying cell styles on each row

Is it feasible to achieve a table layout resembling the one depicted below using only div tags and CSS? _________________________________________________ | | | | | | | | ...

Ways to vertically center an absolutely positioned element

In the code snippet below, there is a .square-container that is absolutely positioned and contains a square. The goal is to vertically center the .square-container within its parent div. .container { position: relative; background-color: blue; } ...

Display or conceal a div based on the size of the screen using HTML and CSS

Hey there, I recently finished my first React Project and I’m wondering if there’s a way to hide the 'side-menu' section on mobile screens using CSS. Any suggestions? <div className='side-menu'> <SiderComponent /> < ...

Having difficulty invoking a JavaScript function through PHP

My goal is to achieve the following: <html> <script type="text/javascript" src="jquery.js"></script> <a id="random">before</a> <script> function test(a) { document.getElementById('random').innerHTM ...

Having trouble getting wire:click to work within an if statement in Laravel Livewire

I am currently in the process of creating a popover feature for my website that should open when I click on a phone number. Upon clicking on the phone number, it triggers a function called "startCall" in my Livewire component which sets the value of $calli ...

The text should be wrapped to overlap with an image positioned above it

Currently, I am in the process of enhancing a webpage that contains a significant amount of old legacy code. One issue I have encountered pertains to text wrapping within a fixed-height and width container, as illustrated in the image below: The first ima ...

Clear session data when logging out from a dropdown list

I have a header that appears on several of my web pages. It contains a dropdown menu that allows users to log out by selecting the "Logout" option. When a user clicks on "Logout", I want to destroy the session variables associated with their session. Is t ...

What is the best way to align a Font Awesome icon within an SVG circle?

Can anyone help me position the trophy inside the circle, just below the number 2000? <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1b7974746f686f697a6b5b2e352835 ...

Attempting to extract information from website, successful on majority of sites but encountering issues on this particular one

We are looking to extract dividend data specifically from the Nasdaq exchange similar to this Google Sheets example. While most other URLs work without any issues, the query for this one seems to be failing. <?php $ch = curl_init(); curl_setopt($ch, C ...

When JSON data is displayed in an HTML table, it mysteriously duplicates

I was able to retrieve the data using this code, but I am encountering an issue where the data is being displayed multiple times for certain entries. For example, "tom" might appear as tom, tom, tom... <div class="row"> <div class="col-12"> ...

"Sending data with jQuery by encoding an array in PHP and converting it

This question has been raised in various forms before. I am facing a challenge when it comes to transferring data from a JSON encoded array to another page on my domain. Below is the PHP code snippet: <?php $json_results = json_encode($results); ...

Centered buttons placed right next to each other

Having trouble getting my buttons centered and aligned side by side on the screen. I've managed to achieve one or the other but not both simultaneously. Currently, the buttons are next to each other but positioned at the top left corner of the screen. ...

Exploring Image Access with Rails and jQuery

Currently, I am facing an issue with accessing images uploaded to my Rails app using jQuery. Specifically, I want to switch out images and perform similar tasks. The jQuery implementation is quite simple: $('#a1').change(function() { var src = ...

Randomly switch out the wordpress header image at designated intervals

I have a custom header image on my website that displays 6 random images each time the site is visited. I am attempting to change this group of images while the user is browsing my site. Here is the code I am using: function show_banner(){ document.ge ...

File uploads in Django may pose a challenge when the request is sent from Ajax along with a form

I'm facing an issue while attempting to upload a file in Django using Ajax post. Unfortunately, it doesn't seem to work as expected. Here is the HTML code snippet responsible for handling the upload: <form action="{% url 'saveprof' ...