Skip to content
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

Auto-scroll only cares about window/body scroll #9

Open
adam-lynch opened this issue Apr 18, 2017 · 2 comments
Open

Auto-scroll only cares about window/body scroll #9

adam-lynch opened this issue Apr 18, 2017 · 2 comments

Comments

@adam-lynch
Copy link
Contributor

It should scroll the nearest ancestor with a scrollbar on the given axis. I say "on the given axis" because you could have a situation where the parent is horizontally scrollable but the grandparent is vertically scrollable.

@supraniti
Copy link
Owner

this is what i was initially trying to achieve...
but the solution comes with its own set of problems -
1 - you must check weather the current mouse position is on a 'scrollable' div (seems simple, but check this)
so it adds up more calculations.
2 - the calculations are different for a scrollable div and for the main window (each has its own properties to check)
Programmatically scrolling a div is also different from scrolling the window...
This makes the scroll controller code almost twice as long.
3 - Very difficult to get cross browser compatibility.

I wrote the code to handle it all (main functions are down here for reference) , but I ended up messing too much with scrolling and thought it might not worth the extra code and calculations (you rarely see scrollable divs on modern websites).
I think this issue (replacing browser native scrolling) deserves its own repository... i will get to it some day :-)

//scroll controller for replacing the native scroll behaviour var scrollManager = { event: null, active:true, refTarget: false, sm: 20,//scroll margin el: document.documentElement,//scroll scope nested: false,//true when scrolling an element, false when scrolling the window scrollInvoked:{ top:false, left:false, bottom:false, right:false }, getScrollContainer : function (el) { if (document.body.contains(el) && document.body !== el) { var y1 = el.scrollTop; el.scrollTop+=1; var y2 = el.scrollTop; el.scrollTop-=1; var y3 = el.scrollTop; el.scrollTop = y1; var x1 = el.scrollLeft; el.scrollTop+=1; var x2 = el.scrollLeft; el.scrollTop-=1; var x3 = el.scrollLeft; el.scrollLeft = x1; return (y1 === y2 && y2 === y3 && x1 === x2 && x2 === x3) ? this.getScrollContainer(el.parentNode): el; } return document.documentElement; }, targetUpdated: function () { this.refTarget = this.event.target; this.el = this.getScrollContainer(this.event.target); this.nested = (this.el !== document.documentElement); }, get canScroll(){ var mspx = this.el.scrollWidth - this.el.clientWidth, mspy = this.el.scrollHeight - this.el.clientHeight;//maximum scroll point on each axis return { top: (this.nested) ? this.el.scrollTop > 0 : window.pageYOffset > 0, left: (this.nested) ? this.el.scrollLeft > 0 : window.pageXOffset > 0, bottom: (this.nested) ? this.el.scrollTop < mspy : window.pageYOffset < mspy, right: (this.nested) ? this.el.scrollLeft < mspx : window.pageXOffset < mspx }; }, get cmp(){//current mouse position relative to container return{ x: (this.nested) ? this.event.clientX - this.el.getBoundingClientRect().left : this.event.clientX, y: (this.nested) ? this.event.clientY - this.el.getBoundingClientRect().top : this.event.clientY }; }, get willScroll(){ return{ top: (this.cmp.y <= this.sm)&&(this.canScroll.top), left: (this.cmp.x <= this.sm)&&(this.canScroll.left), bottom: (this.cmp.y >= this.el.clientHeight - this.sm)&&(this.canScroll.bottom), right: (this.cmp.x >= this.el.clientWidth - this.sm)&&(this.canScroll.right) }; }, get speed(){ return this.sm + (Math.max(0 - this.cmp.y,0 - this.cmp.x,this.cmp.y - this.el.clientHeight ,this.cmp.x - this.el.clientWidth)); }, updateEvent: function (e) { this.event = e; if (e.target !== this.refTarget) { this.targetUpdated(); } for (var key in this.willScroll){ if ((this.willScroll[key])&&(!this.scrollInvoked[key])){ this.move(key); } } }, move:function(key){ var self = this; this.scrollInvoked[key] = window.setInterval(function(){ if (self.nested) { switch (key) { case "top": self.el.scrollTop -= self.speed; break; case "left": self.el.scrollLeft -= self.speed; break; case "bottom": self.el.scrollTop += self.speed; break; case"right": self.el.scrollLeft += self.speed; break; } } else { switch (key) { case "top": window.scrollTo(window.pageXOffset, window.pageYOffset - self.speed); break; case "left": window.scrollTo(window.pageXOffset - self.speed, window.pageYOffset); break; case "bottom": window.scrollTo(window.pageXOffset, window.pageYOffset + self.speed); break; case"right": window.scrollTo(window.pageXOffset + self.speed, window.pageYOffset); break; } } if ((!self.willScroll[key])||(!self.active)){ clearInterval(self.scrollInvoked[key]); self.scrollInvoked[key]=false; } },16); } };

@adam-lynch
Copy link
Contributor Author

Yeah, it's tough.

Even if this was implemented, I assume doing scrollHeight, etc. checks up the DOM tree is too expensive so I guess the best thing would be to pass an array of elements or selectors (and their axes) to scroll.

I think this issue (replacing browser native scrolling) deserves its own repository... i will get to it some day :-)

Ha, yeah. But as a user, I couldn't even plug this hypothetical library in if it existed, because there's no drag event continuously fired (related: #5). If such an event existed, anyone could handle this themselves. That's probably the best way to go?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants