From 8e6817912d4b1510fe56bd2fe192ae7ad8aef34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Buscht=C3=B6ns?= Date: Wed, 22 Mar 2017 15:28:08 +0100 Subject: [PATCH] calculate scrollbar width correctly --- addon/components/ember-scrollable.js | 94 +++++++++++++--------------- 1 file changed, 43 insertions(+), 51 deletions(-) diff --git a/addon/components/ember-scrollable.js b/addon/components/ember-scrollable.js index 982dcef1..ee875c88 100644 --- a/addon/components/ember-scrollable.js +++ b/addon/components/ember-scrollable.js @@ -2,7 +2,7 @@ import Ember from 'ember'; import InboundActionsMixin from 'ember-component-inbound-actions/inbound-actions'; import DomMixin from 'ember-lifeline/mixins/dom'; import layout from '../templates/components/ember-scrollable'; -import {Horizontal, Vertical} from '../classes/scrollable'; +import { Horizontal, Vertical } from '../classes/scrollable'; const { computed, @@ -67,10 +67,10 @@ export default Ember.Component.extend(InboundActionsMixin, DomMixin, { * @type Number */ scrollTo: computed('vertical', { - get(){ + get() { return this.get('vertical') ? this.get('scrollToY') : this.get('scrollToX'); }, - set(key, value){ + set(key, value) { deprecate('Using the `scrollTo` property directly has been deprecated, please prefer being explicit by using `scrollToX` and `scrollToY`.'); const prop = this.get('vertical') ? 'scrollToY' : 'scrollToX'; this.set(prop, value); @@ -215,40 +215,34 @@ export default Ember.Component.extend(InboundActionsMixin, DomMixin, { this._contentElement = this.$(`${contentSelector}:first`); }, + /** + * Original function by Jonathan Sharp: + * http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php + * + * Modified to work with newer jQuery version. + * + * @property scrollbarThickness + * @private + * @type Number + */ + scrollbarThickness: computed(() => { + // Append a temporary scrolling element to the DOM, then measure + // the difference between between its outer and inner elements. + let tempEl = $(` +
+
+
+
+
+ `); + $('body').append(tempEl); + let width = $(tempEl).width(); + let widthMinusScrollbars = $('.scrollbar-width-tester__inner', tempEl).width(); + tempEl.remove(); + + return (width - widthMinusScrollbars); + }), - measureScrollbar() { - - /** - * Calculate scrollbar width - * - * Original function by Jonathan Sharp: - * http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php - * Updated to work in Chrome v25. - */ - function scrollbarWidth() { - // Append a temporary scrolling element to the DOM, then measure - // the difference between between its outer and inner elements. - var tempEl = $('
'); - $('body').append(tempEl); - var width = $(tempEl).innerWidth(); - var widthMinusScrollbars = $('div', tempEl).innerWidth(); - tempEl.remove(); - - // On OS X if the scrollbar is set to auto hide it will have zero width. On webkit we can still - // hide it using ::-webkit-scrollbar { width:0; height:0; } but there is no moz equivalent. So we're - // forced to sniff Firefox and return a hard-coded scrollbar width. I know, I know... - - // https://github.com/alphasights/ember-scrollable/issues/34 - // if (width === widthMinusScrollbars && navigator.userAgent.toLowerCase().indexOf('firefox') > -1) { - // return 17; - // } - - return (width - widthMinusScrollbars); - } - - return scrollbarWidth(); - - }, /** * Used to create/reset scrollbar(s) if they are necessary @@ -264,7 +258,7 @@ export default Ember.Component.extend(InboundActionsMixin, DomMixin, { }); }, - _resizeHandler(){ + _resizeHandler() { debounce(this, this.resizeScrollbar, 16); }, @@ -275,7 +269,7 @@ export default Ember.Component.extend(InboundActionsMixin, DomMixin, { resizeScrollContent() { const width = this.$().width(); const height = this.$().height(); - const scrollbarThickness = this.measureScrollbar(); + const scrollbarThickness = this.get('scrollbarThickness'); const hasHorizontal = this.get('horizontal'); const hasVertical = this.get('vertical'); @@ -283,15 +277,13 @@ export default Ember.Component.extend(InboundActionsMixin, DomMixin, { if (hasHorizontal && hasVertical) { this.set('scrollContentWidth', width + scrollbarThickness); this.set('scrollContentHeight', height + scrollbarThickness); + } else if (hasHorizontal) { + this.set('scrollContentWidth', width); + this.set('scrollContentHeight', height + scrollbarThickness); + this._contentElement.height(height); } else { - if (hasHorizontal) { - this.set('scrollContentWidth', width); - this.set('scrollContentHeight', height + scrollbarThickness); - this._contentElement.height(height); - } else { - this.set('scrollContentWidth', width + scrollbarThickness); - this.set('scrollContentHeight', height); - } + this.set('scrollContentWidth', width + scrollbarThickness); + this.set('scrollContentHeight', height); } }, @@ -336,7 +328,7 @@ export default Ember.Component.extend(InboundActionsMixin, DomMixin, { * @method mouseMove * @private */ - mouseMove(){ + mouseMove() { if (this.get('autoHide')) { throttle(this, this.showScrollbar, THROTTLE_TIME_LESS_THAN_60_FPS_IN_MS); } @@ -349,8 +341,8 @@ export default Ember.Component.extend(InboundActionsMixin, DomMixin, { * @param e * @private */ - updateMouseOffset(e){ - const {pageX, pageY} = e; + updateMouseOffset(e) { + const { pageX, pageY } = e; this.set('horizontalMouseOffset', pageX); this.set('verticalMouseOffset', pageY); }, @@ -378,7 +370,7 @@ export default Ember.Component.extend(InboundActionsMixin, DomMixin, { * @private */ updateScrollbarAndSetupProperties(scrollOffset, scrollbarDirection) { - const {handleOffset, handleSize} = this.get(`${scrollbarDirection}Scrollbar`).getHandlePositionAndSize(scrollOffset); + const { handleOffset, handleSize } = this.get(`${scrollbarDirection}Scrollbar`).getHandlePositionAndSize(scrollOffset); this.set(`${scrollbarDirection}HandleOffset`, handleOffset); this.set(`${scrollbarDirection}HandleSize`, handleSize); }, @@ -522,7 +514,7 @@ export default Ember.Component.extend(InboundActionsMixin, DomMixin, { scrollTop() { this.set('scrollToY', 0); }, - scrolled(){ + scrolled() { scheduleOnce('afterRender', this, 'scrolled', ...arguments); }, horizontalDrag(dragPerc) {