Closed luruke closed 5 years ago
Hi. Barba is cool ) But it leaks of better ES6 support (e.g. I can't extend base transtion) and docs are confusing in some places. For example: http://barbajs.org/transition.html
Barba.Pjax.getTransition = function() {
/**
* Here you can use your own logic!
* For example you can use different Transition based on the current page or link...
*/
return FadeTransition;
};
It is cool, but I really can't use different Transition based on the current link because I can't access it from there.
About limits — impossibility to have several updatable containers
Hello @terion-name !
.getTransition
- You have different ways decide what transition to use. I have identified three techniques. You can check my comment here for more information: https://github.com/luruke/barba.js/issues/19#issuecomment-223874845 - Definitely is something that could be explained better on the documentationMany thanks for your feedbacks, I really appreciate it. Do not hesitate to make a pull request or to comment if you have further ideas / improvements. Cheers.
also:
Hello again @terion-name
Barba.Pjax.goTo
http://barbajs.org/docs/Barba.Pjax.html#.goToOh, and redirects handling
Redirects are easily handled if use fetch
.
And about forms, here is a demo how I handle forms now (this is a bad code, but I've needed to make it work VERY quick), it also handles redirects:
handleForms(e) {
e.preventDefault();
const url = e.target.getAttribute('action');
const method = e.target.method || 'get';
const formData = new FormData(e.target);
fetch(url, {
method: method,
body: formData
}).then(function (response) {
response.text().then(function(data) {
var newContainer = new Promise(function(resolve, reject) {
var container = Barba.Pjax.Dom.parseResponse(data);
Barba.Pjax.Dom.putContainer(container);
Barba.Pjax.History.add(response.url);
window.history.pushState({}, '', response.url);
setTimeout(resolve(container), 1);
});
var transition = Object.create(Barba.Pjax.getTransition());
Barba.Pjax.transitionProgress = true;
Barba.Dispatcher.trigger('initStateChange',
Barba.Pjax.History.currentStatus(),
Barba.Pjax.History.prevStatus()
);
var transitionInstance = transition.init(
Barba.Pjax.Dom.getContainer(),
newContainer
);
newContainer.then(
Barba.Pjax.onNewContainerLoaded.bind(Barba.Pjax)
);
transitionInstance.then(
Barba.Pjax.onTransitionEnd.bind(Barba.Pjax)
);
});
});
}
Thanks @terion-name for your inputs! Your example may work fine when the action of the form it's the same page, but, when the action is the current page I don't think It's a good idea.
Let me explain better: Let's suppose you have a long contact page with a google map, some text and at the end the contact form (and let's suppose your screen is small and you have to scroll down to see the contact form). Let's also say you are using a simple fade-in / fade-out transition.
Then, at the form submit the user will see the page fade out and the same page fading in, but with a different scroll position.
For a better UX should be your site to manually handle the submission of your form and not Barba.js responsibility.
For example, you may want to just hide the form, display a progress loading and then show the feedback (and maybe scroll to the feedback message to make sure the user will see it).
Making the transition on the whole container at the form submit it looks too much for me. I always use a different behaviour when forms are submitted.
Even if we let the user disable / enable functionality I wonder how many people will actually use it.
For "redirects handling", you meant related to the form submission?
Then, at the form submit the user will see the page fade out and the same page fading in, but with a different scroll position.
nope. I can use custom (or predefined in package) transition for this:
Barba.Pjax.getTransition = ()=> {
if (newUrl === oldUrl) {
return StaticTransition; // no fade, no scroll change
}
return BaseTransition;
};
Moreover, I'm using such thing now, for simulating tabs: links get data-noscroll="true"
attribute and my custom transition doesn't touch the scroll. And scrolls with animation in other case.
Of course, manual form handling is ideal, but It can be said the same for async page changing :) And purpose of this lib is to make this as simple a possible, so handling forms is logical.
For "redirects handling", you meant related to the form submission?
not only. backend can return redirects. xhr resolves them, barba — not. so if I click on /register
, backend redirects me to /register/step1
, Barba doesn't change url to /register/step1
but should.
Sorry for the late reply @terion-name , I've been quite busy recently. I'll brainstorm a bit about the form thing!
About the redirect handing, thanks! It more looks like a bug, I will check it!
Cheers
@luruke Barba is great! One pattern that it does not accommodate out of the box is if you want to return the user to the same scroll position. For example, if there is a long feed with links to individual posts and a 'back to feed' link, that when clicked returns them to the feed page at the same scroll position as when they left. There is a likely a way to accomplish this within the current API, so perhaps it is just a matter of putting together another code example in the docs.
first of all, i really enjoy working with barba.js, thank you for your great effort @luruke It's super easy to understand and use. Maybe theres a way to make binding specific page transition easy. Something like:
Barba.Pjax.getTransition = function(a, b) {
// first you'd have to define the specific transition that should be fired only from a to b
return specificTransition;
};
i know you could do something like this easily with conditions, but i think it would make working with barbe.js even nicer if its build in, theres probably also plenty of room to take the idea further.
Thanks for the suggestion @max-schu . I will try to do my best to start v2 next week :)
Cheers
Hi @luruke,
Thanks for your work, I was about to create the same kind of library, but then I found yours and it seems to work really well! :)
My initial reactions (some may be my mistakes)
this.newContainer.style.visibility = "visible";
in order to make things work as expected. Am I doing something wrong?Thank you for your precious advices @tipsy!
Usually, when I have forms on my websites using barba.js I prefer to handle them manually via ajax. But could be an idea.
It's quite easy if you want to use CSS transitions, you just need to create a basic transition that adds specific CSS classes during the different states of transition. Someone made a little "plugin" (https://github.com/JoeeGrigg/barba-transitions) that can be written better. Maybe I can provide with barba a default transition that adds specific classes.
yes, nice idea.
Strange, I'm including this https://github.com/taylorhakes/promise-polyfill https://github.com/luruke/barba.js/blob/master/src/index.js#L3
Generally I'd like to not add hundreds of features into barba.js, I would like to keep it simple as possible, but still very flexible.
Also one thing that scary me most is to keep the documentation very light without complicating it.
Usually, when I have forms on my websites using barba.js I prefer to handle them manually via ajax. But could be an idea.
I guess it depends on what you're making. I'm making a native-looking application with user settings (imagine it like android/iphone settings), so posts should feel the same as gets when the user navigates around. I can solve it like @terion-name did, but it would be nice if it worked out of the box. (I realize I'm probably not your target demographic though).
Just my two cents: add an auto html head update feature. Right now only the title tag is supported and I'm not the only one who would appreciate :-) I'm currently achieving it like this: https://gist.github.com/pierrehenri220/58690c83d8c8d5c9308a35a240b34d69
And good job for the library. I've just started to enjoy it.
"Nice shapes", amazing piece of codes 💯
Maybe I can provide with barba a default transition that adds specific classes.
Hi again @luruke,
After playing with Barba some more, I ended up with the classes barba-transition
and new-container
/old-container
, which I use like this:
.barba-transition {
// shared styles (pos abs, width, etc)
}
.animation-name.new-container {
// enter animation
}
.animation-name.old-container {
// exit animation
}
Maybe it's useful for you. Thanks again for your work on Barba!
@grenouille220 It doesn't make much sense do that to me :) see here: https://github.com/luruke/barba.js/issues/82
@tipsy Thank you!
Hi!
Maybe the possibility to add the .no-barba
class to a container to ignore all the links inside?
The @tipsy data-barba-prefetch
could be awesome!
Hi. Thanks @luruke for this great project, I've been waiting for something like this for a long time, I even created a little awkward script some time ago, but nothing comparable to barba.js. Some ideas:
I hope you find this useful Happy new year!
Thank you @oscarotero for your inputs!
This weekend I finally started working on this on the branch v2-dev 💪
I mostly worked on the build system / CI:
To have a view of a build process: https://travis-ci.org/luruke/barba.js/builds/192131197
Next steps:
If anyone wants to contribute, will be great if you could try the build process on your machine or help me to write more tests! 🙏🏻
Edit: Here's the gist showing what I mean: https://gist.github.com/nicooprat/ea184d51ba3c9ab131bf1d3400ef0ef0
I played a bit with Barba yesterday, and here are the features I'd dream of, and so the structure I'd need. Overall, I think Barba should behave and look more like a router.
Actually all of this is already kinda doable with getTransition
, but that could become very messy with a complex website. I think it should be done by the library by default (and only leave to the developer the possibility to overwrite/hook it maybe). I'd prefer a "config over code" behavior here. I tried to achieve this kind of behavior with v1, but the library is not structured for it, so it's really difficult. Here's what I think would be better:
/posts/*
). Very useful to below out
transitions...in
and out
methods which does a transition (or whatever actually): going "to" this route, or coming "from" it. These methods should receive as parameters:
in
and out
methods, when transition ends (or whatever the developer needs)timeline
) for example.in
and out
methods too, same as abovebefore(un)Loaded
, after(un)Loaded
, and so on, to trigger code (like creating a slider when coming on a page), getting rid of "global" Barba's events listenersSo internally, Barba would do the following when a link is clicked (speaking of transitions, the rest of the library works fine), pretty similar to the fade transition in the docs does:
out
transition (with parameters: next route & a promise to be resolved (getting rid of this.done()
) and loads the new URL contentsin
transition (again with route & promise parameters)The move to ES6 is great of course, although I'm not sure including the Promise polyfill is a good idea (in my build tools I already have one, and I don't want to have it included twice): could just declare it as a dep? Speaking of this, I think webpack and others shouldn't be defined in dependencies
in your package.json
, but rather in devDependencies
? A new label v2
for issues would be great too.
Hopefully I can spend some time on v2 in the next few weeks to help. I'll also try to make a quick gist to show what I'd like in a more concrete way. Anyway, I looked at a bunch of other librairies, and I think Barba is the closest to what I need, although the current code structure doesn't really fit for what I'm trying to do.
(Hope I'm clear and thanks for reading me :))
Hello @nicooprat, thanks for taking time to write this.
Router What you are describing i’s very similar to a generic router from a framework/SPA like Vue.js, React, Angular...
Defining routes it’s feasable, but It will introduce certain limitations in my opinion, examples:
How you will handle situations where you don’t know in advance the page path? Take for example a multilanguage website running wordpress.
What if you want to have “random” transitions? For example create a pool of transitions and pick a random one (it’s certainly not a common case)
Multiple transitions I’m working on a website where I’m using 8 transitions, and it looks fine like this:
getTransition() {
if (WorkToDetail.valid()) {
return WorkToDetail;
}
if (HomeAboutToAbout.valid()) {
return HomeAboutToAbout;
}
if (FooterToContact.valid()) {
return FooterToContact;
}
if (FooterContactToContact.valid()) {
return FooterContactToContact;
}
if (HomeSliderToCase.valid()) {
return HomeSliderToCase;
}
if (HomeSliderToPage.valid()) {
return HomeSliderToPage;
}
if (WorkSibling.valid()) {
return WorkSibling;
}
return FadeTransition;
}
Basically in each transition i’ve added a method .valid
that indicate if that transitions can be used or not.
Another example could be this: https://github.com/quentinneyraud/jekyll-starter-kit
As you can see you can easily write your own “structure” around barba.js
GSAP I’d like to keep the library independent, without introducing necessary dependencies.
Promise polyfill You’re right, it’s probably better not include the polyfill in the next version
devDependencies Thank you! I will fix it.
In general, i’d like to keep barba.js very unopinionated,without dictate much the structure of your code
What you are describing i’s very similar to a generic router from a framework/SPA like Vue.js, React, Angular...
Indeed, I worked the past few months with Meteor so I'm definitely biased, but I think there're good ideas there and Barba could be the perfect fit between SPA and "regular" websites.
How you will handle situations where you don’t know in advance the page path? Take for example a multilanguage website running wordpress.
To know what's the next route will be, we can match the link href against each route path
definition. We could also add something like data-route
to the a
tag to explicitly tell Barba what the next route is (actually that's what I'm doing now). If we don't know it, the route
parameter will be undefined, that's all. To be clear: I don't want Barba to be a full router, just something to progressively enhance the navigation, just like what it is now.
To retrieve an in or out transition, the logic would be:
The way to match complex URL against the path route definitions might be copied from an existing router. For example, for a multilang site, paths could be something like /[en|fr|it]/posts/*
. That would be really great, but maybe for a future release.
What if you want to have “random” transitions? For example create a pool of transitions and pick a random one (it’s certainly not a common case)
In and out transition methods actions are up to the developer. It just needs to resolve the promise. So random transitions are not a problem, being for a specific route or all of them, via the default transitions. We could also still expose the getTransition()
method if someone needs to overwrite it for some reason.
I’m working on a website where I’m using 8 transitions, and it looks fine like this:
Actually your example clearly shows what I'd rather avoid :) Could you show what's inside a valid()
method? I think you're somehow trying to create something that scale, like what I'm proposing, but sticking to the procedural structure of the current code. What's the advantage?
As you can see you can easily write your own “structure” around barba.js
Yes it's close to what I've in mind (BarbaWrapper and Page are interesting files). But it's really complicated! All this intelligence should be in Barba core IMO. I see no advantage of keeping it outside.
I’d like to keep the library independent, without introducing necessary dependencies.
Of course, that's not what I meant. I was thinking of a optional first-class integration, like the one in Scrollmagic (plugin). But that would be a bonus for a future release too :)
In general, i’d like to keep barba.js very unopinionated, without dictate much the structure of your code
I clearly agree on this, but I think your current code is not really far from what I'm proposing:
All of this is optional in case someone just want a simple fadeIn/fadeOut between all pages ; that could still be done in just a few lines of code. It's not more complicated, just rearranging things in a more scalable/robust/understandable way (IMO).
Thanks @nicooprat, For me the transition can not be determined only by the old route and the next route. (If I understand your vision)
In fact for me a transition can be determined by three factors (by URL, namespace, or the last item clicked), as I explained in this old problem: https://github.com/luruke/barba.js/issues/19#issuecomment-223874845
For example, I might want some sort of transition if I use the top navigation, and a different one if I click on a CTA at the center of the page.
Now of course this has to be managed "manually" (and that is what I am doing in metodo'.valid ', which is not so difficult, but I'm more than happy to explore new ways to simplify this.
I usually work on projects (wordpress), I can not really predict only by URL templates / transition, so this is my doubtful about the routing matching regex.
But I am really interesting to find a solution to simplify the way to choose and declare a transition!
You can open another issue where you can talk about your path proposed? I'm curious to see a test code!
Creating a new issue there. Just responding to your last comments here:
For me the transition can not be determined only by the old route and the next route. (If I understand your vision).
That's why every in/out transition methods should receive at least route
+ event
as parameters (so event.target
or event.target.href
could be useful). The issue you linked to shows how to currently do it indeed, but I think we can agree that it's pretty messy, like the need to store the clicked element in a global variable.
I usually work on projects (wordpress), I can not really predict only by URL templates / transition, so this is my doubtful about the routing matching regex.
That's my case too. For now, by default, I'm echoing the namespace
according to the Wordpress page template. The developer would still be totally free to set a particular namespace for, let's say, a special article that needs some javascript transitions (or even a different onEnter
event to initiate a slider). He/she would just have to create a new route js file. We even could let routes extend other routes to only overwrite some of its methods in this case.
How do you currently differentiate URLs to choose a transition? What more than my gist would you wish for a "test code"?
Thanks :)
another idea that just came to my mind is the option to save the state of the last visited page. I'm aware thats a typical SPA framework functionality, but since barba kind of is the go-to alternative for all devs that dont like/dont want/can't develop an SPA, why not…
what do you think?
Barba already exposes history with Barba.HistoryManager.prevStatus()
and Barba.HistoryManager.currentStatus()
(or full history array with Barba.HistoryManager.history
). Is it what you need?
depends if for example i manipulate the dom through js in the prevstate i'm not sure if the historymanager saves that – didn't test it tho – thanks for the hint.
Ok so you mean keeping the actual HTML of the previous views? Kind of overkill for Barba I guess :) But you could do it by listening to events and manually updating the Barba.HistoryManager.history
object.
yes indeed that's what i was talking about. I know… just a thought. I can imagine people end up real quick on this, when building pages with dynamic functionalities like filters sort, etc… But good to know it's kind of possible to achieve that, thanks!
@max-schu another idea that just came to my mind is the option to save the state of the last visited page ... what do you think?
I don't think barba should attempt to handle state-changes for you. You can solved "edited doms" by persisting the state-change on the backend, or by keeping a separate JS state yourself.
I wish me a easy way to replace multiple barba containers in one pajax request with different animations.
Here is an example:
The screenshot shows a product page with the shopsystem Shopify. On developing themes for Shopify I can not customize the Backend / Codebase of Shopify itself, so it is very limited to use single page applications like angular etc. This is why barba.js is perfect for this.
On Top right (prev, next) you can slide to the next product with a nice animation using barba,js. But normally everything (red, green and blue) slides in the same time with the same animation. It was I very tricky to solve this.
It would be nice if I could define multiple barba containers on the same site to handle the replacement for each container individual. So I would replace the blue and green part without any animation (So it looks as if it does not change) and I the red part with the slide animation.
What do you think about that?
Hello @JumpLink .
No, barba.js do not supports multiple containers. Technically it's possible but it was a design choice.
What you are describing should be feasable with a single transition. You might overlap new and old page then animate the right containers.
@JumpLink If I understand what you want to do, it's pretty easy to do this with CSS transitions. You put a barba-container on a parent element, position new/old container on top of each other, and do:
.transition .blue {
animation: none;
}
.transition .red {
animation: fade-in;
}
@luruke and @tipsy thanks for the advice, in a similar way I am solve this currently. Did I understood it correctly, that this feature request would not be an option for barba.js v2? Perhaps a main container and several children's containers would be a way to do this directly through the API for barba.js v2.
Btw: Thank you very much for this great and useful library and the good work!
Hello, i'm start using barba.js and its AWESOME(its really awesome), great work @luruke 👍 . I have a question. I want different page transition on some pages. Eg i want transition NUMBER ONE for aboutpage i want transition NUMBER TWO for projectpage. Is this possible?
@zachariast have a look here: https://github.com/luruke/barba.js/issues/19#issuecomment-223874845
Hi @luruke and first of all, thank you for all your work here!
I am currently working a new site and decided to use Barba to handle navigation. One of the requests was to replace complete page container for top-level menu items and only subpage container for second-level menu items (with sidebar staying in place). After a bit of testing, I found out this can be solved easily with something like this:
$(document).on('click', '[data-barba=subcontainer]', function(e){
Barba.Pjax.Dom.containerClass = 'barba-subcontainer';
Barba.Pjax.Dom.wrapperId = 'barba-subwrapper';
});
$(document).on('click', '[data-barba=container]', function(e){
Barba.Pjax.Dom.containerClass = 'barba-container';
Barba.Pjax.Dom.wrapperId = 'barba-wrapper';
});
But what would be really nice is to have the option to define multiple Barba instances instead of configuring static class. This would also allow per-instance transitions.
Love the framework! Couple things I'd like added..
A way to determine if the back/forward button was pressed.
A data-prefetch attribute on certain links to be prefetched, instead of prefetching all of them.
An event for initial page load, 'newPageReady' doesn't fire when hitting a url directly, or on initial page load
Offline-Support for the Barba Cache would be also nice for Barba.js v2
One of my favorite aspects of Barba is that it does not behave like a typical router in that you do not need to define routes. This makes it incredibly simple to drop into a project. Having used a framework like Bigwheel from Jam3 on many projects, I've realized how limiting the need to define routes can be for a large site with many dynamic routes (like a WordPress site). Hoping V2 keeps the simplicity of V1.
@lsbyerley What's your use-case for detecting a back/forward button press and where do you want to know this?
Using the existing API and some listeners it is possible to differentiate between the user following a link or navigating the browser history. The latter is caused by a popstate event. Barba starts listening to this event when you call start()
on Barba.Pjax
.
The following example shows how you can use the event to know how the user navigated while transitioning.
var popping = false;
window.addEventListener('popstate', function () {
popping = true;
});
Barba.Pjax.start();
Barba.Dispatcher.on('initStateChange', function() {
popping = false;
});
Barba.Pjax.getTransition = function() {
return popping ? HideShowTransition : FadeTransition;
};
Disabling animations on transitions triggered by popstate
is very useful if you don't want Safari to glitch when using Swipe between pages on macOS. Unfortunately the Barba documentation does not take this into consideration in the FadeTransition Example and the API does not allow to detect it out-of-the-box. Because of this a lot of websites that use animated transitions, including the Barba examples, are very unpleasant to navigate when using swipe gestures or mouse hotkeys.
@bramcordie Thanks for the explanation. I'm adding an is-active
class to my nav links when linkClicked
is triggered. If you press the back button, this is never fired and the nav links don't show correct active link.
Hey @lsbyerley, our use-case are completely different but I think I can help you out.
Instead of listening to linkClicked
you can switch to initStateChange
. This event might not give you the element that was clicked but the currentStatus
argument is enough to get the current URL and update your navigation.
Below is some example code. You might need to change the nav
and a
queries, have fun 😎
Barba.Dispatcher.on('initStateChange', function(currentStatus) {
$('nav').find('a').each(function() {
$(this).toggleClass('is-active', $(this).href === currentStatus.url);
});
});
@luruke I don't think the source of the official docs are public so I can't send a pull request to add this example? I'm not sure where it belongs but you might consider adding it under http://barbajs.org/faq.html?
Hey @bramcordie thanks man this works great and solves the back/forward issue!
@bramcordie thanks this is great. How can I trigger the transitions on page load?
Hi All! I am really happy to see more and more people using Barba.js. It's really nice to be able to give something back to the open source community.
I am also proud that in ~20 issues opened from users, there is not a single bug that has been encountered.
The library has been initially used just from myself, but now we should look ahead and see how the library could be improved in a eventually major release.
I think the design and the concept behind the library seems working very well, it's flexible and it's easily adaptable to the user's need.
What I think could really be improved are how the API methods are exposed, and the naming in general.
Can you help me?
I would like to have an open discussion and see what are your ideas about it:
Thank you! 🎉