content resize detection
The content of my iScroll panels can change. Specifically the dimensions of the scrollElement can change depending on user interaction with the content (for example open/close a <details> element). Right now I'm forced to hook into actions that change my iScroll content and issue a scroller.refresh() when something changed. This is quite annoying and error-prone.
Have you seen Cross-Browser, Event-based, Element Resize Detection? It explains how you can detect content dimension changes across IE (native feature), Firefox and Chrome. It uses (unspecified) flow events to detect the changes. I've wrapped that in a function I added to my local IScroll copy - see the demo fiddle
IScroll.prototype.refreshOnContentResize = function() {
var _resize = this._resize.bind(this);
// make sure the scroller can fire overflow events
// this might be moved to user-css
this.scroller.style.height = '100%';
this.scroller.style.overflow = 'auto';
// Internet Explorer
this.scroller.addEventListener('resize', _resize, true);
// Firefox
this.scroller.addEventListener('overflowchanged', _resize, true);
// Webkit, Blink
this.scroller.addEventListener('overflow', _resize, true);
this.scroller.addEventListener('underflow', _resize, true);
this.on('destroy', function () {
// Internet Explorer
this.scroller.removeEventListener('resize', _resize, true);
// Firefox
this.scroller.removeEventListener('overflowchanged', _resize, true);
// Webkit, Blink
this.scroller.removeEventListener('overflow', _resize, true);
this.scroller.removeEventListener('underflow', _resize, true);
});
};
var scroller = new IScroll('#scroll-wrapper');
scroller.refreshOnContentResize();
This looks pretty cool Rodney. I am not using iScroll now. Will this modification work for horizontal scrolling? I'll have a gallery of items that I would like to scroll like a carousel. I will be dynamically adding and removing items.
The resize detection itself is applicable to both axes.
Getting rid of scroller.refresh() would be one of the best improvements to iScroll. :+1:
Are there any plans to implement this feature?
I dabbled with this to make it more generic. Couldn't make it work without changing too much of the DOM. Adding this would mean a couple of new rules imposed on the possible CSS for iScroll content.
Hmm. When I open your demo on jsfiddle I see the native scroll instead of iScrol because of overflow: autol. Is there a way to make it work for iScroll with overflow: hidden ?
Just wondered if it is possible to resize the wrapper as well. Trying to get the width of the device and using that to set the height of the wrapper. Not sure if its possible
Thanks!!
Hey, guys,
I ran into the same issue, so firstly I tried the refreshOnContentResize. However, I want to have scrollbars as well, and they get messed up with that solution.
So, I ended up with this:
- Included the
css-element-querieslibrary. - Listen for change of dimensions of the element that actually changes. (In my case was a form element.)
- When it changes - just triggers the
refreshmethod of the iScroll.
The final code was like this:
<script type="text/javascript" src='/js/vendor/ResizeSensor.js'></script>
<script type="text/javascript" src='/js/vendor/ElementQueries.js'></script>
// and later, when the iScroll inits ..
var the_iScroll = new IScroll(...);
new ResizeSensor(document.querySelector('form#my-form'), function(){
the_iScroll.refresh();
});
Hope this helps someone else :)
Regards, Petar