Apologies for such a vage title, but I seriously don't know where the two issues I have are related to. My JavaScript/jQuery skill is on a noob level, so bare with me please :)

I'm working on a AJAX/HTML5 History website which is a pet project of mine. It will be a music site where I use the mixcloud player as a widget (unfortunately) and a custom Soundcloud player which runs on the Soundcloud API.

The page is here: http://gentle.media/mixture/news
You can login with:
username: dani
password: web

On the 'News' page, that you should see now, I have 5 soundcloud items and clicking on 'play track' or 'play set' will change the default mixcloud player at the bottom to a soundcloud player and it starts playing (if autoplay is supported by the browser/device). Clicking on another track/set will change again and starts playing that track/set. So far so good! But.. if a user clicks on an 'info' link to open the artist info and closing it again by clicking on the little cross, I lost control over the player. I can't pause/stop the song anymore untill I click on a 'play track' link again.

The second issue is also on the 'News' page. The artist info is hidden inline (display: none) and by clicking on a 'info' link I create dynamically a list-item (.clone-container) at the end where I load a cloned version of the artist info content. This works fine, but only twice. If user clicks (after closing the artist info with the little cross) again on a 'info' link it opens the artist info, but now the user can't close it anymore.

The following jQuery function does all the magic for the news page. I have to say if I don't empty .clone-container before detaching it, I don't have the second issue, but then I have all the previous artist info still in that div.

(function($) {

    function _news() {

        var cc = $('<li class="clone-container"></li>'),
            sd = $('.show-details'),
            cd = $('<button class="close-details"><i class="icon-close"></i></button>')

        $('.sc').click(function(e) {

            e.preventDefault();

            var $href = $(this).attr('href');
            $('#main-player').load($href);

            var $title = $(this).parent().siblings('h2').find('span').text()
            $('#main-player').attr("title", $title).hover(function() {
                $(this).attr("title","");
            });

        });

        $(sd).click(function(e) {

            e.preventDefault();

            $(this).closest('li').addClass('active').siblings().removeClass('active').addClass('hide');
            $(this).hide();
            $(cc).appendTo('.news-grid').addClass('show');
            $(cd).appendTo(cc);
            $(this).parent().prev('.artist-info').children().clone().appendTo(cc)

        });

        $(cd).click(function(e) {

            $('li.active').removeClass('active').siblings().removeClass('hide');
            $(cc).empty().detach();
            $(sd).show();

        });

    }_news()

})(jQuery);

Thanks for your time guys!

EDIT: I have to say I've tested my progress so far only in Chrome, Firefox and Safari on the Mac, so i really don't know (yet) if it looks and works okay in Windows (IE and etc.).

Recommended Answers

All 19 Replies

Here is my guess (I am not coding in JQuery). When the function is called, the closing button object is created the first time. Then it is properly added to the clone container. Once a user closes the container, the object is still there, but the click() function has been removed from the object. When you attempt to open another info, the display is correct, but the functionality of the click() for the closing button is now gone. Check the line $(cc).empty().detach(); again. May try to empty (and add if not already exists) only the info content rather than the whole content inside the container.

Thanks for your reply, Taywin! I will try that too. It is the .empty() that is conflicting somehow.

@Taywin, pointed me in the right direction, so I have resolved issue 2. I remove the siblings of the closing button (object) before detaching the clone-container.

        $cd.click(function(e) {

            $('li.active').removeClass('active').siblings().removeClass('hide');
            $(this).siblings().remove();
            $cc.detach();
            $sd.show();

        });

Now is only left the first issue (not pausing souncloud player after opening and closing artist info).

I got this error below...

TypeError: $.browser is undefined
if ($.browser.msie) {  // line 174 of sc-player.js

Yeah, I saw that in the console, but I believe it's not related to the issue. It is the Flash fallback for IE. It's browsersniffing with jQuery which is deprecated, so therefore the error I guess.

Then you should remove the part because Javascript will stop running after it found an error in the script.

Seriously? But that bit is somewhere in the beginning of sc-player.js and all the lines of code after that seems to run just fine (except for my issue then :) )

Surely cc can be permanently appended to .news-grid and cd can be permanently appended to cc with .show() and .hide() controlling visibility? There doesn't appear to be any need to detach/reappend. Even better, cc/cd could be hard coded in HTML.

I'm not sure this will fix anything but should better guarantee that the behaviour is consistent and debugging should be simpler.

Thanks for looking at this, @Airshow! I could indeed hard code cc, it's just that I'm not such a fan of hard coded empty tags in the markup, but I will follow your suggestions and see if this will make a difference. Thanks!

I have hard coded li.clone-container and button.close-details, but the issue of not stopping/pausing the soundcloud player still persist once I've closed .clone-container.

I have a (temporarely) fix for the second issue. After closing the artist info and I click on the 'play track' or 'play set' link of the song/set that is playing, I have control again over the pause/play button, so I do this step now dynamically with jQuery, but if there's a better solution or if someone can track down the cause of the issue, I'm all ears. I commented my 'fix' out in scripts.news.js for now and I'll leave the thread open for a bit. Thanks!

Well... unfortunately that fix works only if a track is playing and not when a set is playing half way. The set starts playing again with the first track (obviously). Bummer!

When I said 'remove it', it could simply be commenting the whole block out. The reason is that the whole block of code will never be executed anyway. The block of code starts from the line with if and all the way from its scope { ... }. Shouldn't hurt anything afterward. ;)

Thanks Taywin! I did some googeling this afternoon about that ($.browser.msie) and found a thread on Stackoverflow stating it is not compatible with jQuery 1.9.0. (which I load) and suggesting to replace that bit with (navigator.userAgent.match(/msie [6]/i)) which I did and it doesn't throw in an error like this, but it didn't solve the issue either :(

So... I'm still looking for a good fix!

Hmm... I have no idea :( Also, the part that stop working is inside an iframe too... May have to keep poking for a while...

The mixcloud player is in an iframe, but the soundcloud player not. The soundcloud player data (audio, track info, artwork, etc.) comes from the track URL with json. I switch the content (the players) of section#main-player with jQuery .load(). The code of the players (mixcloud iframe and soundcloud URL) are in a HTML snippet that gets loaded into section#main-player. This al works as intended and I can navigate to other pages of the site and audio keeps on playing. Coming back to the 'news' page I still have control over the play/pause button of the soundcloud player, but once I open/close artist info it start to become a mistery :)

Gentlemedia, it's not obvious what is causing this issue. You need to devise an investigation strategy to discover what's causing it. Simplify everything one aspect at a time and see when the problem disappears.

You're right, Airshow! I followed your advice and I got it solved, but I feel kind of stupid now :)

I add/remove a class 'active' on a 'li' so that I had a hook to trigger the CSS animations/transitions for the news items, but this classname is also used for the active song (the song that is playing) in the soundcloudplayers' playlist which is an unordered list with a li.active too.

So I had to be more specific with my selector when removing the 'active' class, so now I have it like this:

$('.news-grid').find('li.active').removeClass()

... and problem is solved! Both Airshow and Taywin thank you for your time and help. Much appreciated!

Gentlemedia, coooooool! Now Taywin and I can start breathing again ;-)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.