Skip to content

Instantly share code, notes, and snippets.

@tkh44
Last active August 23, 2017 22:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tkh44/1901ee1dc43ec4cfcde8fdfa0fa931ba to your computer and use it in GitHub Desktop.
Save tkh44/1901ee1dc43ec4cfcde8fdfa0fa931ba to your computer and use it in GitHub Desktop.
import React from 'react';
import { findDOMNode } from 'react-dom';
import PropTypes from 'prop-types';
import listen from 'simple-listen';
import { getTop } from 'fbjs/lib/Scroll';
export default class SidebarAdManager extends React.Component {
constructor (props) {
super(props);
this.state = { stickyAd: {} };
this.ads = {};
}
componentDidMount () {
this.resizeListener = listen(window, 'resize', this.handleWindowUpdate);
this.scrollListener = listen(window, 'scroll', this.handleWindowUpdate);
this.handleWindowUpdate();
}
componentWillUnmount () {
this.resizeListener();
this.scrollListener();
// for (const index in this.ads) this.ads[index] = null;
}
handleWindowUpdate = () => {
const { adTopOffset } = this.props;
// const scrollTop = getTop(window.document.body);
let stickyAd = Object.assign({}, this.state.stickyAd);
console.log('adTopOffset', adTopOffset);
console.log('stickyAd', stickyAd);
let prevIndex;
for (const index in this.ads) {
// eslint-disable-next-line react/no-find-dom-node
const rect = findDOMNode(this.ads[index]).getBoundingClientRect();
if (index === '2') {
console.log(index, rect);
}
if (
stickyAd.index
&& stickyAd.index === prevIndex
&& stickyAd.rect.bottom + 250 >= rect.top
) {
console.log('about to collide');
} else if (rect.top <= adTopOffset) {
stickyAd.index = index;
stickyAd.rect = rect;
} else if (index === stickyAd.index) {
stickyAd = {}
}
prevIndex = index;
}
if (this.state.stickyAd.index !== stickyAd.index) {
this.setState({ stickyAd });
}
};
renderAd = (index, adComponent, props, ...children) => {
const { targetWidth, targetHeight, adTopOffset, onStick } = this.props;
return React.createElement(
adComponent,
{
...props,
ref: (node) => {
this.ads[index] = node;
},
attachedToHead: parseInt(this.state.stickyAd.index, 10) === index,
lastKnownRect: this.state.stickyAd.rect,
onStick,
targetHeight,
targetWidth,
topOffset: adTopOffset,
},
...children,
);
};
render () {
const { render } = this.props;
return render({
renderAd: this.renderAd,
});
}
}
SidebarAdManager.propTypes = {
adTopOffset: PropTypes.number.isRequired,
targetHeight: PropTypes.number.isRequired,
targetWidth: PropTypes.number.isRequired,
adTopOffset: PropTypes.number.isRequired,
onStick: PropTypes.func.isRequired,
render: PropTypes.func.isRequired,
};
<SidebarAdManager
adTopOffset={adTopOffset}
onStick={this.handleStick}
targetHeight={250}
targetWidth={300}
topOffset={adTopOffset}
render={({ renderAd }) =>
(<div ref={this.handleRef} className="dynamic-ads">
{dynamicAds.map((_, i) =>
renderAd(i + 2, StickyAd, {
key: i + 2,
index: i + 2,
}),
)}
</div>)}
/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment