-
Notifications
You must be signed in to change notification settings - Fork 13.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: Coupling two ion-scrolls (or setting an element within an ion-scroll to fixed on one axis) #1462
Comments
I just pushed a fix making sure both ion-scroll and ion-content support direction x and y scrolling. It worked in my tests. EDIT: Hold on, not pushing yet. Found a problem. |
You can now put The documentation now reflects this, too. |
That's nice to have @ajoslin thanks. It's not completely what I meant though in the feature request. This issue should be reopened. I'm talking about coupling two or more ion-scrolls to each other, and defining some kind of mechanism that would allow them to interact with each other. One use case would be to have a spreadsheet like scenario in which you can set a row to 'always stay on top'. You could then scroll vertically and horizontally through the document, while the header bar would remain fixed at the top, but would still scroll on one axis (left to right). Related to this would be sticky list headers for instance. Basically ion-scroll needs a mechanism to set an element to be sticky in one place. It would be really cool if you could set that element to be sticky on one axis (so either x or y). So it would scroll on one axis, but not the other. |
Sounds crazy! 💃 You could do it by catching the scroll event on your main scroll element and using that to scroll the other one, if it's the axis you want. |
Yes! Exactly. Is something like that possible? Do ion-scroll's emit their scrolling in some way? |
Yes. They emit a
|
Awesome. I'll take a look to see what I can come up with. |
If you want to stop the user from scrolling on the fixed element with his fingers...
This is of course very evil, touching a private API, and will get you arrested in 27 countries. |
Well, at least Zynga was good for something I guess ;) |
In Ios UIScrollview, I have three view side-to-side setuped, and one is webview which used ion-content and ion-refresher.However, except setting "scroll='false'"in ion=content, it won't be scrolled.In other words,UIScrollview can't handle the horizontal events.And it's ok in Android. |
I have no idea what you're talking about @beiliubei. Are you reporting a bug? Or contributing to the discussion about this feature request? And what is this about UIScrollview? |
@CoenWarmer, were you able to successfully couple multiple ion-scrolls in the way you described? I would be interested in the solution as I am trying to do something similar. Also, I noticed the solution you describe may help solve this issue on the forum: http://forum.ionicframework.com/t/when-using-horizontal-scroll-ion-scroll-page-cant-be-scrolled-down-in-y-direction/3833 |
Hey @evandsandler, I haven't made much progress on this I'm afraid. I'll try to see if this would work in my scenario. Drawback is, as they mentioned in the thread on the forum that the scroll position on the x axis won't be remembered this way- makes sense since it's just an overflowed div, and thus falls outside of the more advanced functionality that ion-scroll / ion-content offer. I still think an implementation where you can 'couple' two or more ion-scrolls together would be the best way to go about this. That would allow for some really cool functionality like easy parallax scrolling and a way to have timetables like this one: Where you would be able to scroll on the x axis and the y axis, but the names of the stages (in the black rows) would only move on the y axis, but not on the x. So they stay in the middle. And the times at the top would only move on the x axis, but stay at the top when you scroll up and down. |
@CoenWarmer, I see what you are saying, that would be a great UI design! After digging through the ionic code, i found that if you comment out or remove the "(e.defaultPrevented)" from the return statement in the ignoreScrollStart function then it allows scrolling to bubble up to parent scroll Views which would allow nested scroll views to work as desired. I haven't dug into the code to find out what potential side effects this might have though. To achieve the UI you are talking about then, perhaps you could do this and then have each black line be something like a class "list-divider" then each row of red squares be a <ion-scroll direction="x>. To get the times row to stay at the top perhaps you could use something like bootstrap's affix(https://github.com/passy/angular-bootstrap-affix). |
@CoenWarmer, perhaps a better and less 'hacky' way to do it on second thought is to make a method that checks if there is another scroll higher in the dom and prevents calling preventDefault at the end of self.touchStart in ionic.views.Scroll if it find there is a parent higher in the dom |
Seems like your comment got cut off @evandsandler... But I'm definitely intrigued by this approach. |
@CoenWarmer, you can just ignore my last comment until I figure out how to actually do it. The comment before though should help you get what you need hopefully. Let me know if it works for you or if my explanation of the changes to the ionic bundle were bad |
@CoenWarmer it seems a better way to do what you want to do would be to have just one ion-scroll container, have the black bars be width: 100%, and then use a directive on the black bar's header element to keep it centered horizontally. You can listen to the scroll event on the scroller and then broadcast that down as angular event, then have the headers catch it and align themselves correctly using JS. |
Hey @ajoslin, I've made some progress in building the code that allows elements to fixed on one axis. Code (in controller):
Video on how it looks in action: Only question left that would make this perfect. Right now I'm using a $timeout to execute this code in my controller. For some older devices, this timeout isn't long enough (maybe the DOM is still rendering? Unsure) so it gets called too early, and as a result $scope.scrollOffset never gets set. I could up the timeout, but that would lead people with faster devices to wait unnecessarily. Is there a way to make this code execute only when the template is done rendering? |
Hi @CoenWarmer, you can do the same using a directive instead of timeout.
|
@CoenWarmer Can you put your solution in CodePen.io too, I am trying to do something similar where I have two scrolls (Parent for horizontal scrolling of contents, some of the content in the horizontal scroll would have vertical list as scroll) Everything works good, but the event touch & move (horizontally) on the child scroll (used for list) is not sent to the parent horizontal scroll. |
I've come up with pretty simple solution to this that seems passable. <ion-content delegate-handle="mainScroll" has-bouncing="true" scroll="true"> Add drag events on the child/children ion-scroll(s) <ion-scroll direction="x" scrollbar-y="false" scrollbar-x="false" on-drag-down="onDrag($event)" on-drag-up="onDrag($event)"> In the controller add the onDrag function and the ionicScrollDelegate to the scope $scope.handle = $ionicScrollDelegate.$getByHandle('mainScroll');
$scope.onDrag = function(e){
var distance = -1 * e.gesture.deltaY;
$scope.handle.scrollBy(0,distance,true);
}; I hope this helps. |
@paulseed in html the delegate name is I'll keep digging. IMO the clean solution would be emitting the touch/drag events to parent ion-content when user dragged in y axis. I need to find a function/callback something where i can choose not to call |
Thank for the note on the typo! I fixed the the example. Anyway, after testing I realized that my above solution wasn't going to work, for the exact reasons you specified. So we came up with another solution.
Template:
The scrolling is now as you would expect. I have you say a big thanks to @jbasinger for all his help on this. DO WORK!!!! |
Interesting, I'll definitely try your solution, meanwhile i've come up with another solution too. Instead of monkey-patching the event listeners (which requires copying other related ionic codes to make it functional), i patched the event's var sv = $ionicScrollDelegate.$getByHandle('slider').getScrollView();
var container = sv.__container;
var originaltouchStart = sv.touchStart;
var originaltouchMove = sv.touchMove;
container.removeEventListener('touchstart', sv.touchStart);
document.removeEventListener('touchmove', sv.touchMove);
sv.touchStart = function(e) {
e.preventDefault = function(){}
originaltouchStart.apply(sv, [e]);
}
sv.touchMove = function(e) {
e.preventDefault = function(){}
originaltouchMove.apply(sv, [e]);
}
container.addEventListener("touchstart", sv.touchStart, false);
document.addEventListener("touchmove", sv.touchMove, false); Currently i tested this from controller and it worked like a charm :3 . I'll need to move it to a directive now. |
Update: While Above solutions works on iPhone, whole thing goes haywire on android o.O |
Our solution works on android. I have a feeling yours should too. I have only tested on 4.0+ |
+1 |
-> http://forum.ionicframework.com/t/when-using-horizontal-scroll-ion-scroll-page-cant-be-scrolled-down-in-y-direction/3833/16 |
So, I just ran into the same problem, demonstrated here: http://codepen.io/anon/pen/BoGkA |
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out. |
Hey there,
I'm building a Timetable screen for a festival app. I'm using ion-scroll and ion-content to scroll the x axis of the screen, so you can scroll left to right to see more events.
This works, check out: http://codepen.io/squrler/pen/xihmk6
However! In cases when there are too many rows, some events might end up below the viewport so I would now also like to make the list scrollable vertically.
As far as I know that is currently not possible with the implementations of ion-scroll that we have right now.
It would be really helpful if it were possible to couple two ion-scroll to each other, and being able to scroll one ion-scroll on the x and y axis, whilst the other ion-scroll is locked on one axis.
This would allow for very cool scrolling effects, possibly leading to very easy to deploy parallax scrolling.
The text was updated successfully, but these errors were encountered: