0

This is a simple loading script from nettuts and I tried to modify it to suit my needs. But I can't get function "res," which resizes loaded elements, to happen BEFORE function shownewcontent runs. Now it resizes after it is visible, which is very bad looking. But if I place call the function sooner, nothing happens, because the content is not yet loaded.

$(document).ready(function() { 
    var hash = window.location.hash.substr(1);  
    var href = $('#menu a').each(function(){  
        var href = $(this).attr('href');  
        if(hash==href.substr(0,href.length-4)){  
            var toLoad = hash+'.php #content';  
            $('#content').load(toLoad);
        }
    });  
    $('#menu a').click(function(){  
        var toLoad = $(this).attr('href')+' #content';  
        $('#content').hide('slow',loadContent);  
        window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-4);
        function loadContent() {  
            $('#content').load(toLoad,'',showNewContent());
        }  
        function showNewContent() {
            $('#content').show("0", res)
        }
        return false;
    });
});
mr.VVoo
  • 2,265
  • 20
  • 30
  • Your `showNewContent()` function calls `res()` as its callback. Why would you expect `res()` to happen first? Why not call `res()` as the callback to `load()` and then execute `showNewContent()`? – Mike Brant Apr 03 '13 at 18:50

1 Answers1

0

You have res() defined as the callback to show(), meaning it will get called after the show() function completes.

I would change your callback structure so that it contains all of the work you want to do:

$('#menu a').click(function(e) {  
    var toLoad = $(this).attr('href') + ' #content';  
    $('#content').hide('slow', function() {
        var self = this;
        $(self).load(toLoad, '', function() {
            res();
            $(self).show("0");
        });
    });  
    window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-4);
    e.preventDefault();
}

Then you don't need the function definitions inside your click handler.

FYI, instead of return false;, it would be better to use e.preventDefault(); at the end of your click handler, though. You will have to define e as a parameter to the click callback function. See this for the return false; vs. e.preventDefault() debate.

Additionally, if the resizing is taking a noticeable amount of time, you might want to have the res() function take a call back in the same fashion that show() does. Then you can show the content only once it's loaded and resized.

Community
  • 1
  • 1
Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
  • e.preventDefault(); causes script malfunction, instead of loading #content link (a href) is used. Your solution helped me immensely in understanding the problem, but it doesn't work, the objects are displayed with wrong proportions - I can only guess why, but if the function is called in `$('#content').show("0", res)` it works perfectely. – Peter Magic Apr 03 '13 at 19:10
  • `function loadContent() { $('#content').load(toLoad,'',function() {$('#content').css("visibility", "hidden").css("display", "inline"); res(); $('#content').css("visibility", "visible");});}` works well enough, thank you for your help! – Peter Magic Apr 03 '13 at 19:18
  • @PeterMagic: I made some post-accept changes to my answer so help clarify what I was intending. You can also combine your `.css()` changes by doing: `$('#content').css({ "visibility": "hidden", "display": "inline" });` – Cᴏʀʏ Apr 03 '13 at 19:57