antiscroll
antiscroll copied to clipboard
Rebuild/refresh methods on window resize
Hi,
My container is 100% height. I am handling the window resize to update the scroller. All three potential methods I've tried have issues.
Here is a gist that demonstrates the issue.
https://gist.github.com/2522897
The methods I've tried to get this to work
- reapply the plugin_ - This works but the scroller range is not updated.
- rebuild - Updates the size of the inner div but removes the scroll bars
- refresh - Updates the scroller but doesn't change the size of the inner div.
I'm not sure why the plugin has both a rebuild and a refresh method? From reading the previous issues it seems rebuild was meant to solve the issue of flexible containers. I have an alternative fix which doesn't require the rebuild method.
function Antiscroll (el, opts) {
this.el = $(el);
this.options = opts || {};
this.x = false !== this.options.x;
this.y = false !== this.options.y;
this.padding = undefined == this.options.padding ? 2 : this.options.padding;
this.inner = this.el.find('.antiscroll-inner');
this.refresh();
};
Antiscroll.prototype.refresh = function() {
var width = this.el.width(),
height = this.el.height(),
needHScroll, needVScroll;
this.inner.css({
'width': (width + scrollbarSize()) + 'px'
, 'height': (height + scrollbarSize()) + 'px'
});
needHScroll = this.inner.get(0).scrollWidth > width;
needVScroll = this.inner.get(0).scrollHeight > height;
if (!this.horizontal && needHScroll && this.x) {
this.horizontal = new Scrollbar.Horizontal(this);
} else if (this.horizontal && !needHScroll) {
this.horizontal.destroy();
this.horizontal = null
}
if (!this.vertical && needVScroll && this.y) {
this.vertical = new Scrollbar.Vertical(this);
} else if (this.vertical && !needVScroll) {
this.vertical.destroy();
this.vertical = null
}
};
I simply update the inner size in the refresh method. This step can then be removed from the constructor. Works great for me. Maybe I am missing the reason for the rebuild method.
Thanks
I believe what happened here is that destroy() method forget to clean up scrollbar variable
I don't have git with me at the moment, but try this destroy() method
Antiscroll.prototype.destroy = function () {
if (this.horizontal) {
this.horizontal.destroy();
this.horizontal = null
}
if (this.vertical) {
this.vertical.destroy();
this.vertical = null
}
return this;
};
I am using this workaround, I just tested it on IE8, this seems to to do the job, it could probably be encapsulated inside the lib
// on resize ...
// reset size of wrapper and inner, you can probably do the same for height if you do horizontal scroll
scroller.inner.width('auto');
scroller.el.width('auto');
// resize it again
// I updated antiscroll to expose the scrollbarbarsize and reuse it here
scroller.el.width(w = this.scroller.el.width());
scroller.inner.width(w + this.scroller.scrollbarSize);
Using both @madcapnmckay 's and @bitinn 's modifications above, I'm having success with the following code on a resize:
scroller.destroy().refresh();
Is there a documented 'correct' way to refresh the antiscroll? I have various things like window resize, adding elements to the container and loading this via ajax that all require the antiscroll to be destroyed and reapplied and I can't work out which method I should be using.
Bump
I was having trouble with rebuild as used in Addepar/ember-table. Horizontal scrolling after content resize sometimes results in an inability to scroll all the way to the right to see the rightmost content. From my tests this seems to be true with vanilla usage of antiscroll rather than something incorrect in ember-table.
Changing the way the antiscroll-inner div is sized solved it for me and the usage of rebuild then worked as expected.
See Addepar/ember-table#249 for details.