Ich versuche, eine List-Ansicht in React zu implementieren. Was ich versuche zu erreichen, ist, dass die Liste Kopfzeilen Informationen zu speichern und registrieren Sie die Komponenten und registrieren Sie das Scroll-Ereignis. Jedes Mal, wenn der Benutzer das Fenster scrollt, möchte ich das gespeicherte div entfernen und die offsetTop
Daten neu berechnen.Erhalten divs OffsetTop-Positionen in React
Das Problem ist jetzt, dass ich fand die Konsole nur den Anfangswert ausdrucken (der Wert ist fixiert und nie geändert) offsetTop
Daten ändern sich nie in onscroll
Funktion.
Wer schlägt vor, wie man offsetTop
aus dem _instances
Objekt erhalten?
import React, { Component } from 'react';
import ListHeader from './lib/ListHeader';
import ListItems from './lib/ListItems';
const styles = {
'height': '400px',
'overflowY': 'auto',
'outline': '1px dashed red',
'width': '40%'
};
class HeaderPosInfo {
constructor(headerObj, originalPosition, originalHeight) {
this.headerObj = headerObj;
this.originalPosition = originalPosition;
this.originalHeight = originalHeight;
}
}
export default class ReactListView extends Component {
static defaultProps = {
events: ['scroll', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll', 'resize', 'touchmove', 'touchend'],
_instances:[],
_positionMap: new Set(),
_topPos:'',
_topWrapper:''
}
static propTypes = {
data: React.PropTypes.array.isRequired,
headerAttName: React.PropTypes.string.isRequired,
itemsAttName: React.PropTypes.string.isRequired,
events: React.PropTypes.array,
_instances: React.PropTypes.array,
_positionMap: React.PropTypes.object,
_topPos: React.PropTypes.string,
_topWrapper: React.PropTypes.object
};
state = {
events: this.props.events,
_instances: this.props._instances,
_positionMap: this.props._positionMap,
_topPos: this.props._topPos
}
componentDidMount() {
this.initStickyHeaders();
}
componentWillUnmount() {
}
componentDidUpdate() {
}
refsToArray(ctx, prefix){
let results = [];
for (let i=0;;i++){
let ref = ctx.refs[prefix + '-' + String(i)];
if (ref) results.push(ref);
else return results;
}
}
initHeaderPositions() {
// Retrieve all instance of headers and store position info
this.props._instances.forEach((k)=>{
this.props._positionMap.add(new HeaderPosInfo(
k,
k.refs.header.getDOMNode().offsetTop,
k.refs.header.getDOMNode().offsetHeight
));
});
let it = this.props._positionMap.values();
let first = it.next();
this.props._topPos = first.value.originalPosition;
this.props._topWrapper = first.value.headerObj;
}
initStickyHeaders() {
this.props._instances = this.refsToArray(this, 'ListHeader');
this.initHeaderPositions();
// Register events listeners with the listview div
this.props.events.forEach(type => {
if (window.addEventListener) {
React.findDOMNode(this.refs.listview).addEventListener(type, this.onScroll.bind(this), false);
} else {
React.findDOMNode(this.refs.listview).attachEvent('on' + type, this.onScroll.bind(this), false);
}
});
}
onScroll() {
// update current header positions and apply fixed positions to the top one
console.log(1);
let offsetTop = React.findDOMNode(this.props._instances[0].refs.header).offsetTop;
}
render() {
const { data, headerAttName, itemsAttName } = this.props;
let _refi = 0;
let makeRef =() => {
return 'ListHeader-' + (_refi++);
};
return (
<div ref="listview" style={styles}>
{
Object.keys(data).map(k => {
const header = data[k][headerAttName];
const items = data[k][itemsAttName];
return (
<ul key={k}>
<ListHeader ref={makeRef()} header={header} />
<ListItems items={items} />
</ul>
);
})
}
</div>
);
}
}
Der gesamte Quellcode ist auf Github, können Sie es klonen und kompilieren von hier:
Wahrscheinlich müssen Sie dem OffsetTop den '' 'scrollTop''' Wert hinzufügen, um den" echten "Offset zu erhalten. Ich konnte deinen Code auf Github nicht zur Arbeit bringen, also konnte ich es nicht versuchen:/ –
@PatrickNeschkudla wirklich? Welche Fehler hast du? Wahrscheinlich brauchst du npm zuerst das Webpack installieren. – JavaScripter
Nur ein Hinweis für alle, die darauf stolpern, denken Sie daran, dass React "React.findDOMNode" in sein eigenes Paket "react-dom" verschoben hat. Siehe [hier] (https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode) – aug