javascript - 如何在使用 ScrollView 的 native react 中实现 scrollspy?

标签 javascript reactjs react-native

我有一个包含不同元素的 ScrollView 组件说:

<ScrollView>

    <Item1/>

    <Item2/>

    <Item3/>

</ScrollView>

我现在有一个选项卡,我需要根据用户在 ScrollView 中查看的当前部分突出显示每个选项卡项。例如,如果用户正在查看/滚动到 <Item2/>在 ScrollView 中,然后我应该在选项卡中突出显示 item2 图标。

此外,如果用户单击选项卡项目,它应该自动使 ScrollView 滚动到相应项目的部分。

有没有办法在 React Native 中实现这个 scrollspy 功能?

最佳答案

要实现所需的行为,您需要结合几件事。

  1. ScrollView 有一个名为 scrollTo 的方法这让您可以滚动到内容的所需位置。
  2. 为了能够检测ScrollView 的当前位置,您需要使用onScroll。属性(property)。您可以将此属性与 scrollEventThrottle 结合使用以获得更好的准确性。
  3. 要获取每个项目在 ScrollView 中的位置,您需要实现 onLayout每个项目的属性。

下面是一个小示例应用程序,用于展示如何实现上述步骤。

const Item = props => (
  <View
    style={{ minHeight: 500 }}
    onLayout={e => props.onItemLayout(e, props.index)}>
    <Text>{`Item ${props.index}`}</Text>
  </View>
);

export default class App extends Component {
  constructor() {
    super();
    this.state = {
      sections: [1, 2, 3],
      currentSection: 1
    };
  }
  moveToSetion = section => {
    // scroll view to section
    this.scrollView.scrollTo({ x: 0, y: this.state[section], animated: true });
    // set state to current section
    this.setState({ currentSection: section });
  };
  onItemLayout = ({ nativeEvent: { layout: { x, y, width, height } } }, section) => {
    // setting each items position
    this.setState({ [section]: y });
  };
  onScroll = ({ nativeEvent: { contentOffset: { y, x } } }) => {
    let _currentSection;
    // loop sections to calculate which section scrollview is on
    this.state.sections.forEach((section) => {
      // adding 15 to calculate Text's height
      if((y + 15) > this.state[section]) _currentSection = section
    })
    // settint the currentSection to the calculated current section
    this.setState({ currentSection: _currentSection })
  }
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.buttonContainer}>
          {this.state.sections.map(section => (
            <Button
              key={section}
              title={`Section ${section}`}
              color={this.state.currentSection === section ? 'red' : 'blue'}
              onPress={() => this.moveToSetion(section)}
            />
          ))}
        </View>
        <ScrollView
          style={styles.scrollView}
          ref={ref => (this.scrollView = ref)}
          scrollEventThrottle={100}
          onScroll={this.onScroll}>
          {this.state.sections.map(section => (
            <Item
              key={section}
              index={section}
              onItemLayout={this.onItemLayout}
            />
          ))}
        </ScrollView>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
  },
  buttonContainer: {
    flexDirection: 'row',
    justifyContent: 'center',
    position: 'fixed',
    top: 0,
  },
  scrollView: {
    paddingLeft: 15,
    paddingRight: 15
  }
});

关于javascript - 如何在使用 ScrollView 的 native react 中实现 scrollspy?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50324412/

相关文章:

javascript - 具有三元运算符表达式的 AngularJS 过滤器

reactjs - 获取 react 组件的大小?

javascript - 在下拉列表中选择一个选项时,如何使用 onChange 更改状态但使用选项标签内的值以外的值

reactjs - RNIap.getProducts(itemSku) 返回空数组

react-native - 我是否使用通用代码库正确处理多个项目?

javascript - django 使用模板 View 和 ajax

javascript - 当我将鼠标悬停在 DIV 中的链接上时,我需要阻止 DIV 消失

javascript - 在 POST 和 DELETE 请求之前禁用 OPTIONS 请求

javascript - 如何将 readAsDataURL() 的值分配给变量?

Javascript - 使用 ESLINT 6 获取 json 数组的出现次数