From a40ab406958307c4f4e3cc8e6e7d5e0a4d1d137f Mon Sep 17 00:00:00 2001 From: Jaron Kennel Date: Fri, 10 Apr 2015 11:04:08 -0400 Subject: [PATCH 1/2] Fix clicking and dragging the scrollbar rails with large margin values. Fix initial rail height/width calculation: Set the rails to display:block temporarily to correctly calculate percentage margins Account for scrolltop/left on the document. --- examples/scrollbars-with-margin.html | 32 +++++++++++++++++-------- src/js/plugin/handler/click-rail.js | 9 ++++--- src/js/plugin/handler/drag-scrollbar.js | 16 ++++++------- src/js/plugin/instances.js | 7 ++++++ src/js/plugin/update-geometry.js | 2 ++ src/js/plugin/update.js | 11 +++++++-- 6 files changed, 52 insertions(+), 25 deletions(-) diff --git a/examples/scrollbars-with-margin.html b/examples/scrollbars-with-margin.html index df50767..2b8486c 100644 --- a/examples/scrollbars-with-margin.html +++ b/examples/scrollbars-with-margin.html @@ -6,27 +6,39 @@ -
+

Default

+
+
+
+
+ +

Margins

+
diff --git a/src/js/plugin/handler/click-rail.js b/src/js/plugin/handler/click-rail.js index 2063689..94341d5 100644 --- a/src/js/plugin/handler/click-rail.js +++ b/src/js/plugin/handler/click-rail.js @@ -16,8 +16,8 @@ function bindClickRailHandler(element, i) { i.event.bind(i.scrollbarY, 'click', stopPropagation); i.event.bind(i.scrollbarYRail, 'click', function (e) { var halfOfScrollbarLength = h.toInt(i.scrollbarYHeight / 2); - var positionTop = e.pageY - pageOffset(i.scrollbarYRail).top - halfOfScrollbarLength; - var maxPositionTop = i.containerHeight - i.scrollbarYHeight; + var positionTop = i.railYRatio * (e.pageY - window.scrollY - pageOffset(i.scrollbarYRail).top - halfOfScrollbarLength); + var maxPositionTop = i.railYRatio * (i.railYHeight - i.scrollbarYHeight); var positionRatio = positionTop / maxPositionTop; if (positionRatio < 0) { @@ -33,9 +33,8 @@ function bindClickRailHandler(element, i) { i.event.bind(i.scrollbarX, 'click', stopPropagation); i.event.bind(i.scrollbarXRail, 'click', function (e) { var halfOfScrollbarLength = h.toInt(i.scrollbarXWidth / 2); - var positionLeft = e.pageX - pageOffset(i.scrollbarXRail).left - halfOfScrollbarLength; - console.log(e.pageX, i.scrollbarXRail.offsetLeft); - var maxPositionLeft = i.containerWidth - i.scrollbarXWidth; + var positionLeft = i.railXRatio * (e.pageX - window.scrollX - pageOffset(i.scrollbarXRail).left - halfOfScrollbarLength); + var maxPositionLeft = i.railXRatio * (i.railXWidth - i.scrollbarXWidth); var positionRatio = positionLeft / maxPositionLeft; if (positionRatio < 0) { diff --git a/src/js/plugin/handler/drag-scrollbar.js b/src/js/plugin/handler/drag-scrollbar.js index 4bab8c6..aede1ce 100644 --- a/src/js/plugin/handler/drag-scrollbar.js +++ b/src/js/plugin/handler/drag-scrollbar.js @@ -13,8 +13,8 @@ function bindMouseScrollXHandler(element, i) { var currentPageX = null; function updateScrollLeft(deltaX) { - var newLeft = currentLeft + deltaX; - var maxLeft = i.containerWidth - i.scrollbarXWidth; + var newLeft = currentLeft + (deltaX * i.railXRatio); + var maxLeft = i.scrollbarXRail.getBoundingClientRect().left + (i.railXRatio * (i.railXWidth - i.scrollbarXWidth)); if (newLeft < 0) { i.scrollbarXLeft = 0; @@ -24,7 +24,7 @@ function bindMouseScrollXHandler(element, i) { i.scrollbarXLeft = newLeft; } - var scrollLeft = h.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - i.scrollbarXWidth)); + var scrollLeft = h.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - (i.railXRatio * i.scrollbarXWidth))); element.scrollLeft = scrollLeft; } @@ -42,7 +42,7 @@ function bindMouseScrollXHandler(element, i) { i.event.bind(i.scrollbarX, 'mousedown', function (e) { currentPageX = e.pageX; - currentLeft = h.toInt(d.css(i.scrollbarX, 'left')); + currentLeft = h.toInt(d.css(i.scrollbarX, 'left')) * i.railXRatio; h.startScrolling(element, 'x'); i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler); @@ -58,8 +58,8 @@ function bindMouseScrollYHandler(element, i) { var currentPageY = null; function updateScrollTop(deltaY) { - var newTop = currentTop + deltaY; - var maxTop = i.containerHeight - i.scrollbarYHeight; + var newTop = currentTop + (deltaY * i.railYRatio); + var maxTop = i.scrollbarYRail.getBoundingClientRect().top + (i.railYRatio * (i.railYHeight - i.scrollbarYHeight)); if (newTop < 0) { i.scrollbarYTop = 0; @@ -69,7 +69,7 @@ function bindMouseScrollYHandler(element, i) { i.scrollbarYTop = newTop; } - var scrollTop = h.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - i.scrollbarYHeight)); + var scrollTop = h.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - (i.railYRatio * i.scrollbarYHeight))); element.scrollTop = scrollTop; } @@ -87,7 +87,7 @@ function bindMouseScrollYHandler(element, i) { i.event.bind(i.scrollbarY, 'mousedown', function (e) { currentPageY = e.pageY; - currentTop = h.toInt(d.css(i.scrollbarY, 'top')); + currentTop = h.toInt(d.css(i.scrollbarY, 'top')) * i.railYRatio; h.startScrolling(element, 'y'); i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler); diff --git a/src/js/plugin/instances.js b/src/js/plugin/instances.js index 507c0cc..a94a599 100644 --- a/src/js/plugin/instances.js +++ b/src/js/plugin/instances.js @@ -33,8 +33,12 @@ function Instance(element) { i.isScrollbarXUsingBottom = i.scrollbarXBottom === i.scrollbarXBottom; // !isNaN i.scrollbarXTop = i.isScrollbarXUsingBottom ? null : h.toInt(d.css(i.scrollbarXRail, 'top')); i.railBorderXWidth = h.toInt(d.css(i.scrollbarXRail, 'borderLeftWidth')) + h.toInt(d.css(i.scrollbarXRail, 'borderRightWidth')); + // Set rail to display:block to calculate margins + d.css(i.scrollbarXRail, 'display', 'block'); i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight')); + d.css(i.scrollbarXRail, 'display', ''); i.railXWidth = null; + i.railXRatio = null; i.scrollbarYRail = d.appendTo(d.e('div', 'ps-scrollbar-y-rail'), element); i.scrollbarY = d.appendTo(d.e('div', 'ps-scrollbar-y'), i.scrollbarYRail); @@ -46,8 +50,11 @@ function Instance(element) { i.scrollbarYLeft = i.isScrollbarYUsingRight ? null : h.toInt(d.css(i.scrollbarYRail, 'left')); i.scrollbarYOuterWidth = i.isRtl ? h.outerWidth(i.scrollbarY) : null; i.railBorderYWidth = h.toInt(d.css(i.scrollbarYRail, 'borderTopWidth')) + h.toInt(d.css(i.scrollbarYRail, 'borderBottomWidth')); + d.css(i.scrollbarYRail, 'display', 'block'); i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom')); + d.css(i.scrollbarYRail, 'display', ''); i.railYHeight = null; + i.railYRatio = null; } function getId(element) { diff --git a/src/js/plugin/update-geometry.js b/src/js/plugin/update-geometry.js index 1548c17..b951474 100644 --- a/src/js/plugin/update-geometry.js +++ b/src/js/plugin/update-geometry.js @@ -70,6 +70,7 @@ module.exports = function (element) { if (!i.settings.suppressScrollX && i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth) { i.scrollbarXActive = true; i.railXWidth = i.containerWidth - i.railXMarginWidth; + i.railXRatio = i.containerWidth / i.railXWidth; i.scrollbarXWidth = getThumbSize(i, h.toInt(i.railXWidth * i.containerWidth / i.contentWidth)); i.scrollbarXLeft = h.toInt(element.scrollLeft * (i.railXWidth - i.scrollbarXWidth) / (i.contentWidth - i.containerWidth)); } else { @@ -82,6 +83,7 @@ module.exports = function (element) { if (!i.settings.suppressScrollY && i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight) { i.scrollbarYActive = true; i.railYHeight = i.containerHeight - i.railYMarginHeight; + i.railYRatio = i.containerHeight / i.railYHeight; i.scrollbarYHeight = getThumbSize(i, h.toInt(i.railYHeight * i.containerHeight / i.contentHeight)); i.scrollbarYTop = h.toInt(element.scrollTop * (i.railYHeight - i.scrollbarYHeight) / (i.contentHeight - i.containerHeight)); } else { diff --git a/src/js/plugin/update.js b/src/js/plugin/update.js index 308a9df..54c3581 100644 --- a/src/js/plugin/update.js +++ b/src/js/plugin/update.js @@ -4,18 +4,25 @@ 'use strict'; var d = require('../lib/dom') + , h = require('../lib/helper') , instances = require('./instances') , updateGeometry = require('./update-geometry'); module.exports = function (element) { var i = instances.get(element); + // Recalculate rail margins + d.css(i.scrollbarXRail, 'display', 'block'); + d.css(i.scrollbarYRail, 'display', 'block'); + i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight')); + i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom')); + // Hide scrollbars not to affect scrollWidth and scrollHeight d.css(i.scrollbarXRail, 'display', 'none'); d.css(i.scrollbarYRail, 'display', 'none'); updateGeometry(element); - d.css(i.scrollbarXRail, 'display', 'block'); - d.css(i.scrollbarYRail, 'display', 'block'); + d.css(i.scrollbarXRail, 'display', ''); + d.css(i.scrollbarYRail, 'display', ''); }; From 046ce954fde98d9cf393156af2b01871cb0c788e Mon Sep 17 00:00:00 2001 From: Jaron Kennel Date: Mon, 13 Apr 2015 08:42:30 -0400 Subject: [PATCH 2/2] Fix gulp watch to call sass instead of css --- gulpfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index cb16e3a..3295f11 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -125,7 +125,7 @@ gulp.task('connect', ['build'], function () { gulp.task('watch', function () { gulp.watch(['src/js/**/*'], ['js']); - gulp.watch(['src/css/**/*'], ['css']); + gulp.watch(['src/css/**/*'], ['sass']); }); gulp.task('serve', ['connect', 'watch']);