Automattic / antiscroll

OS X Lion style cross-browser native scrolling on the web that gets out of the way.
1.07k stars 162 forks source link

Rebuild/refresh methods on window resize #24

Open madcapnmckay opened 12 years ago

madcapnmckay commented 12 years ago

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

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

bitinn commented 12 years ago

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;

};

pgherveou commented 12 years ago

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); 
dizzib commented 11 years ago

Using both @madcapnmckay 's and @bitinn 's modifications above, I'm having success with the following code on a resize:

scroller.destroy().refresh();
calumbrodie commented 11 years ago

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.

jrhe commented 10 years ago

Bump

bargar commented 9 years ago

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.