Search code examples
javascriptjqueryjquery-slider

Custom JQuery css background slider issue with navigation


I've wrote a simple background slider that uses css background image as slide and it can be viewed here: http://jsfiddle.net/yfRUs/

$(".project h2").click(function() {
    if ($(this).parent().hasClass('opened')) {
        $(".projectbgs").remove();
        var projectid = $(this).parent().data("projectid");
        var titlewidth = $(this).width();
        var titleholderwidth = $(this).parent().width();
        var titleposition = titleholderwidth - titlewidth;
        $(this).css({left: 0});
        $(this).animate({'margin-right': 0}, 300);
        $('.project h2').css({'margin-left': 'auto', 'font-size': '', 'color': ''});
        $(".project").removeClass("opened");
    }
    else {
        $('.project h2').css({'margin-left': 'auto', 'font-size': '', 'color': ''});
        $(".project").removeClass("opened");
        $(".projectbgs").remove();
        var projectid = $(this).parent().data("projectid");
        $(this).parent().addClass('opened', 500);
        var titlewidth = $(this).width();
        var titleholderwidth = $(this).parent().width();
        var titleposition = titleholderwidth - titlewidth;
        $(this).css({left: titleposition});
        $(this).animate({'margin-left': 0}, 300);

        if (projectid === 1) {
            $('body').append($('<div id="projectbg-' + projectid + '" class="projectbgs">   <ul class="bgimages">    <li class="image" style="background-image: url(\'http://upload.wikimedia.org/wikipedia/commons/thumb/9/97/The_Earth_seen_from_Apollo_17.jpg/270px-The_Earth_seen_from_Apollo_17.jpg\');"> </li>     <li class="image" style="background-image: url(\'http://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/FullMoon2010.jpg/280px-FullMoon2010.jpg\');"> </li>  </ul> </div>'));
        }
        else if (projectid === 2) {
            $('body').append($('<div id="projectbg-' + projectid + '" class="projectbgs">   <ul class="bgimages">    <li class="image" style="background-image: url(\'http://www.mallorcaweb.net/masm/Planetas/Jupiter.jpg\');"> </li>   <li class="image" style="background-image: url(\'http://upload.wikimedia.org/wikipedia/commons/thumb/0/06/Neptune.jpg/240px-Neptune.jpg\');"> </li>    </ul> </div>'));
        }
        var viewportwidth = $(window).width();
        $('#projectbg-' + projectid + ' ul li').each(function(index) {
            $(this).css({width: viewportwidth});
        });
        $(window).resize(function() {
            $('#projectbg-' + projectid + ' ul li').each(function(index) {
                $(this).css({width: viewportwidth});
            })
        });
        var triggers = $('#project-' + projectid + ' ul.triggers li');
        var images = $('ul.bgimages li');
        var lastElem = triggers.length - 1;
        var mask = $('.projectbgs ul.bgimages');
        var imgWidth = images.width();
        var target;
        triggers.first().addClass('active');
        mask.css('width', imgWidth * (lastElem + 1) + 'px');
        function sliderResponse(target) {
            mask.stop(true, false).animate({'left': '-' + imgWidth * target + 'px'}, 1000);
            triggers.removeClass('active').eq(target).addClass('active');
        }
        triggers.click(function() {
            if (!$(this).hasClass('active')) {
                target = $(this).index();
                sliderResponse(target);
                resetTiming();
            }
        });
        function sliderTiming() {
            target = $('ul.triggers li.active').index();
            target === lastElem ? target = 0 : target = target + 1;
            sliderResponse(target);
        }
        var timingRun = setInterval(function() {
            sliderTiming();
        }, 7000);
        function resetTiming() {
            clearInterval(timingRun);
            timingRun = setInterval(function() {
                sliderTiming();
            }, 7000);
        }
    }
});

To see the "unknown issue" open first PROJECT (click on title) on the right and click those 2 small boxes that represent slides (you may need to scroll jsfiddle window as this is built for 1024+ resolutions).

Then open project 2 and also scroll through slides, and now go back to project 1 and try to scroll - it won't work !? I am really puzzled with this as NO ERROR is thrown ?

Anybody has any idea what's wrong ?


Solution

  • The problem is that the click events are not properly unbound and the interval is not stopped on transition from one project to another. To do this, you need to define the triggers and timingRun outside of the event handler, and reset them each time you enter the handler:

    if(triggers){
        triggers.off('click');
        triggers = null;
    }
    if(timingRun){
        clearInterval(timingRun);
        timingRun = null;
    }
    

    The complete piece of code will look like:

    var triggers,
    timingRun;
    
    $(".project h2").click(function() {
        if(triggers){
            triggers.off('click');
            triggers = null;
        }
        if(timingRun){
            clearInterval(timingRun);
            timingRun = null;
        }
        if ($(this).parent().hasClass('opened')) {
            $(".projectbgs").remove();
            var projectid = $(this).parent().data("projectid");
            var titlewidth = $(this).width();
            var titleholderwidth = $(this).parent().width();
            var titleposition = titleholderwidth - titlewidth;
            $(this).css({left: 0});
            $(this).animate({'margin-right': 0}, 300);
            $('.project h2').css({'margin-left': 'auto', 'font-size': '', 'color': ''});
            $(".project").removeClass("opened");
        }
        else {
            $('.project h2').css({'margin-left': 'auto', 'font-size': '', 'color': ''});
            $(".project").removeClass("opened");
            $(".projectbgs").remove();
            var projectid = $(this).parent().data("projectid");
            $(this).parent().addClass('opened', 500);
            var titlewidth = $(this).width();
            var titleholderwidth = $(this).parent().width();
            var titleposition = titleholderwidth - titlewidth;
            $(this).css({left: titleposition});
            $(this).animate({'margin-left': 0}, 300);
    
            if (projectid === 1) {
                $('body').append($('<div id="projectbg-' + projectid + '" class="projectbgs">   <ul class="bgimages">    <li class="image" style="background-image: url(\'http://upload.wikimedia.org/wikipedia/commons/thumb/9/97/The_Earth_seen_from_Apollo_17.jpg/270px-The_Earth_seen_from_Apollo_17.jpg\');"> </li>     <li class="image" style="background-image: url(\'http://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/FullMoon2010.jpg/280px-FullMoon2010.jpg\');"> </li>  </ul> </div>'));
            }
            else if (projectid === 2) {
                $('body').append($('<div id="projectbg-' + projectid + '" class="projectbgs">   <ul class="bgimages">    <li class="image" style="background-image: url(\'http://www.mallorcaweb.net/masm/Planetas/Jupiter.jpg\');"> </li>   <li class="image" style="background-image: url(\'http://upload.wikimedia.org/wikipedia/commons/thumb/0/06/Neptune.jpg/240px-Neptune.jpg\');"> </li>    </ul> </div>'));
            }
            var viewportwidth = $(window).width();
            $('#projectbg-' + projectid + ' ul li').each(function(index) {
                $(this).css({width: viewportwidth});
            });
            $(window).resize(function() {
                $('#projectbg-' + projectid + ' ul li').each(function(index) {
                    $(this).css({width: viewportwidth});
                })
            });
            triggers = $('#project-' + projectid + ' ul.triggers li');
            var images = $('ul.bgimages li');
            var lastElem = triggers.length - 1;
            var mask = $('.projectbgs ul.bgimages');
            var imgWidth = images.width();
            var target;
            triggers.first().addClass('active');
            mask.css('width', imgWidth * (lastElem + 1) + 'px');
            function sliderResponse(target) {
                mask.stop(true, false).animate({'left': '-' + imgWidth * target + 'px'}, 1000);
                triggers.removeClass('active').eq(target).addClass('active');
            }
            triggers.click(function() {
                if (!$(this).hasClass('active')) {
                    target = $(this).index();
                    sliderResponse(target);
                    resetTiming();
                }
            });
            function sliderTiming() {
                target = $('ul.triggers li.active').index();
                target === lastElem ? target = 0 : target = target + 1;
                sliderResponse(target);
            }
            timingRun = setInterval(function() {
                sliderTiming();
            }, 7000);
            function resetTiming() {
                clearInterval(timingRun);
                timingRun = setInterval(function() {
                    sliderTiming();
                }, 7000);
            }
        }
    });