Skip to content
This repository

Allow effects #17

Closed
Philipp15b opened this Issue May 10, 2011 · 69 comments
Philipp Schröer

Hello,
I think it would be really great if it was possible to use effects, for example to show the new content.

Chris Wanstrath
Owner
defunkt commented May 11, 2011

I think this is very application-specific, but I'm not against adding a hook or something to help you make it work.

Philipp Schröer

Good idea. Hope it will be ready soon.

Dirk Brünsicke
d1rk commented May 11, 2011

Yeah, callback-functions would be easy to implement, i think.

Fabrica Sapiens

+1

I would use it for a full-content reload (only the menu stays) where the content is on the side of a cube. The cube flips to the right when the new content has loaded. When the user clicks 'back' the cube moves to the left again. Should look nice :-)

Mathew Davies

Can you not use the pjax.start and pjax.end events?

Roberto Decurnex

Guys, you can supply a success function with the options. If you do not supply one $.noop (and empty function) will be used instead.

Chris Wanstrath
Owner
defunkt commented May 18, 2011

@robertodecurnex Unfortunately the data is already inserted into the DOM by that point =/

https://github.com/defunkt/jquery-pjax/blob/master/jquery.pjax.js#L104

Roberto Decurnex

Ouch, you are right. So specific effect don't make much sense since everyone will need transition effects matching their sites so we can think in some sort of optional transition hook, let's say a transition function that can be supplied with the rest of he options.

Luke Morton

Or allow a custom DOM insertion method?

Christian Parpart
trapni commented July 01, 2011

I am currently hooking into start.pjax and end.pjax (or better: pageChanged & pageUpdated - as I'm using pjax-rails gem) to fadeOut() at click and fadeIn() at completion, however, it does not look as cool as I want it.

first thing is, when i actually click on a link, it takes still a high amount of msecs until my callback is invoked (it feels like), especially, when I have a terminal open in a second window, showing me the web server / rails activity, and it seems like when I click on a link/button, the request gets first sent, and then start.pjax is invoked, which I personally hate the most, because triggering the request can take ages depending on the client->server connection until my actual fadeOut starts. that feels very bad to me.

I'd wish some global point to hook into the click (start.pjax) and finish (end.pjax) to make the effect look like such :)

p.s.: doesn't github have a VOTE/BUMP-button somewhere? I thought so :)

Goudnet

I'm trying to do the exact same thing as trapni mentioned where I fadeOut my target DIV before sending the PJax, then fadeIn upon completion.

$('#pages').bind('start.pjax', function() { $('#pages').fadeOut(1000) }).bind('end.pjax', function() { $('#pages').fadeIn(1000) });

When I click my link, the #pages DIV immediately disappears, then the new content fades in as expected.

James Hu

I'm also interested in seeing this come to fruition.

Philipp Schröer

Maybe just stick with three events: Before request, after request and after inserting the new html. I think this would be enough for most effects.

Christian Parpart

I just want to be able to do basic fadeOut() on click, and fadeIn() when the new fragment has been inserted.

bump :)

Chris Heng

I did this by having a hidden "staging" div which is used to load in new content, and pjax.end triggers the starting animation, the insertion of the hidden content into the proper position, and the ending animation. You can even load content into multiple separate areas of the page this way.

Christian Parpart

@gigablah while this sounds as a really interesting "workaround", it's still what it is :) and I'd like to have an upstream
API-solution for it :)

Goudnet

Trapni, same here. I had to get around this also by using 2 divs and switching OLD/NEW content between them. Very ugly. hate it.

Scott Tolinski

I am very interested in being able to do this.

Joshua Peek
Collaborator

Actually going to look into this soonish. The github tree slider doesn't actually use pjax :( because of the animation.

I think supplying your own insert function ought to be enough.

Christian Parpart

@josh, having your idea in mind, I think that might be really a great solution, providing some neat example(s) on how to easily override the standard-"insert". that would be great.

but what does the upstream gem-dev think about it?

Martin Stabenfeldt

+1 on this.
Looking forward to when it will be done! :-)

fukuball

Looking forward the effects

João Sardinha

Is there any alternative way of achieving this at this time?

mjava1

Does anybody have any code samples on how to do this?

João Sardinha

I wanted to apply a fade out -> fade in effect, i managed to do it like this

jQuery(document).on('click', '.js-pjax', function(click) {

    click.preventDefault();

    var target = jQuery(this).attr('href';

    jQuery('#page').fadeOut('normal', function() {

        $.pjax({
            url: target),
            container: '#page'
        });

    });
});

What this does is hiding the content area, then load the page content into it, but only after the content area has faded out

Then on pjax:success i show the content

jQuery(document).on('pjax:success', function() {
    jQuery('#page').fadeIn('normal');
});

Im not sure if this is what you are asking, but i think this might help someone. If anyone has improvements to this snippet, please share.

Michael Yin

@johnsardine good idea, and I modified your code a little bit to save a little time by starting fadingOut and requesting at the same time

$('a').pjax('#main', {
    fragment: '#main',
    timeout: 5000
})
.live('click', function () {
    $('#main').fadeOut('normal');//change to your own speed
    //$('.loading').fadeIn('fast'); //if you need loading
});
$(document).on('pjax:success', function () {
    $('#main').stop().fadeIn('normal');//change to your own speed
    //$('.loading').fadeOut('fast');
});  
Joshua Peek
Collaborator
josh commented April 18, 2012

CSS fades are pretty easy with something like:

$('#main').on('pjax:start', function() {
  $(this).addClass('loading')
})

$('#main').on('pjax:end', function() {
  $(this).removeClass('loading')
})
#main {
  opacity: 1;
  transition: opacity 0.20s linear;
}

#main.loading {
  opacity: 0.5;
}
João Sardinha

I wrote my code the way I did because with the current methods, as the content was loaded very fast (which is great), the content was being changed while the fade out was being processed, so if anyone needs a page fade out, than load, than fade in, with the assurance that the content will only be changed after the target div has been faded out, can start with the code I suggested

Sean Hogan

I've created a branch to provide one solution to this issue. You can check the source at https://github.com/shogun70/jquery-pjax/tree/transition, and a demo at http://playground.meekostuff.net/jquery-pjax/demo/index.html

This solution adds a duration option which is the minimum duration for page transition. New content won't be inserted before this has expired, which allows page-out animation to complete.

If new content isn't ready then pjax:waiting is fired at the container, allowing for a waiting indicator.

@johnsardine, @layerssss might use it like

var duration = 400
$('a.pjax').pjax('#main', { duration: duration })
$('#main')
  .on('pjax:start', function() { $(this).fadeOut(duration) })
  .on('pjax:waiting', function() {
      $(this)
        .html('<div style="width: 100%; text-align: center;"><img src="waiting.gif" /></div>')
        .show()
    })
  .on('pjax:end',   function() { $(this).fadeIn(duration) })

It's really a proof-of-concept, so use it as food-for-thought or for nothing at all.

I've upped the default timeout to 5000ms, so if you consider adopting it whole you probably want to revert that.

mjava1
mjava1 commented May 02, 2012

Nice work, will give a try and keep you posted. Many thanks.

Patrick Campbell

Thank you @shogun70! It works a treat.

freman
freman commented May 27, 2012

Hey @shogun70, any chance you'll put a pull request in to get it merged into the defunkt trunk? :)

Oisin Lavery

+1
It would be great to have it in the main trunk.

James Hernandez

+1 for a PR from @shogun70, worth a shot

Michael Yin

+1 for a PR from @shogun70

Christian Parpart
trapni commented May 31, 2012

+1 for a PR from @shogun70 - best solution IMHO so far. :-)

Matthew Ferry

word @shogun70. that seriously needs to make it into the defunkt trunk

Sean Hogan

Thanks @matthewferry. I'm glad you like it.

I made the branch only so I could demo the concept - it's scrappy, doesn't have any testing, and doesn't even facilitate the github slider effect.

It's really more an exploration of the problem domain than a considered solution.

Oisin Lavery

Hey @shogun70, it might be scrappy and untested but it's better than nothing. I'm glad someone is trying to solve this problem!

tD3rk

Another +1 for @shogun70. This is such a common issue, this solution or another really needs make it to the main trunk.

Nate Goldman

+1 for @shogun70. Using his fork in production :)

Ianfeather

I've added a very simple hook for our own purposes, the pull request is here: #204

Just initialise it with options.animate: true

Silver89

+1 @shogun70, works perfectly, really should be in the main issue.

Anthony

Hey, guys, seems it is great plugin, only one thing I need to know before using it. Is there a way to make a close button for fade in/out box so the behaviour should be like back browser button? Really need this feature, waiting for someone reply. :) Thanks.

Matthew Ferry
Anthony

Thanks, matthewferry, for the reply, one more important thing. I start testing this plugin on my site and have some problem. Here is my link http://goo.gl/dcX9P If click on thumbnail link then pjax load my content above the thumb's block how it should be. But in case I copy the link for example http://demo.themeuniverse.net/pulse/?portfolio=cool-never-fades and place it in a new browser tab it shows only content without my header, thumbs, etc. Any help on how to fix that?

Matthew Ferry

@pixelous Questions specific to your implementation are better suited for Stack Overflow, not github issues...

Real quick though -- the second link there is broken... but if you want it to look the same, the ajaxed page would need to have the same markup, just with your overlay exposed on load. if the ajaxed page only contains the container element you're telling pjax to look for, then it won't look like the other page when linked to directly...

Anthony

matthewferry, thanks for your answer. One more question please how to achieve such effect like here http://jensen-demo.squarespace.com You see? When you click on a photo a right panel is move from the right with ajaxed content in it?

Dan

Just started using this, sweet stuff!

Small issue:
Using any jQuery version after 1.7.2 seems to give this error:
Uncaught TypeError: Object # has no method 'getAttribute'

This is how I am calling pjax:

var duration = 200
$('a.pjax').pjax('#guts', {
fragment: '#guts',
duration: duration
})
$('#guts')
.on('pjax:start', function() {
$(this).fadeOut(duration)
console.log('Start')
})
.on('pjax:waiting', function() {
$('.loader').show()
console.log('Waiting')
})
.on('pjax:end', function() {
$('.loader').hide()
$(this).fadeIn(duration)
console.log('Complete')
})

Would be fantastic if anyone could let me know if the problem is with my code and not with the plugin.

THANK YOU!

Sean Hogan

@LookingLA If you are using my branch it is based on an older clone of jquery-pjax which doesn't support jquery-1.8.

Dan

@shogun70 Sounds good to me, works great in jQuery 1.7.2. I tried to get in there and change whatever 1.7.3 depreciated but no luck, any ideas?

Sean Hogan

@LookingLA I don't think there was a jQuery 1.7.3 - did you mean 1.8.3?

Anyway, take a look at this commit

Dan

@shogun70 you are the man, thank you!

Joshua Peek josh closed this February 07, 2013
Joshua Peek
Collaborator

I don't think this is going to happen anymore.

Christian Parpart

just ignore a ticket long enough. sad story.

Silver89

So if you want use fadein/fadeout effects with pjax you now have to use css to avoid the issues this prevented?

Dan

There has never been a problem with fading content in and out with animation.

You do it like this:

$('a.pjax').pjax('#main-content-fragment', {
fragment: '#main-content-fragment',
duration: 300
});
$('#main-content-fragment')
.on('pjax:start', function() {
$(this).fadeOut(300)
})
.on('pjax:end', function() {
$(this).fadeIn(300)
})

Maybe you guys did not read this entire thread, but this Fork adds a loading callback: https://github.com/shogun70/jquery-pjax/

Oisin Lavery

Yes but there is no "duration" option in the main repo. The shogun70 fork hasn't been updated in 10months so is well behind.

Please, please add this tiny extra to Pjax!

Jon Long

@josh Could you elaborate on the decision to close this one? Is it because it's a duration-based solution rather than an evented one?

Dan

So closest we've been able to come without using shogun70's fork is a combination of several suggestions in this thread:
Using the latest version of pjax from https://github.com/defunkt/jquery-pjax
Full fade out on click, full fade in on pjax end.
The ONLY thing that is not perfect is the fading transitions when using the browser back button, you won't get a full fade out, but you will get a full fade in, which so far is going to work just fine for us.


var duration = 200;
var target = "";
$('body').delegate('a.pjax', 'click', function() {
var target = $(this).attr('href');
$('#main-content').fadeOut(duration, function() {
$.pjax({
url: target,
container: '#main-content',
fragment: '#main-content'
})
})
return false;
})
$('#main-content')
.on('pjax:start', function() {
$(this).fadeOut(0)
})
.on('pjax:send', function() {
$('.loader').show()
})
.on('pjax:success', function() {
$('.loader').hide()
})
.on('pjax:end', function() {
$(this).fadeIn(duration)
})

Conclusion:
• Using a callback on the initial click will yield smooth and complete fade out before pjax starts.
• Works great except browser back button doesn't "click" anything, so we just skip the fade out animation and just fade out the content at a duration of 0. This way, at least the content will fade in smoothly without blinking first when using the pop state/browser back.

A three fourths solution!

However, when it comes down to it, do we really want the back button to trigger the fade out animation? Perhaps it's actually more intuitive and more user friendly to have the content instantly removed and only fade in new content when using browser back and forth. Transitions are great for clicking throughout a site, but when going backward and skipping around, that extra 200ms or so could become obtrusive.

Anyway, we're happy now. Thanks everyone!

html5anchor

You're limiting the usage of Pjax by not providing an option to delay swapping of the content. As a result, we and many others are not able to use Pjax, just because this one feature is absent.
Not every history AJAX website wants to swap the content immediately on every page.

Aen Tan

Here's a tutorial on cross fading http://aenism.com/teleportation-is-scary/

Dan

Hey, that's neat, but not sure if cloning is always a good idea. Our pjaxed website does exactly the same thing by simply fading out the main content container, keeping it faded out until new content is added, then fading it in. Seems simple enough, we do a few more things not shown here, like forcing the height of the page so it doesn't collapse during transition, and adding a loader graphic etc.

Our site: http://looking.la

Our code:

  // USER CLICKS LINK WITH PJAX CLASS
  $('body').delegate('a.pjax', 'click', function() {
    // CONTENT FADE OUT TRANSITION BEGINS
    $('#main_inner').fadeOut(200, function() {
        // CALLBACK TO RUN PJAX AFTER FADEOUT
        $.pjax({
          url: target,
          container: '#main_inner',
          fragment: '#main_inner'
        })
    })
     // STOP THE LINK FROM WORKING NORMALLY
    return false;
  })

  // PJAX DOIN THANGS TO THE CONTENT FRAGMENT IDENTIFIED ABOVE
  $('#main_inner')
    .on('pjax:start', function() { 
      // KEEPING THE MAIN CONTENT HIDDEN
      $(this).fadeOut(0)
    })
    .on('pjax:end',   function() { 
      // FADE IN THE MAIN CONTENT
      $(this).fadeIn(200)
      // FUNCTIONS LOADED AGAIN AFTER PJAX ENDS GO HERE
    })

Aen Tan

@LookingLA I'm cloning because I needed a crossfade effect.

Dan

@aentan Oh, I see, very cool, I like it, thanks for sharing!

ghprod

this i'm looking for :)

Aen Tan

Great. Glad we could help.

marcmontecalvo

@LookingLA That was the first thing that worked for me. Thanks a ton for that!

Now when is PJAX going to get patched so we can just use the pjax:start and pjax:end instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.