Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save linhmtran168/2ec35dc3a78e3538fe58e97810aa1586 to your computer and use it in GitHub Desktop.
Save linhmtran168/2ec35dc3a78e3538fe58e97810aa1586 to your computer and use it in GitHub Desktop.
IScroll 5 with DOM change detection

IScroll 5 with DOM change detection

When implementing a custom scrollbars there’s a need to detect changes in height of the element to which you are applying the scrollbars to, as the height of the scrollbars need to be adjusted based on the content’s height. We also need to take into account that the content could change and height needs to be recalculated i.e paging on queries could yield 10 results, whilst on the last page it could yield just 5 results, and these changes need to be accounted for by the scrollbar. And the same problem arises when getting content asynchronously, because whilst the content is empty on initial render it gets rendered only after successful fetch of the required data and we should calculate the scrollbar height once the content is available which is hard to determine as the operation is asynchornous.

Different libraries and plugins deal with the problem separately.

Currently in our application we use the method that has been used by ftscroller which is to detect DOM mutations using Mutation Observer and for unsupported browsers like IE9, IE10 Android 4.1.2 we fall back to DOM Mutation events.

    var MutationObserver = window.MutationObserver || window.WebkitMutationObserver;
				
		if (MutationObserver) {
					obs = new MutationObserver(function (mutations, observer) {
						if (mutations[0].addedNodes.length || mutations[0].removedNodes.length) {
							domChanged(); //recalculate scrollbar height if necessary
						}
					});
					obs.observe(observeElem, { childList: true, subtree: true });
				} else {
					/*
					This is expensive in terms of performance. However the only alternative
					we would have is to use setInterval.
					*/
					observeElem.addEventListener('DOMSubtreeModified', domChanged, true);
		}

Mutation observers are performant and don't cause any visible performance lag but falling back on the mutation events on devices that don't support mutaion observer is an expensive operation which has been well documented all over the internet and somewhat visible on IE9 on our current application. https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events

Using set interval is another viable operation but firing set intervals for all the Gadgets could eat up the CPU cycles and over time bog the application performance.

One approach we could take to tackle the issue is to detect Touch devices and fallback to native overflow scrolling for these devices which could potentially leave us with only IE9 and IE10 suffering from the performance problem. But this would mean that we won't have any visible scrollbars on the gadget themselves and the users will have to rely on their on intuition/sixth sense to understand that content is scrollable.

Any thoughts and suggestion is welcome.

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