Update links when audio plays


by Jeremy Caudle
code

While listening to today’s episode of the Shop Talk Show, 457: CSS Colors Fun, HSL, Updates from Browser Land, Pseudo Selectors, and Responsive Design Questions, Dave and Chris discussed the experience of clicking on links that take you off of a page that has audio playing. I thought I’d give updating links when audio is playing and removing the target="_blank" when the audio is paused. I really like this idea and I think I’ll put it to use whenever I get more audio on this site. I’ll be sure to make it look much nicer.

This is a test of the HTML audio element.

View the code:

HTML and JS
<section class="code-block">
            <audio id="audioPlayer" src="../ast/testaudio.mp3">
            </audio>
            <div>
                <button id="btnPlayPause" data-playing="false" role="switch" aria-checked="false">Play</button>
                <button id="btnVolumeUp" onclick=""><span>Volume Up</span></button>
                <button id="btnVolumeDown" onclick=""><span>Volume Down</span></button>
            </div>
						<p>This is a <a href="https://jeremycaudle.com" class="link">test</a> of the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio" class="link">HTML audio element</a>.</p>
        </section>
        <script>
            // Create an instance of the audio context.
            // First is for legacy browsers
            const AudioContext = window.AudioContext || window.webkitAudioContext;
            const audioContext = new AudioContext();
            // Variable for audio element
            const audioElement = document.querySelector('#audioPlayer');
            // Pass audio into audio context
            const track = audioContext.createMediaElementSource(audioElement);
            // Connect audio source to destination
            track.connect(audioContext.destination);
            // Variable for play/pause button
            const playPause = document.querySelector('#btnPlayPause');
            // Code for Play/Pause button click and ended event
            playPause.addEventListener('click', function () {

                // Check to see if context is in a suspended state
                if (audioContext.state === 'suspended') {
                    audioContext.resume();
                }

                // Change to Play or Pause depending on the state
                if (this.dataset.playing === 'false') {

                    // Grab all links that contain the class 'link' to convert them into external links. 
                    audioElement.play();
                    this.textContent = 'Pause'
                    this.dataset.playing = 'true';
                    let linkArray = document.querySelectorAll('.link');
                    console.log(linkArray);
                    for(let i = 0; i < linkArray.length; i++) {
                        linkArray[i].setAttribute('class', 'external-link');
                        linkArray[i].setAttribute('target', '_blank');
                    };
                } else if (this.dataset.playing === 'true') {
                    audioElement.pause();
                    this.textContent = 'Play';
                    this.dataset.playing = 'false';
                    let linkArray = document.querySelectorAll('.external-link');
                    console.log(linkArray);
                    for(let i = 0; i < linkArray.length; i++) {
                        linkArray[i].setAttribute('class', 'link');
                        linkArray[i].removeAttribute('target');
                    };
                }
                
            }, false);
            // Check to see if the audio has ended
            audioElement.addEventListener('ended', () => {
                console.log('Audio finished.');
								let linkArray = document.querySelectorAll('.external-link');
                    console.log(linkArray);
                    for(let i = 0; i < linkArray.length; i++) {
                        linkArray[i].setAttribute('class', 'link');
                        linkArray[i].removeAttribute('target');
                    };
                playPause.dataset.playing = 'false';
                console.log(playPause.dataset.playing);
                playPause.textContent = 'Play';
                console.log(playPause.textContent);
                audioElement.style.backgroundColor = 'red';
            }, false);


            // Variables for volume up and down buttons
            const volumeUp = document.querySelector('#btnVolumeUp');
            const volumeDown = document.querySelector('#btnVolumeDown');
            volumeUp.addEventListener('click', function () {
                if (audioElement.volume < 1) {
                audioElement.volume += .01;
                }
            }, false);
            volumeDown.addEventListener('click', function () {
                if (audioElement.volume > 0.1) {
                audioElement.volume -= .1;
            }
            }, false);

        </script>
CSS
.code-block { 
                width: clamp(16em, 90vw, 60em);
                font-family: Verdana, Geneva, Tahoma, sans-serif;
                z-index: 1;
                padding: 1rem;
                margin: 1rem auto;
                text-align: center;
            }

            audio {
                border-radius: 1rem;
                margin: 1rem;
            }

            .external-link {
                color: slateblue;
            }

            .external-link:after {
                content: "(opens in new tab/window)";
                display: inline;
            }