3

I have this function that (on page load) changes my margin using the "css" jQuery method...

function page_change() {
  var h = window.location.hash;

  switch (h) {
    case 'home':
      $('.page-slide-box').css({marginLeft: 0});
      break;
    case 'history':
      $('.page-slide-box').css({marginLeft: '-820px'});
      break;
    // more cases here.....
  }
}

...but after the page is loaded, I'd like to animate the change instead. I was thinking I could alter the existing function using replace() (rather than writing another redundant function), like so:

window.onhashchange = function() {
  var get = page_change.toString();
  var change = get.replace(/css/g, 'animate');
  page_change();
}

This successfully changes all instances of "css" to "animate" in my page_change() function. How do I get this function to change dynamically once I've replaced the strings? Or is this just a bad idea?

Adam
  • 613
  • 7
  • 16
  • if you are using php, I would suggest to use a css with php variables like so myFile.css?var=value or replace the function with the new content. – radu florescu Feb 05 '13 at 06:52

3 Answers3

4

In your example, I'd say this is a terrible idea. Why not simply define 1 function that can do both, and use it accordingly:

var page_change = function(e)
{
    var method = e instanceof Event ? 'animate' : 'css';
    switch (location.hash)
    {
        case 'home':
            $('.page-slide-box')[method]({marginLeft: 0});
        break;
        //and so on...
    }
};

call this function directly, and it'll set the css, use it like so:

window.onhaschange = page_change;

and it'll animate instead of use the css method. Easy

If you want to test this easily, you could try this:

var page_change = function(e)
{
    var method = e instanceof Event ? 'animate' : 'css';
    console.log(method);
};
document.body.onclick = page_change;
page_change();//logs css
//click the body and... 
//animate will be logged

That's, basically, how this works.
The added benefit of defining a function like this (anonymous function, assigned to a variable or referenced by a var) is that you can easily assign a new function to that same variable:

var myFunc = function(){ console.log('foo');};
myFunc();//logs foo
myFunc = function(){console.log('bar')};
myFunc();//logs bar

This might work for you, too... of course. You can even store the old function:

var myFunc = function(){ console.log('foo');};
myFunc();//logs foo
var oldMyFunc = myFunc;
myFunc = function(){console.log('bar')};
myFunc();//logs bar
oldMyFunc();//logs foo

Play around with this for a while, to find the approach that fits your needs best (it could well be a combination of the things I talked about in this answer)

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • Thanks. This looks good but I'm not that familiar with the proper use of "instanceof" here - I think thats why it's not working for me; I'm just getting the "else" condition of css, no animation. – Adam Feb 05 '13 at 08:08
  • If you assign the `page_change` function as event handler (as I did in the last line of code), the `page_change`'s `e` argument will be assigned an event object. That's what the ternary is checking for: if `e` is an instance of the `Event` object, then the `animate` method will be used. if not, `e` will be undefined, or whatever you pass to the function as first argument... – Elias Van Ootegem Feb 05 '13 at 09:49
  • 1
    @Adam: I've also updated my answer, added a couple of additional tips/tricks that might help you – Elias Van Ootegem Feb 05 '13 at 09:59
0

You still need to create a new Function() with the body being the body with the replaced css, so just write another function in which you can put delays and callbacks and everything else that you need with animate().

Konstantin Dinev
  • 34,219
  • 14
  • 75
  • 100
0

Assign a boolean to reflect the page load state (say loadstatus), and use it to determine the action. You can use bracket notation to trigger the right action:

function page_change() {
  var h = window.location.hash,
      action = loadstatus ? 'animate' : 'css';
  //           ^ set loadstatus to true after page load.
  switch (h) {
    case 'home':
      $('.page-slide-box')[action]({marginLeft: 0});
  //                       ^ action used here
      break;
    case 'history':
      $('.page-slide-box')[action]({marginLeft: '-820px'});
      break;
    // more cases here.....
  }
}
KooiInc
  • 119,216
  • 31
  • 141
  • 177