Results 1 to 5 of 5

Thread: icon loses class attribute when swapped

  1. #1
    Join Date
    Aug 2010
    Posts
    86
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Default icon loses class attribute when swapped

    Beverly very kindly helped me create a js script that played a sound file from a list and changed the play/pause icon. This works perfectly and the thread can be seen here http://www.dynamicdrive.com/forums/s...ht=#post310353 .

    I have a small problem that I’ve been unable to fix. Some of the song titles are long and extend over two lines, when I click the play/pause icon the 2nd line of the title appears below the icon and not to the right of the icon. The effect can be seen here www.innocente.us/discography.php when you click on the play icon beside the song titles that extends over two lines the second line shows below the pause icon.

    I think the problem is that when the play icon is clicked it is replaced by the pause icon but the attribute class=”fltlft” is removed and I can’t figure out how to retain it – I tried adding it to the variables playicon and pauseicon and it didn’t work - it fixed the alignment problem but when I clicked the pause icon the sound did not pause. Here's what I tried:

    Code:
    var playIcon = '<img class=”fltlft” src="images/play.png">';
    		var pauseIcon = '<img class=”fltlft” src="images/pause.png">';
    Here’s a sample html (using debugger) showing the play icon before being clicked:
    Code:
    <a href="#">
    <img class="fltlft" src="images/play.png"/>
    And here’s the html (using debugger)after the play icon is clicked
    Code:
    <a href="#">
    <img src="images/pause.png"/>
    Notice that the class=”fltlft” is missing.

    Here’s the script that swaps the play/ pause icon - without my changes above.
    Code:
    <script>
    var ctrl = document.getElementById('audio').getElementsByTagName('a');
    for(var i = 0; i < ctrl.length; i++){
             ctrl[i].onclick = function(){
    		var audio = this.nextSibling;
    		while (audio.nodeType != 1){ audio = audio.nextSibling; }
    		var playIcon = '<img src="images/play.png">';
    		var pauseIcon = '<img  src="images/pause.png">';
    		var pause = this.innerHTML === pauseIcon;
    		this.innerHTML = pause ? playIcon : pauseIcon;
    		var method = pause ? 'pause' : 'play';
    		audio[method]();
    		return false;
                 }
         }
    </script>
    Thanks for any assistance you can provide.
    Tony

  2. #2
    Join Date
    Jul 2008
    Location
    Derbyshire, UK
    Posts
    3,033
    Thanks
    25
    Thanked 599 Times in 575 Posts
    Blog Entries
    40

    Default

    I revised the code in my demo a while back after I noticed that the play/pause toggle lost functionality with img tags. This version uses a <button> element with the image set as a background-image instead. The addition of the "pause" class changes the background-image.

    CSS;
    Code:
    #audio button { height:64px; width:64px; margin:0.5em; vertical-align:middle; background:url(play.png) 50% no-repeat; border:0; cursor:pointer }
    #audio button.pause { background-image:url(pause.png) }
    HTML / JS;
    Code:
    <div id="audio">
    
    <button class="fltlft" title="Play / Pause"></button> Song 1 - Takin' It All
    <audio preload="none">
        <source src="takin_it_all.mp3" type="audio/mpeg" />
    </audio><br/>
    
    <button class="fltlft" title="Play / Pause"></button> Song 2 - Too Close
    <audio preload="none">
        <source src="too_close.mp3" type="audio/mpeg" />
    </audio><br/>
    
    <button class="fltlft" title="Play / Pause"></button> Song 3 - Gettin' Down To Business
    <audio preload="none">
        <source src="gettin_down_to_business.mp3" type="audio/mpeg" />
    </audio><br/>
    
    </div>
    
    
    <script>
    var ctrl = document.getElementById('audio').getElementsByTagName('button');
    for(var i = 0; i < ctrl.length; i++){
    	ctrl[i].addEventListener('click', function(){
    		var audio = this.nextSibling;
    		while (audio.nodeType != 1){ audio = audio.nextSibling; }
    		var pause = this.className === 'pause fltlft';
    		this.className = pause ? 'fltlft' : 'pause fltlft';
    		var method = pause ? 'pause' : 'play';
    		audio[method]();
    		audio.addEventListener('ended', function(){
    			this.previousElementSibling.className = 'fltlft';
    			}, false);
    		}, false);
    	}
    </script>
    Focus on Function Web Design
    Fast Edit (A flat file, PHP web page editor & CMS. Small, FREE, no database!) | Fast Edit BE (Snippet Manager) (Web content editor for multiple editable regions!) | Fast Apps

  3. #3
    Join Date
    Aug 2010
    Posts
    86
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Default

    Hi Beverley,
    Thank you for the reply replacing the img with a button. I tried the code you provided and it worked fine. When I added some of the additional formatting I'm using it stopped working - no sound was played. The first thing I added was just a <br /> in the song title and it failed. The original problem I was trying to solve was when a song with a long title played one line displayed alongside and the other below the play icon. You can see this original behaviour here www.innocente.us/discography.php when you click Play beside a long title.

    So, I set up a test page using the buttons and with fewer songs than the original page and included all the various formatting I'm using. The test page can be seen here www.innocente.us/beverley.php . I'm afraid my js skills just aren't up to figuring out what the problem is....sigh.

    Here is a sample of a song with a long title - i.e. it extends over two lines.
    Code:
    <button class="fltlft" title="Play / Pause"></button> <span class="songTitle" title="">When The Stone<br />Was Rolled Away</span>
    <audio preload="none">
        <source src="music/Stone.mp3" type="audio/mpeg" />
    </audio>
    <div class="clearfloat"></div>
    When I tried debugger it said it couldn't apply a method "Play" to an <Audio> object.

    If you could point me in the right direction I'd really appreciate it.

    Thanks,

    Tony

  4. #4
    Join Date
    Jul 2008
    Location
    Derbyshire, UK
    Posts
    3,033
    Thanks
    25
    Thanked 599 Times in 575 Posts
    Blog Entries
    40

    Default

    It comes down to these lines in the script - specifically the part in red;
    Code:
    		var audio = this.nextSibling;
    		while (audio.nodeType != 1){ audio = audio.nextSibling; }
    "this" is the button element, and "nextSibling" is the audio element - matching the original markup structure where <audio> is the next element after <button>.

    Now, with you adding another element between <button> and <audio>, the audio element is no longer nextSibling of the button element, so the original script breaks. But you can adapt it to account for the extra nextSibling (the <span>) - replace the two lines above with these;
    Code:
    		var span = this.nextSibling;
    		while (span.nodeType != 1){ span = span.nextSibling; }
    		var audio = span.nextSibling;
    		while (audio.nodeType != 1){ audio = audio.nextSibling; }
    It also means that this line won't work either;
    Code:
    			this.previousElementSibling.className = 'fltlft';
    There's another previousElementSibling to account for, so change the line to this;
    Code:
    			this.previousElementSibling.previousElementSibling.className = 'fltlft';
    This makes the script work with your markup, providing that all your musical notes and song titles maintain this format;
    Code:
    <button class="fltlft" title="Play / Pause"></button> <span class="songTitle" title="">When The Stone<br />Was Rolled Away</span>
    <audio preload="none">
        <source src="music/Stone.mp3" type="audio/mpeg" />
    </audio>
    The <br/> won't affect the script as its contained within the span.
    Focus on Function Web Design
    Fast Edit (A flat file, PHP web page editor & CMS. Small, FREE, no database!) | Fast Edit BE (Snippet Manager) (Web content editor for multiple editable regions!) | Fast Apps

  5. #5
    Join Date
    Jul 2008
    Location
    Derbyshire, UK
    Posts
    3,033
    Thanks
    25
    Thanked 599 Times in 575 Posts
    Blog Entries
    40

    Default

    Scratch
    Code:
    		var audio = this.nextSibling;
    		while (audio.nodeType != 1){ audio = audio.nextSibling; }
    and
    Code:
    		var span = this.nextSibling;
    		while (span.nodeType != 1){ span = span.nextSibling; }
    		var audio = span.nextSibling;
    		while (audio.nodeType != 1){ audio = audio.nextSibling; }
    nextSibling is to account for older browsers - taken from a script that supports IE7/8 - but since this is an audio script that only needs to support modern browsers and IE9 and above due to native compatibility with the <audio> element, we can use nextElementSibling instead;
    Code:
    		var audio = this.nextElementSibling.nextElementSibling;
    Focus on Function Web Design
    Fast Edit (A flat file, PHP web page editor & CMS. Small, FREE, no database!) | Fast Edit BE (Snippet Manager) (Web content editor for multiple editable regions!) | Fast Apps

Similar Threads

  1. Replies: 1
    Last Post: 03-03-2014, 08:36 AM
  2. Resolved session in iFrame loses session data
    By crobinson42 in forum PHP
    Replies: 4
    Last Post: 02-29-2012, 12:59 AM
  3. JquerySlideMenu DropDown loses visibility in IE
    By islandice1 in forum Dynamic Drive scripts help
    Replies: 2
    Last Post: 02-23-2010, 03:21 PM
  4. Replies: 2
    Last Post: 10-09-2009, 04:19 PM
  5. Nesting DIV loses format with Axjaxtabs
    By techfella in forum Dynamic Drive scripts help
    Replies: 3
    Last Post: 03-25-2007, 02:53 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •