DannyBoy DannyBoy - 28 days ago 13
jQuery Question

How to stop the infinite loop in the play/pause control function

In my music player I have a function that controls the audio object and when the play/pause button is clicked it decides to either pause the sound or play it. Also if any other audio is playing when the button is clicked, it pauses them and play the sound corresponding to the click button.

This is the function:

function manageAudio() {
if (audio.paused) {

//play after 150ms
setTimeout(function() {
audio.play();
}, 150);

$('.playButton.playing').click();

$(thisObj).addClass("bekhon");
$(".sMusicPlyaer").removeClass("nakhon ");
} else {
audio.pause();

$(thisObj).addClass("nakhon");
$(".sMusicPlyaer").removeClass("bekhon");
}
}


Here is the full demo to have a look:



$.fn.MusicPlayer = function(options) {
var settings = $.extend({
// These are the defaults
title: "",
track_URL: "",
load_playlist: ""
}, options);
var audio, thisObj, playPauseBTN;
audio = new Audio();
thisObj = this;
playPauseBTN = $(".playButton", thisObj);

//Statuses Evnts
$(audio).on("playing", function() {
togglePlying(playPauseBTN, true);
$(playPauseBTN).addClass("pause");
});
$(audio).on("pause", function() {
togglePlying(playPauseBTN, false);
$(playPauseBTN).removeClass("pause");
});


thisObj.each(function() {
audio.src = settings.track_URL;
$(".title", thisObj).text(settings.title);

if (settings.load_playlist == "true") {
$(thisObj).css("height", "140px");
$(thisObj).append("<div class='playlist'></div>");
$(".playlist", thisObj).append("<div class='row' data-src='https://p.scdn.co/mp3-preview/c92cc644b1eb5094ce65cf561c41b0c6d9f3faaa'>music 1</div>");
$(".playlist", thisObj).append("<div class='row' data-src='https://p.scdn.co/mp3-preview/dc73c2b8aa08c7b5ac2c72813326fbd6aa65787b'>music 2</div>");
$(".playlist", thisObj).append("<div class='row' data-src='https://p.scdn.co/mp3-preview/b2da3e7ee2834c24fbf5a0927e59d34cc618e30e'>music 3</div>");
}
});


$(playPauseBTN, thisObj).on("click tap", function() {
manageAudio();
});

$(".playlist > .row", thisObj).on("click tap", function() {
audio.src = $(this).attr("data-src");
manageAudio();
});


function manageAudio() {
if (audio.paused) {

//play after 150ms
setTimeout(function() {
audio.play();
}, 150);

console.log("print");
$('.playButton.playing').click();

$(thisObj).addClass("bekhon");
$(".sMusicPlyaer").removeClass("nakhon ");
} else {
audio.pause();

$(thisObj).addClass("nakhon");
$(".sMusicPlyaer").removeClass("bekhon");
}
}
}


// Utility functions
function togglePlying(aClassName, bool) {
$(aClassName).toggleClass("playing", bool);
}

$("#player1").MusicPlayer({
title: "title 1",
track_URL: "https://rjmediamusic.com/media/mp3/mp3-256/Alireza-JJ-Sijal-Nassim-Ki-Khoobe-Ki-Bad-(Ft-Behzad-Leito-Sami-Low-AFX).mp3"
});

$("#player2").MusicPlayer({
title: "title 2",
track_URL: "http://myst729.qiniudn.com/within-temptation_pale.mp3",
load_playlist: "true"
});

$("#player3").MusicPlayer({
title: "title 3",
track_URL: "https://p.scdn.co/mp3-preview/657f7141682f667253bf9c3afab5feebccf75105"
});

body {
background: url(http://wallpapercave.com/wp/VkyGWEi.jpg) no-repeat;
background-size: cover;
}

.sMP {
background: rgba(255, 255, 255, 0.5);
color: #000;
width: 400px;
height: 50px;
margin: 10px;
}

.playButton {
background: url(https://cdn4.iconfinder.com/data/icons/standard-free-icons/139/Play01-64.png);
background-size: 30px 30px !important;
width: 30px;
height: 30px;
}

.playButton.pause {
background: url(https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-pause-48.png);
}

.row {
border: 1px solid black;
margin: 5px 0 5px 0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sMP" id="player1">
<div class="playButton"></div>
<div class="title"></div>
</div>
<div class="sMP" id="player2">
<div class="playButton"></div>
<div class="title"></div>
</div>
<div class="sMP" id="player3">
<div class="playButton"></div>
<div class="title"></div>
</div>





JSFiddle:

To see the error, click on the play button in player 2, then change the track by click on another track in the same playlist.
it ends up with
Uncaught RangeError: Maximum call stack size exceeded(…)
error. It is most likely related to
$('.playButton.playing').click();
.

Any solution to fix it?

Answer

You have to make sure you are clicking the play button outside your current playlist.

So instead of doing $('.playButton.playing').click(); you can do:

  var $playing = $('.playButton.playing');

  if ($(thisObj).find($playing).length === 0) {
     $playing.click();
  }

This way you are not clicking again the play button in the middle box.