Skip to content
This repository has been archived by the owner on Oct 3, 2023. It is now read-only.

Fix/getting ref children #8

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions dist/inview.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,14 @@ var ReactInviewWrapper = function ReactInviewWrapper() {

_this.scrollListener = _this.scrollListener.bind(_this);
_this.handleScroll = (0, _debounce2.default)(_this.handleScroll.bind(_this), debounceTime);
_this.containerRef = _react2.default.createRef();
return _this;
}

_createClass(ReactInview, [{
key: 'componentDidMount',
value: function componentDidMount() {
if (!this.refs.container) {
if (!this.containerRef) {
throw new Error('Cannot find container');
}

Expand Down Expand Up @@ -127,11 +128,11 @@ var ReactInviewWrapper = function ReactInviewWrapper() {
}, {
key: 'handleScroll',
value: function handleScroll() {
if (typeof this.refs.container === 'undefined') {
if (typeof this.containerRef === 'undefined') {
return;
}

var element = this.refs.container.children[0];
var element = this.containerRef.children[0];
var boundingBox = getBoundingBox(element);
var viewPortBox = getViewPortBox(offsetY, boundingBox);
var elementIsInView = false;
Expand Down Expand Up @@ -186,7 +187,7 @@ var ReactInviewWrapper = function ReactInviewWrapper() {
}
return _react2.default.createElement(
'div',
{ style: styles, ref: 'container' },
{ style: styles, ref: this.containerRef },
_react2.default.createElement(ComposedComponent, _extends({ update: this.handleScroll }, this.state, this.props)),
this._showGuides()
);
Expand Down
127 changes: 64 additions & 63 deletions src/inview.jsx
Original file line number Diff line number Diff line change
@@ -1,127 +1,128 @@
import React, { Component } from 'react';
import debounce from "lodash/debounce";
import React, { Component } from 'react'
import debounce from 'lodash/debounce'

// Returns dimensions of container
function getViewPortBox(offsetY, boundingBox) {
function getViewPortBox (offsetY, boundingBox) {
let vTop = 0,
vLeft = 0,
vWidth = window.innerWidth || document.documentElement.clientWidth,
vHeight = window.innerHeight || document.documentElement.clientHeight;
vHeight = window.innerHeight || document.documentElement.clientHeight

if (offsetY >= 0 && offsetY <= 1) {
const newHeight = vHeight * (1- offsetY);
const newTop = (vHeight - newHeight) /2;
vTop = newTop;
vHeight = newHeight;
const newHeight = vHeight * (1 - offsetY)
const newTop = (vHeight - newHeight) / 2
vTop = newTop
vHeight = newHeight
}

return {
top: vTop,
height: vHeight,
width: vWidth,
left: vLeft
};
}
}

// Returns dimensions of element/target
function getBoundingBox(el) {
let rect = el.getBoundingClientRect();
return rect;
function getBoundingBox (el) {
let rect = el.getBoundingClientRect()
return rect
}

// Checks to see if element is visisble
function isElementFullyVisible (el, rect, viewport) {
return (
return (
rect.top >= viewport.top &&
rect.left >= 0 &&
rect.bottom <= viewport.top + viewport.height &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
)
}

function isElementTopVisible (el, rect, viewport) {
const topIsInView = !(rect.top >= (viewport.top + viewport.height));
const topIsAboveView = !((rect.top + rect.height - viewport.height) <= viewport.top);
const topIsInView = !(rect.top >= (viewport.top + viewport.height))
const topIsAboveView = !((rect.top + rect.height - viewport.height) <= viewport.top)
return (
topIsInView && topIsAboveView
);
)
}

let ReactInviewWrapper = function ReactInviewWrapper ({
offsetY = 0,
showGuides = false,
fullElementInView = true,
debounceTime = 100
}={}) {
} = {}) {
return (ComposedComponent) => {

return class ReactInview extends Component {
return class ReactInview extends Component {

constructor() {
super();
constructor () {
super()

this.state = {
elementIsInView: false,
elementIsHasBeenInView: false,
boundingBox: {},
viewPortBox: {}
};
}

this.scrollListener = this.scrollListener.bind(this);
this.handleScroll = debounce(this.handleScroll.bind(this), debounceTime);
this.scrollListener = this.scrollListener.bind(this)
this.handleScroll = debounce(this.handleScroll.bind(this), debounceTime)
this.containerRef = React.createRef()
}

componentDidMount() {
if (!this.refs.container) {
throw new Error('Cannot find container');
componentDidMount () {
if (!this.containerRef) {
throw new Error('Cannot find container')
}

if (typeof(window) !== 'undefined') {
window.addEventListener('scroll', this.scrollListener);
this.handleScroll();
if (typeof (window) !== 'undefined') {
window.addEventListener('scroll', this.scrollListener)
this.handleScroll()
}

}

componentWillUnmount() {
if (typeof(window) !== 'undefined') {
window.removeEventListener('scroll', this.scrollListener);
componentWillUnmount () {
if (typeof (window) !== 'undefined') {
window.removeEventListener('scroll', this.scrollListener)
}
}

scrollListener() {
scrollListener () {
window.requestAnimationFrame(() => {
this.handleScroll();
});
this.handleScroll()
})
}

handleScroll() {
if (typeof this.refs.container === 'undefined') { return; }
handleScroll () {
if (typeof this.containerRef.current === 'undefined') { return }

const element = this.refs.container.children[0];
const boundingBox = getBoundingBox(element);
const viewPortBox = getViewPortBox(offsetY, boundingBox);
let elementIsInView = false;
const element = this.containerRef.current.children[0]
const boundingBox = getBoundingBox(element)
const viewPortBox = getViewPortBox(offsetY, boundingBox)
let elementIsInView = false

if(fullElementInView) {
elementIsInView = isElementFullyVisible(element, boundingBox, viewPortBox);
if (fullElementInView) {
elementIsInView = isElementFullyVisible(element, boundingBox, viewPortBox)
} else {
elementIsInView = isElementTopVisible(element, boundingBox, viewPortBox);
elementIsInView = isElementTopVisible(element, boundingBox, viewPortBox)
}
const newState = {
elementIsInView: elementIsInView,
boundingBox: boundingBox,
viewPortBox: viewPortBox
};
}
if (elementIsInView) {
newState.elementHasBeenInView = elementIsInView;
newState.elementHasBeenInView = elementIsInView
}
this.setState(newState);
this.setState(newState)
}

_showGuides() {
_showGuides () {
if (showGuides && typeof this.state.viewPortBox.top !== 'undefined') {
const {top, left, height, width} = this.state.viewPortBox;
const {top, left, height, width} = this.state.viewPortBox
let styles = {
'backgroundColor': '#ccc',
'position': 'fixed',
Expand All @@ -131,28 +132,28 @@ let ReactInviewWrapper = function ReactInviewWrapper ({
'height': height,
'width': width,
'zIndex': 99999999999
};
}

return <div style={styles}></div>;
return <div style={styles}></div>
}
}

render() {
let styles = {};
render () {
let styles = {}
if (showGuides) {
styles = {
backgroundColor: 'gray'
}
}
return (
<div style={styles} ref="container">
<ComposedComponent update={this.handleScroll} {...this.state} {...this.props} />
{ this._showGuides() }
return (
<div style={styles} ref={this.containerRef}>
<ComposedComponent update={this.handleScroll} {...this.state} {...this.props} />
{this._showGuides()}
</div>
);
)
}
};
};
};
}
}
}

export default ReactInviewWrapper;
export default ReactInviewWrapper