Using the Soundcloud JavaScript SDK I have successfully been able to grab my tracks and play them. My goal is to allow playing and pausing via clicking on one button (like a play/pause toggle). However, my issue is that when I click on the .SCbtn element, the song plays, and doesn't stop. My conditionals seem to be correct because I can see true and false making it into the console. Not quite sure why SC.sound.pause(); isn't working.
var is_playing = false;
var trackCont = function(trackNum){
SC.stream("/tracks/" + trackNum).then(function(sound){
SC.sound = sound;
if (is_playing === false){
SC.sound.play();
is_playing = true;
console.log(is_playing);
}else if(is_playing === true){
SC.sound.pause();
is_playing = false;
console.log(is_playing);
}
});
}
$('body').on("click", ".SCbtn", function(){
var theTrack = $(this).attr('id');
trackCont(theTrack);
});
Update
My Fiddle
I think you're overcomplicating things. Here's a simple example:
HTML:
<script src="https://connect.soundcloud.com/sdk/sdk-3.0.0.js"></script>
<button id="play">Play</button>
JavaScript:
SC.initialize({
client_id: 'XXXX'
});
var myPlayer;
var isPaused = false;
SC.stream('tracks/43377447').then(function(player){
player.play()
myPlayer = player;
});
document.querySelector('button').addEventListener('click', function() {
if (isPaused) {
myPlayer.play()
isPaused = false;
} else {
myPlayer.pause()
isPaused = true;
}
});
Working JSFiddle.
You should use the toggle() method provided by Soundcloud for easiest implementation. See here: https://developers.soundcloud.com/docs/api/html5-widget
Something like the below should do the trick:
var sc = SC.Widget(iframe);
$('body').on("click", ".SCbtn", function(){
sc.toggle();
});
Related
Im building a .clicktoggle function in jQuery and for the life of me i can't get a .stop like effect on it, basically i don't want it to play over and over if mash clicked.
I want it to be applied the the function so its self contained, that's where im stuck.
JS fiddle link
(function($) {
$.fn.clickToggle = function(func1, func2) {
var funcs = [func1, func2];
this.data('toggleclicked', 0);
this.click(function() {
var data = $(this).data();
var tc = data.toggleclicked;
$.proxy(funcs[tc], this)();
data.toggleclicked = (tc + 1) % 2;
});
return this;
};
}(jQuery));
$('div').clickToggle(function() {
$('.testsubject').fadeOut(500);
}, function() {
$('.testsubject').fadeIn(500);
});
<div class="clickme">click me fast</div>
<div class="testsubject">how do i stop it playing over and over if you click alot</div>
Toggle .click seems like something alot of people would use so i thought it might be useful to ask it here
By adding a check to a boolean variable fadeInProgress, you can choose to only queue the animation if fadeInProgress is false. It then sets the value to true and executes the animation. When the animation is completed, set the value to false.
var fadeInProgress = false;
$('div').clickToggle(function() {
if (!fadeInProgress) {
fadeInProgress = true;
$('.testsubject').fadeOut(700, function(){fadeInProgress = false;});
}
}, function() {
if (!fadeInProgress) {
fadeInProgress = true;
$('.testsubject').fadeIn(700, function(){fadeInProgress = false;});
}
});
var clicked = false;
var doing = false;
$(".clickme").click(function(e) {
if (doing) {
return;
} else {
doing = true;
}
doing = true;
clicked = !clicked;
if (clicked) {
$('.testsubject').fadeOut(700, function() {
doing = false
});
} else {
$('.testsubject').fadeIn(700, function() {
doing = false;
});
}
});
This example is a simple toggle which only allows you to click when it is not doing anything. I explained on IRC, but as an example here, the function only runs when doing is set to false, which only happens when it's set after fadeIn() or fadeOut's callback function thingymajigger.
I have this piece of code and i can't prevent default link event all the time. It's working like 90% of the times, but the rest 10% my code doesn't run, get no error message and put a # on the end of my url. I have # on my href on my a tag.
I use .on() because sometimes the element is loaded after the document is ready. And i use .off() because before i used it, sometimes triggered more than once when i clicked on it. The strange part is sometimes. I don't get it how can a code sometimes work and sometimes dont. Shouldn't be the same result all the time?
Sorry for the lot of comments.
Here is my full jquery code:
//Handle box opening and closing
var boxcontent_width = $(".box-content").css("width");
$(".boxarrow").addClass("done");
$(document).on("click",".boxarrow", function(event){
var serial = $(this).parent().parent().attr("serial");
var clink = $(document).find("[comment-link='"+serial+"']");
if(clink.hasClass("open")){
clink.click();
}
if($(this).hasClass("done")){
$(this).removeClass("done");
$(document).find("#comment-box"+$(this).parent().parent().attr("serial")).slideUp(250);
if($(this).parent().parent().find(".box-content").is(":hidden")){
$(this).attr("src","source/up_arrow.png");
}else{
$(this).attr("src","source/down_arrow.png");
}
$(this).parent().parent().find(".box-content").slideToggle(500,function(){
$(this).parent().find("div img").addClass("done");
});
}
return false;
});
//Handle votes
$(document).on("click","#positive-button, #negative-button", function(event){
var serial = $(this).parents(".tutorial-box").attr("serial");
var vote = 0;
if($(this).attr("id") == "positive-button"){
vote = 1;
}
$.post("vote.php",{
php_tutorial_id: serial,
php_vote_value: vote
},function(data){
if(data.localeCompare("error") && data){
if(data > 9999)data = 9999;
if(data < -9999)data = -9999;
if(data > 0){
data = "+"+data;
}
$("#tutorial-vote"+serial+" p").fadeOut(250, function(){
$("#tutorial-vote"+serial+" p").html(data).fadeIn(250);
});
}
});
return false;
});
//Handle comment opening and closing
$(document).on("click",".showcomments", function(event){
if($(this).hasClass("open")){
$(this).html("<p>Show comments</p>");
$(this).removeClass("open");
}else{
$(this).html("<p>Hide comments</p>");
$(this).addClass("open");
}
var clink = $(this).attr("comment-link");
var is_open = $(this).hasClass("open");
$(this).parents().find("#"+clink).slideToggle(500);
return false;
});
//Handle add comment button
$(document).on("click",".comment-button", function(event){
var serial = $(this).attr("serial");
serial = "#comment-box"+serial;
$(document).find(".comment-box").not(serial).slideUp(250);
$(document).find(serial).slideToggle(250);
return false;
});
$(document).on("click",".comment-box-submit", function(event){
var tutorial_id = $(this).parent().attr("serial");
var comment_text = $(this).parent().find(".comment-box-area");
var serial = $(this).parent().attr("serial");
$.post("send_comment.php",{
php_tutorial_id: tutorial_id,
php_comment_text: comment_text.val()
},function(data){
$(document).find("#comment-response"+serial).fadeOut(500, function(){
if(data){
$(document).find("#comment-response"+serial).html(data);
$(document).find("#comment-response"+serial).fadeIn(500);
}else{
$(document).find("#comment-response"+serial).html("");
$.post("reflesh_comments.php",{
php_tutorial_id: tutorial_id
},function(data){
if($(document).find("#"+tutorial_id).is(":hidden")){
$(document).find("#"+tutorial_id).html(data);
}else{
$(document).find("#"+tutorial_id).fadeOut(500, function(){
$(document).find("#"+tutorial_id).html(data);
$(document).find("#"+tutorial_id).fadeIn(500);
});
}
});
$(document).find("#comment-response"+serial).html("");
comment_text.val("");
}
});
});
return false;
});
$(document).on("click",".comment-remove", function(event){
var serial = $(this).attr("serial");
var tutorial_serial = $(this).parent().parent().parent().attr("id");
$("#overlay-box").load("overlay_boxes/remove_comment.php", { php_serial: serial, php_tutorial_serial: tutorial_serial }, function(){
$("#overlay-box").fadeIn(250);
$("#overlay").fadeIn(250);
});
return false;
});
$(document).on("click",".comment-reply", function(event){
var serial = $(this).parent().parent().attr("serial");
var owner = $(this).parent().parent().find(".comment-owner").html();
var owner_id = $(this).attr("serial");
$(document).find("#comment-box"+serial).find(".comment-response").hide();
$(document).find("#comment-box"+serial).slideDown(250);
$(document).find("#comment-box"+serial).find(".comment-box-area").val("#"+owner+": ");
$(document).find("#comment-box"+serial).find(".comment-box-area").focus();
return false;
});
$(document).on("click",".comment-report", function(event){
var serial = $(this).attr("serial");
var tutorial_serial = $(this).parent().parent().parent().attr("id");
$("#overlay-box").load("overlay_boxes/report_comment.php", { php_serial: serial }, function(){
$("#overlay-box").fadeIn(250);
$("#overlay").fadeIn(250);
});
return false;
});
You apparently have a multitude of issues, some of which we can't help with because you haven't included the relevant code.
You have your javascript code that attaches the event handler sometimes? executing more than once.
You are attaching the event to an element that may not exist at run time (are you executing the event handler attaching code when you insert it?)
You are removing all event handlers indiscriminately, possibly events that aren't your own.
The second and third problems are easy. Don't use
$(".comment-remove").off().on("click", function(event){
use
$(document).on('click','.comment-remove',function(event){
I would also recommend not using the serial attribute, but use data-serial instead, and instead of var tutorial_serial = $(this).parent().parent().parent().attr("id"); use something like var tutorial_serial = $(this).closest('.tutorial').attr("id"); which is more maintainable.
Remove the href property on your anchor to prevent it from adding a # at the end of your url:
<a href="#" serial="'.$data_id.'" class="comment-remove" '.$hidden_remove.' >Remove</a>
And I would suggest using:
$("body").on("click",".comment-remove",function(){...})
To prevent the event firing more than once, since you are setting the listener on the body once, instead of on, which could or could not be assigned to your ID as desired, depending on wether the element exists in the DOM when that line is ran.
I have the following JavaScript to play a sound when a button is clicked on the screen, however I'm only getting NaN for the duration.
$(document).ready(function() {
function play_sound() {
var audio = new Audio("assets/sound.ogg");
audio.play();
var duration = audio.duration;
console.log(duration);
}
$(document).on("click", ".box", function(e) {
play_sound();
});
});
In my research I found this answer which uses the "loadeddata" event, however I'm not sure how to incorporate that into my code. Should I use an <audio> element in my HTML?
Here's my shot at it:
$(document).ready(function() {
function play_sound() {
var audio = new Audio("assets/sound.ogg");
audio.addEventListener("loadedmetadata", function(_event) {
var duration = audio.duration;
console.log(duration);
});
audio.play();
}
$(document).on("click", ".box", function(e) {
play_sound();
});
});
http://jsfiddle.net/x2pe6hcf/1/
Added the eventListener and it works perfectly.
I am trying to execute some code that has a callback when clicking on specific links. The callback is to click the link again, but on the second pass, the method returns true to follow normal behavior. But for some reason, it's not working? I use clickedLink for proper scope. In the event callback, this was referring to window.
UPDATE
For a little more clarity, I agree normally this wouldn't be an optimal solution, but I am using Google's Tag Manager to monitor eCommerce traffic. I am trying to make sure product clicks get pushed to their dataLayer, and using their event callback to resume normal behavior. More info here: https://developers.google.com/tag-manager/enhanced-ecommerce#product-clicks
This is my updated method based on the answers below, but it still doesn't work.
var shopCartBtnClicked = false;
var clickedLink;
jQuery('#pdp_add_cart, .add_to_cart_button').click(function(e) {
if (shopCartBtnClicked === true) {
shopCartBtnClicked = false; //I make it here just fine
} else {
e.preventDefault();
clickedLink = this;
var pdp = false;
if (mmProduct) {
//On detail page
mmProduct.qty = jQuery('input[name="quantity"]').val();
pdp = true;
} else {
//on a shopping page
mmProduct = findProductClicked(this);
mmProduct.qty = 1;
}
dataLayer.push({
'event': 'addToCart',
'ecommerce': {
'currencyCode': 'USD',
'add': {
'products': [{
'name': mmProduct.name,
'id': mmProduct.id,
'price': mmProduct.price,
'quantity': mmProduct.qty
}]
}
},
'eventCallback': function () {
//Are we on a product detail page with a form, or just a shopping page with a link?
if (pdp) {
jQuery('form.cart').submit(); //This part works just fine
} else {
mmProduct = null;
shopCartBtnClicked = true;
$(clickedLink).trigger('click'); //This doesn't
}
}
});
}
});
Its not very well done, but this should work:
var shopCartBtnClicked = false;
var clickedLink;
jQuery('.add_to_cart_button').click(function(e) {
if (shopCartBtnClicked === true) {
shopCartBtnClicked = false;
// dont return, just let javascript handle this one
} else {
// only execute when you have not set it to true
e.preventDefault();
clickedLink = this;
shopCartBtnClicked = true;
$(clickedLink).trigger('click');
}
});
I do have to wonder why you don't just execute your other logic first and then not prevent default anyway.
Taking #somethinghere's answer, your code can further be simplified to improve readability:
var shopCartBtnClicked = false;
jQuery('.add_to_cart_button').click(function(e) {
if( shopCartBtnClicked ) {
shopCartBtnClicked = false;
// dont return, just let javascript handle this one
} else {
// only execute when you have set it to true
e.preventDefault();
shopCartBtnClicked = true;
this.click();
}
});
Or, as suggested by #Regent:
var shopCartBtnClicked = false;
jQuery('.add_to_cart_button').click(function(e) {
shopCartBtnClicked = !shopCartBtnClicked;
if( shopCartBtnClicked ) {
e.preventDefault();
this.click();
}
});
OK guys, thank you for helping me get there. Normally, all of the other answers would work great, but for this specific tag manager instance, it appears (for some unknown reason), document.location works in the event callback fine here. This works.
It's weird because I used $(this).('form.cart').submit(); in a callback earlier in the code.
'eventCallback': function () {
//Are we on a product detail page with a form, or just a shopping page with a link?
if (pdp) {
jQuery('form.cart').submit();
} else {
mmProduct = null;
document.location = $(clickedLink).attr('href');
//$(clickedLink).trigger('click');
}
}
Based on this script I found on Stack Overflow, I tried adapting it to fade out an editor panel on a HTML page. Fading out works fine, but I'd like limit the fade-out from being triggered.
What I hope to accomplish is to prevent the fade-out whenever the mouse is over the editor panel (and child controls) or when there's keyboard activity in one of the input children.
var i = null;
// this part is working
$("#my-canvas").mousemove(function() {
clearTimeout(i);
$("#panel,#btn-panel-toggle,#fps").fadeIn(200);
var i = setTimeout('$("#panel,#btn-panel-toggle,#fps").fadeOut(800);', 3000);
})
// this part is not working
$("#panel").mouseover(function() {
clearTimeout(i);
})
For a live example, please check out this jsFiddle.
Two independent variables are needed here to indicate, whether the input#sc-url is focused and div#panel is hovered by mouse or not. Then you can handle the timer with these functions:
$(function () {
var t = null; //timer
var is_url_focused = false, is_panel_hovered = false;
var panel = $('#panel');
function hide_panel(){
if (t) {
clearTimeout(t);
}
t = setTimeout(function(){
if (is_url_focused || is_panel_hovered) {
return;
}
panel.stop().animate({
opacity:0
},800, function(){
panel.hide(); // == diplay:none
});
},2000);
}
function show_panel(){
panel.show().stop().animate({
opacity:1
},800);
}
$('#my-canvas').mouseenter(function(){
show_panel();
}).mouseleave(function(){
hide_panel();
});
$('#panel').hover(function(){
is_panel_hovered = true;
show_panel();
}, function(){
is_panel_hovered = false;
hide_panel();
});
$('#sc-url').focus(function(){
is_url_focused = true;
show_panel();
}).blur(function(){
is_url_focused = false;
hide_panel();
});
$('#btn-panel-toggle').click(function(){
if (panel.is(':hidden')) {
panel.css('opacity',1).show();
} else {
panel.css('opacity',0).hide();
}
});
});
http://jsfiddle.net/w9dv4/3/