0

I have an autofade button attached to each instance of my audio tracks:

<input type="button" id="autofadebtn<?php echo $track;?>"  value="Fade Out"

onclick="$(document).ready(function()

{
    $('#<?php echo $track;?>')[0].volume = .5;
    $('#<?php echo $track;?>').animate({volume: 0}, 30000); 
  });

  $('#<?php echo $track;?>').promise().done(function() { 
  $('#<?php echo $track;?>').trigger('pause');
});
    "
    >

I also have a volume slider:

var audio<?php echo $track;?> = document.getElementById("<?php echo $track;?>");
var slider<?php echo $track;?> = document.getElementById("slider<?php echo $track;?>");
var display<?php echo $track;?> = document.getElementById("display<?php echo $track;?>");


slider<?php echo $track;?>.addEventListener("input", sliderActions);

function sliderActions( )
{
  var newVolume = slider<?php echo $track;?>.value;

  display<?php echo $track;?>.innerText = newVolume; // range 0 to 100
  audio<?php echo $track;?>.volume = newVolume / 100; // range 0 to 1 
}

My issue is that I would like my autofade button to start at the volume the user moves the volume slider to. Currently the auto fade starts at .5. I can't work out which variable to use from the volume slider. The autofade button is within the input tag whilst the volume slider script is at the bottom of the page.

I've tried replacing the volume = .5 in the autofade with the named variables from the volume slider but each time the autofade stops working.

5
  • 6
    onclick="$(document).ready(function() ... - that is one of the worst constructs I have ever seen, when it comes to event handling. Surprised it does anything at all, considering it appears to try and set a ready handler for the document, when the element gets clicked (by which time ready will probably already have passed.) Commented Apr 1 at 10:02
  • "Currently the auto fade starts at .5" - because you are explicitly setting that value. But did you not already do that, in your sliderActions? I'm assuming audio<?php echo $track;?> in there, and $('#<?php echo $track;?>') in your click handler, are effectively the same element? So why do you need to set it again in your click handler, can't just just "animate" from the current volume? Commented Apr 1 at 10:05
  • <?php echo $track;?> in varname and and getElementById looks like you have several of these on the page. If you delegate you do not need this code at all. Commented Apr 1 at 10:21
  • 2
    @C3roe just FYI: doc.ready will fire immediately if the doc is already ready. Unlike the JS domcontentloaded. It is, of course, pointless (unless maybe the page is sooo large that the button is displayed while the rest of the page is still loading?) Commented Apr 1 at 11:38
  • I used to love jQuery because of how simple it made many tasks to code. Now, I hate (most) uses of jQuery because people use it instead of doing simple coding in vanilla JavaScript and therefore making the overall code more complex and excessive. Commented Apr 1 at 12:19

1 Answer 1

1

<?php echo $track;?> in varname and and getElementById looks like you have several of these on the page. If you delegate you do not need this code at all.

jQUery makes delegation easy, although plain vanilla JS can do it too

  1. php
<?php foreach ($tracks as $track) { ?>

<div class="track-container">
    <audio class="track-audio" src="<?= $track ?>"></audio>
    <input type="range" class="volume-slider" min="0" max="100" value="50">
    <span class="volume-display">50</span>
    <input type="button" class="autofade-btn" value="Fade Out">
</div>
<? } ?>
  1. JS using delegation - note you need to change prev/prevAll to next/nextAll depending on where the button is relative to the audio and slider. Post your HTML if you need help with that

$(document).ready(function() {
  // Delegate slider input events
  $(document).on('input', '.volume-slider', function() {
    const $slider = $(this);
    const $audio = $slider.prev('.track-audio'); // Audio is before slider
    const $display = $slider.next('.volume-display'); // Display is after slider
    const newVolume = $slider.val();
    $display.text(newVolume); // Update display (0-100)
    $audio[0].volume = newVolume / 100; // Update audio volume (0-1) note we use the [0] DOM property
  });

  // Delegate autofade button clicks
  $(document).on('click', '.autofade-btn', function() {
    const $button = $(this);
    const $audio = $button.prevAll('.track-audio').first(); // Audio is before button

    // Fade from current volume to 0 over 30 seconds
    $audio.animate({
      volume: 0
    }, 30000).promise().done(function() {
      $audio.trigger('pause');
    });
  });
});

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.