From f6dff27961a4a1eb657626845b6bfff6bbb98b71 Mon Sep 17 00:00:00 2001 From: Voltron Date: Wed, 17 May 2017 16:37:33 -0400 Subject: [PATCH 1/2] fix jitter using a buffer --- lib/index.js | 5 +++-- src/index.js | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/index.js b/lib/index.js index 5c3bda7..fd39674 100644 --- a/lib/index.js +++ b/lib/index.js @@ -88,11 +88,12 @@ var Sticky = function (_React$Component) { }, { key: 'handleScroll', value: function handleScroll() { - if (window.scrollY > this.state.scrollIndex) { + var scrollBuffer = 10; + if (window.scrollY + scrollBuffer > this.state.scrollIndex) { this.setState({ scrollingLock: true }); - } else if (window.scrollY < this.state.scrollIndex) { + } else if (window.scrollY - scrollBuffer < this.state.scrollIndex) { this.setState({ scrollingLock: false }); diff --git a/src/index.js b/src/index.js index f42fa1b..7d6b5df 100644 --- a/src/index.js +++ b/src/index.js @@ -59,11 +59,12 @@ class Sticky extends React.Component { } handleScroll() { - if (window.scrollY > this.state.scrollIndex) { + const scrollBuffer = 10; + if (window.scrollY + scrollBuffer > this.state.scrollIndex) { this.setState({ scrollingLock: true }) - } else if (window.scrollY < this.state.scrollIndex) { + } else if (window.scrollY - scrollBuffer < this.state.scrollIndex) { this.setState({ scrollingLock: false }) From 59bac162a81d7a8fa8db1fc1dc8e1d0e742802f7 Mon Sep 17 00:00:00 2001 From: Voltron Date: Tue, 23 May 2017 10:44:55 -0400 Subject: [PATCH 2/2] 2.1.2 add debounce and jitter fix --- README.md | 7 +++++++ lib/index.js | 18 ++++++++++++------ package.json | 3 ++- src/index.js | 19 ++++++++++--------- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index b76b5c4..a22c5f2 100644 --- a/README.md +++ b/README.md @@ -60,3 +60,10 @@ - **scrollIndex** - @scrollIndex y=100 the stickyness will apply to the wrapped component - **isSticky** - A function that takes true or false to toggle stickyness - **stickyWidth** - Takes width if passed or defaults to 100% + + +### Changelog + +_2.1.2_ + - Added debounce to the on scroll events + - added a buffer around scrolling calculations diff --git a/lib/index.js b/lib/index.js index fd39674..8fd5cf9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -10,6 +10,10 @@ var _react = require('react'); var _react2 = _interopRequireDefault(_react); +var _debounce = require('debounce'); + +var _debounce2 = _interopRequireDefault(_debounce); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } @@ -34,16 +38,18 @@ var Sticky = function (_React$Component) { _this.handleScroll = _this.handleScroll.bind(_this); _this.calculateScrollIndex = _this.calculateScrollIndex.bind(_this); _this.calculateWidth = _this.calculateWidth.bind(_this); + _this.handleScrollDebounced = (0, _debounce2.default)(_this.handleScroll, 25); + _this.calculateWidthDebounced = (0, _debounce2.default)(_this.calculateWidth, 25); return _this; } _createClass(Sticky, [{ key: 'componentDidMount', value: function componentDidMount() { - window.addEventListener('scroll', this.handleScroll); + window.addEventListener('scroll', this.handleScrollDebounced); if (!this.props.stickyWidth) { this.calculateWidth(); - window.addEventListener('resize', this.calculateWidth); + window.addEventListener('resize', this.calculateWidthDebounced); } this.calculateScrollIndex(); } @@ -57,8 +63,8 @@ var Sticky = function (_React$Component) { }, { key: 'componentWillUnmount', value: function componentWillUnmount() { - window.removeEventListener('scroll', this.handleScroll); - window.removeEventListener('resize', this.calculateWidth); + window.removeEventListener('scroll', this.handleScrollDebounced); + window.removeEventListener('resize', this.calculateWidthDebounced); } }, { key: 'calculateScrollIndex', @@ -89,11 +95,11 @@ var Sticky = function (_React$Component) { key: 'handleScroll', value: function handleScroll() { var scrollBuffer = 10; - if (window.scrollY + scrollBuffer > this.state.scrollIndex) { + if (window.pageYOffset + scrollBuffer > this.state.scrollIndex) { this.setState({ scrollingLock: true }); - } else if (window.scrollY - scrollBuffer < this.state.scrollIndex) { + } else if (window.pageYOffset - scrollBuffer < this.state.scrollIndex) { this.setState({ scrollingLock: false }); diff --git a/package.json b/package.json index 2a2a13a..7d0a3f2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-stickky", - "version": "2.1.1", + "version": "2.1.2", "description": "make anything sticky with this react component", "main": "lib/index.js", "scripts": { @@ -41,6 +41,7 @@ "react-addons-test-utils": "^15.2.1" }, "dependencies": { + "debounce": "^1.0.2", "react": "^15.2.1" } } diff --git a/src/index.js b/src/index.js index 7d6b5df..3dafd31 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,5 @@ import React from 'react' +import debounce from 'debounce'; class Sticky extends React.Component { constructor(props) { @@ -11,13 +12,15 @@ class Sticky extends React.Component { this.handleScroll = this.handleScroll.bind(this) this.calculateScrollIndex = this.calculateScrollIndex.bind(this) this.calculateWidth = this.calculateWidth.bind(this) + this.handleScrollDebounced = debounce(this.handleScroll, 25) + this.calculateWidthDebounced = debounce(this.calculateWidth, 25) } componentDidMount() { - window.addEventListener('scroll', this.handleScroll) + window.addEventListener('scroll', this.handleScrollDebounced) if(!this.props.stickyWidth) { this.calculateWidth() - window.addEventListener('resize', this.calculateWidth) + window.addEventListener('resize', this.calculateWidthDebounced) } this.calculateScrollIndex() } @@ -29,8 +32,8 @@ class Sticky extends React.Component { } componentWillUnmount() { - window.removeEventListener('scroll', this.handleScroll) - window.removeEventListener('resize', this.calculateWidth) + window.removeEventListener('scroll', this.handleScrollDebounced) + window.removeEventListener('resize', this.calculateWidthDebounced) } calculateScrollIndex() { @@ -38,9 +41,7 @@ class Sticky extends React.Component { this.setState({ scrollIndex: this.props.scrollIndex && this.props.scrollIndex }) - } - - else if (this.refs[this.stickyRef]) { + } else if (this.refs[this.stickyRef]) { this.dimension = this.refs[this.stickyRef].getBoundingClientRect(); const scrollTop = window.pageYOffset || document.documentElement.scrollTop; this.setState({ @@ -60,11 +61,11 @@ class Sticky extends React.Component { handleScroll() { const scrollBuffer = 10; - if (window.scrollY + scrollBuffer > this.state.scrollIndex) { + if (window.pageYOffset + scrollBuffer > this.state.scrollIndex) { this.setState({ scrollingLock: true }) - } else if (window.scrollY - scrollBuffer < this.state.scrollIndex) { + } else if (window.pageYOffset - scrollBuffer < this.state.scrollIndex) { this.setState({ scrollingLock: false })