2

I have built a site for a client and when the user clicks on a navigation link, the content of the linked page is dynamically loaded and transitioned in with JQuery, instead of loading the new page.

The problem I am having is that because it is not loading a new page, $(document).ready doesn't fire again and any JS on the individual pages gets broken. For example, if you visit http://www.woodlandexotica.com/species.php the page works correctly, but if you try to navigate to the page from http://www.woodlandexotica.com/index_dev.php, the JS won't work.

I'm not an expert in JS and I really appreciate any and all help!

RGilkes
  • 1,012
  • 3
  • 12
  • 22
  • what exactly is not working? looks fine and sleek. I mean: the 'species' page loads in and is displayed. You should not have JS in that page, only content, and all JS in your main php page, and you would not have any problem. – Stefano May 23 '11 at 16:03
  • You have not posted the code for loading the new page. One thing to note about your page(s) so far however is that you seem to be re-using "id" values. That's a really bad idea; each "id" must be **unique** on the whole page. – Pointy May 23 '11 at 16:04
  • @user its fine for me , you should bind all live clicks or mouseovers only in document.ready , all other logic should be outside of documentready , so that they will be global and won't create any scope problem – kobe May 23 '11 at 16:05
  • For example, if you visit http://www.woodlandexotica.com/species.php you'll see that the different species are hidden and only show when you click on the name, but if you go to http://www.woodlandexotica.com/index_dev.php and navigate the species page, the JS that hides the non-active DIVs doesn't work. – RGilkes May 23 '11 at 16:05
  • @kobe anything that references a DOM element at load-time (i.e. as the script is loaded/executed, it references a DOM element) needs to be inside document.ready. – Matt May 23 '11 at 16:08
  • @Matt , i am only asking to keep global methods outside the document.ready.. – kobe May 23 '11 at 16:09
  • @Matt that's not necessarily true - the script just has to run *after* the DOM elements in question. – Pointy May 23 '11 at 16:09
  • @RGilkes where is the code that loads the pages? – Pointy May 23 '11 at 16:10
  • @Pointy Under "Page Transition" here: http://woodlandexotica.com/js/background.js – RGilkes May 23 '11 at 16:12
  • OK @RGilkes, see my answer below. You're running into an oddity with the way jQuery ".load()" works, and specifically when you use the feature that allows a selector to be appended to the URL string. – Pointy May 23 '11 at 16:28

2 Answers2

1

The problem is that when you call ".load()", you're using a URL string and a selector suffix to extract from the loaded content. When you use ".load()" that way, jQuery strips out all the scripts and does not run them. There's nothing you can do about that other than to implement your own version of ".load()" yourself, or (better) have the other pages you load not be complete HTML pages. If you use ".load()" without the selector suffix on the URL string, then jQuery does run the scripts.

See jQuery bug 6307 for more. The bug will not be fixed but hopefully the documentation will be improved.

Pointy
  • 405,095
  • 59
  • 585
  • 614
0

The way you organized this code is wrong

Keep only binding's inside document.ready and move the logic outside to a functions..which can be accessed by any page.

$(document).ready(function() {


    //////////////////////////////////////////////////
    //////////////////////////////////////////////////

    // CONTENT BG SLIDESHOW

    //////////////////////////////////////////////////
    var photos = ["images/bg01.jpg", "images/bg02.jpg", "images/bg03.jpg"];

    var slideshowSpeed = 8000;

    var interval;   
    var activeContainer = 1;    
    var currentImg = 0;
    var navigate = function(direction) {
        currentImg++;
        if(currentImg == photos.length + 1) {
            currentImg = 1;
        }

        // Check which container we need to use
        var currentContainer = activeContainer;
        if(activeContainer == 1) {
            activeContainer = 2;
        } else {
            activeContainer = 1;
        }

        showImage(photos[currentImg - 1], currentContainer, activeContainer);       
    };

    var currentZindex = 1;
    var showImage = function(photoObject, currentContainer, activeContainer) {
        // Make sure the new container is always on the background
        currentZindex--;

        // Set the background image of the new active container
        $("#bgimg" + activeContainer).css({
            "background-image" : "url(" + photoObject + ")",
            "display" : "block",
            "z-index" : currentZindex
        });

        // Fade out the current container
        // and display the header text when animation is complete
        $("#bgimg" + currentContainer).fadeOut(function() {
            setTimeout(function() {
                animating = false;
            }, 500);
        });
        $("#bgimg" + currentContainer).css({
            "z-index" : "1"
        });
        currentZindex = 1;
    };

    function photoLoaded() {
        if(!--numPhotosLeft) {
            navigate("next");

            interval = setInterval(function() {
                navigate("next");
            }, slideshowSpeed);

            $('#bg_load').fadeOut('fast');
            $('#page_bg').animate({opacity: 1, marginLeft: '-=860'}, 500);
        }
    }

    var photos = ["images/bg01.jpg", "images/bg02.jpg", "images/bg03.jpg"];
    var numPhotosLeft = photos.length;

    for(var i = 0; i < photos.length; ++i) {
        var img = new Image();
        img.onload = photoLoaded;
        img.src = photos[i];
    }
    //////////////////////////////////////////////////
    //////////////////////////////////////////////////




    //////////////////////////////////////////////////
    //////////////////////////////////////////////////

    // PAGE TRANSITION

    //////////////////////////////////////////////////


    // ADJUST FOR DEEPLINKING
    var hash = window.location.hash.substr(1);
    var href = $('a.link').each(function(){
        var href = $(this).attr('href');
        if(hash==href.substr(0,href.length-4)){
            var toLoad = hash+'.php #page_bg';
            $('#page_bg').load(toLoad)
        }                                           
    });

    $('a.link').click(function() {

        var toLoad = $(this).attr('href')+' #page_bg';
        $('#page_bg').animate({opacity: 0.25, marginLeft: '-=875'}, 500, loadContent);

        window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-4); //MODIFY FOR DEEP LINKING

        function loadContent() {
            $('#page_wrap').prepend('<span id="load">LOADING...</span>');
            $('#load').fadeIn('fast');

            $('#page_bg').css('marginLeft', 860);
            $('#page_bg').css('backgroundImage', 'none');
            $('#page_bg').load(toLoad,'',hideLoader);
        }
        function hideLoader() {
            $('#load').fadeOut('fast', showNewContent);
        }
        function showNewContent() {         
            $('#page_bg').animate({opacity: 1, marginLeft: '-=860'}, 500);
        }

        return false;
    });

    //set initial position and opacity
    $('#page_bg').css('marginLeft', 860);
    $('#page_bg').css('opacity', 0.25);
    $('#page_wrap').prepend('<span id="bg_load">LOADING...</span>');
    $('#bg_load').fadeIn('fast');

    //////////////////////////////////////////////////
    //////////////////////////////////////////////////

});
kobe
  • 15,671
  • 15
  • 64
  • 91