Skip to content

Commit d75ef7d

Browse files
committed
Fix fire onEnter callback anyway when parent isn't display
Fix #328
1 parent 2239914 commit d75ef7d

2 files changed

Lines changed: 68 additions & 15 deletions

File tree

src/waypoint.jsx

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,7 @@ export class Waypoint extends React.PureComponent {
134134
* as a fallback.
135135
*/
136136
_findScrollableAncestor() {
137-
const {
138-
horizontal,
139-
scrollableAncestor,
140-
} = this.props;
137+
const { horizontal, scrollableAncestor } = this.props;
141138

142139
if (scrollableAncestor) {
143140
return resolveScrollableAncestorProp(scrollableAncestor);
@@ -159,7 +156,11 @@ export class Waypoint extends React.PureComponent {
159156
: style.getPropertyValue('overflow-y');
160157
const overflow = overflowDirec || style.getPropertyValue('overflow');
161158

162-
if (overflow === 'auto' || overflow === 'scroll' || overflow === 'overlay') {
159+
if (
160+
overflow === 'auto'
161+
|| overflow === 'scroll'
162+
|| overflow === 'overlay'
163+
) {
163164
return node;
164165
}
165166
}
@@ -169,6 +170,25 @@ export class Waypoint extends React.PureComponent {
169170
return window;
170171
}
171172

173+
/**
174+
* Traverses up the DOM to check element is display.
175+
*
176+
* @return {Boolean}
177+
*/
178+
_checkDisplay() {
179+
let node = this._ref;
180+
181+
while (node && node instanceof Element) {
182+
const style = window.getComputedStyle(node);
183+
if (style.getPropertyValue('display') === 'none') {
184+
return false;
185+
}
186+
node = node.parentNode;
187+
}
188+
189+
return true;
190+
}
191+
172192
/**
173193
* @param {Object} event the native scroll event coming from the scrollable
174194
* ancestor, or resize event coming from the window. Will be undefined if
@@ -181,7 +201,9 @@ export class Waypoint extends React.PureComponent {
181201
}
182202

183203
const bounds = this._getBounds();
184-
const currentPosition = getCurrentPosition(bounds);
204+
// If waypoint or its parent is not display
205+
const currentPosition = this._checkDisplay() ? getCurrentPosition(bounds) : INVISIBLE;
206+
185207
const previousPosition = this._previousPosition;
186208
const {
187209
debug,
@@ -221,10 +243,8 @@ export class Waypoint extends React.PureComponent {
221243
onLeave.call(this, callbackArg);
222244
}
223245

224-
const isRapidScrollDown = previousPosition === BELOW
225-
&& currentPosition === ABOVE;
226-
const isRapidScrollUp = previousPosition === ABOVE
227-
&& currentPosition === BELOW;
246+
const isRapidScrollDown = previousPosition === BELOW && currentPosition === ABOVE;
247+
const isRapidScrollUp = previousPosition === ABOVE && currentPosition === BELOW;
228248

229249
if (fireOnRapidScroll && (isRapidScrollDown || isRapidScrollUp)) {
230250
// If the scroll event isn't fired often enough to occur while the
@@ -264,7 +284,8 @@ export class Waypoint extends React.PureComponent {
264284
contextHeight = horizontal ? window.innerWidth : window.innerHeight;
265285
contextScrollTop = 0;
266286
} else {
267-
contextHeight = horizontal ? this.scrollableAncestor.offsetWidth
287+
contextHeight = horizontal
288+
? this.scrollableAncestor.offsetWidth
268289
: this.scrollableAncestor.offsetHeight;
269290
contextScrollTop = horizontal
270291
? this.scrollableAncestor.getBoundingClientRect().left
@@ -341,10 +362,7 @@ if (process.env.NODE_ENV !== 'production') {
341362
// For instance, if you pass "-20%", and the containing element is 100px tall,
342363
// then the waypoint will be triggered when it has been scrolled 20px beyond
343364
// the top of the containing element.
344-
topOffset: PropTypes.oneOfType([
345-
PropTypes.string,
346-
PropTypes.number,
347-
]),
365+
topOffset: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
348366

349367
// `bottomOffset` can either be a number, in which case its a distance from the
350368
// bottom of the container in pixels, or a string value. Valid string values are

test/browser/waypoint_test.jsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,41 @@ describe('<Waypoint>', () => {
13901390
});
13911391
});
13921392
});
1393+
1394+
describe('When the parent element is not displayed', () => {
1395+
beforeEach(() => {
1396+
subject = () => {
1397+
parentStyle = {
1398+
height: 100,
1399+
display: 'none',
1400+
};
1401+
const el = renderAttached(
1402+
<div style={parentStyle}>
1403+
<div style={{ display: 'inline-block' }} />
1404+
<Waypoint {...props} />
1405+
<div style={{ display: 'inline-block' }} />
1406+
</div>,
1407+
);
1408+
1409+
jasmine.clock().tick(1);
1410+
return el;
1411+
};
1412+
});
1413+
1414+
afterEach(() => { });
1415+
1416+
it('does not call the onEnter handler', () => {
1417+
expect(props.onEnter).not.toHaveBeenCalled();
1418+
});
1419+
1420+
it('does not call the onLeave handler', () => {
1421+
expect(props.onLeave).not.toHaveBeenCalled();
1422+
});
1423+
1424+
it('does not call the onPositionChange handler', () => {
1425+
expect(props.onPositionChange).not.toHaveBeenCalled();
1426+
});
1427+
});
13931428
});
13941429

13951430
// smoke tests for horizontal scrolling

0 commit comments

Comments
 (0)