2-9 回到顶部功能

回到顶部的功能,因为代码量很少,因此就不将他单独拆分为一个js 文件了。我们在src/pages/home 下的index 中写它。

index 如下。

import React, {Component} from 'react';
import { connect } from 'react-redux';
import {HomeWrapper, HomeLeft, HomeRight, BackTop } from './style';
import List from './components/List';
import Recommend from './components/Recommend';
import Topic from './components/Topic';
import Writer from './components/Writer';
import bannerImage from '../../statics/ooo.jpg';
import { actionCreators } from './store';

class Home extends Component {
    render () {
        return (
            <HomeWrapper>
                <HomeLeft>
                    <img
                        className="banner-img"
                        src={bannerImage}
                        alt=''
                    />
                    <Topic></Topic>
                    <List></List>
                </HomeLeft>
                <HomeRight>
                    <Recommend></Recommend>
                    <Writer></Writer>
                </HomeRight>
                <BackTop>回到顶部</BackTop>
            </HomeWrapper>
        )
    }
    componentDidMount () {
        this.props.changeHomeData();
    }
}

const mapDispatch = (dispatch) => {
    return {
        changeHomeData () {
            const action = actionCreators.getHomeInfo();
            dispatch(action);
        }
    }
}
export default connect(null, mapDispatch)(Home);

然后在 style.js 中定义一下,如下。

然后在 index 中定义一下点击“顶部” 的click 事件,如下。

import React, {Component} from 'react';
import { connect } from 'react-redux';
import {HomeWrapper, HomeLeft, HomeRight, BackTop } from './style';
import List from './components/List';
import Recommend from './components/Recommend';
import Topic from './components/Topic';
import Writer from './components/Writer';
import bannerImage from '../../statics/ooo.jpg';
import { actionCreators } from './store';

class Home extends Component {
    handleScrollTop () {
        window.scrollTo(0,0);
    }
    render () {
        return (
            <HomeWrapper>
                <HomeLeft>
                    <img
                        className="banner-img"
                        src={bannerImage}
                        alt=''
                    />
                    <Topic></Topic>
                    <List></List>
                </HomeLeft>
                <HomeRight>
                    <Recommend></Recommend>
                    <Writer></Writer>
                </HomeRight>
                <BackTop onClick={this.handleScrollTop}>顶部</BackTop>
            </HomeWrapper>
        )
    }
    componentDidMount () {
        this.props.changeHomeData();
    }
}

const mapDispatch = (dispatch) => {
    return {
        changeHomeData () {
            const action = actionCreators.getHomeInfo();
            dispatch(action);
        }
    }
}
export default connect(null, mapDispatch)(Home);

然后,再实现一下,在页面回到顶部的时候,这个小组件就没了,往下翻就会出现。

这个我们通过一个变量保存,它的出现和隐藏。打开 src/pages/home/store 下的 reducer

import { fromJS } from 'immutable';
import * as actionTypes from './actionTypes';

const defaultState = fromJS({
    topicList: [],
    articleList: [],
    recommendList: [],
    articlePage: 1,
    showScroll: false
});

export default (state = defaultState, action) => {
    switch (action.type) {
        case actionTypes.CHANGE_HOME_DATA:
            return state.merge({
                "topicList": fromJS(action.topicList),
                "articleList": fromJS(action.articleList),
                "recommendList": fromJS(action.recommendList)
            });
        case actionTypes.ADD_ARTICLE_LIST:
            return state.merge({
                "articleList": state.get("articleList").concat(action.articleList),
                "articlePage": action.page
            })
        default:
            return state;
    }
}

然后,我们在src/pages/home 下的 index 中做初始化,如下。

import React, {Component} from 'react';
import { connect } from 'react-redux';
import {HomeWrapper, HomeLeft, HomeRight, BackTop } from './style';
import List from './components/List';
import Recommend from './components/Recommend';
import Topic from './components/Topic';
import Writer from './components/Writer';
import bannerImage from '../../statics/ooo.jpg';
import { actionCreators } from './store';

class Home extends Component {
    handleScrollTop () {
        window.scrollTo(0,0);
    }
    render () {
        return (
            <HomeWrapper>
                <HomeLeft>
                    <img
                        className="banner-img"
                        src={bannerImage}
                        alt=''
                    />
                    <Topic></Topic>
                    <List></List>
                </HomeLeft>
                <HomeRight>
                    <Recommend></Recommend>
                    <Writer></Writer>
                </HomeRight>
                {this.props.showScroll ? <BackTop onClick={this.handleScrollTop}>顶部</BackTop> : null }
            </HomeWrapper>
        )
    }
    componentDidMount () {
        this.props.changeHomeData();
    }
}

const mapState = (state) => {
    return {
        showScroll: state.get("home").get("showScroll")
    }
}
const mapDispatch = (dispatch) => {
    return {
        changeHomeData () {
            const action = actionCreators.getHomeInfo();
            dispatch(action);
        }
    }
}
export default connect(mapState, mapDispatch)(Home);

上面我们只是把初始进来的时候隐藏“顶部” 按钮。下面,我们来写,当页面不是顶部的时候,显示“顶部”按钮。如下是 index。

import React, {Component} from 'react';
import { connect } from 'react-redux';
import {HomeWrapper, HomeLeft, HomeRight, BackTop } from './style';
import List from './components/List';
import Recommend from './components/Recommend';
import Topic from './components/Topic';
import Writer from './components/Writer';
import bannerImage from '../../statics/ooo.jpg';
import { actionCreators } from './store';

class Home extends Component {
    handleScrollTop () {
        window.scrollTo(0,0);
    }
    render () {
        return (
            <HomeWrapper>
                <HomeLeft>
                    <img
                        className="banner-img"
                        src={bannerImage}
                        alt=''
                    />
                    <Topic></Topic>
                    <List></List>
                </HomeLeft>
                <HomeRight>
                    <Recommend></Recommend>
                    <Writer></Writer>
                </HomeRight>
                {this.props.showScroll ? <BackTop onClick={this.handleScrollTop}>顶部</BackTop> : null }
            </HomeWrapper>
        )
    }
    componentDidMount () {
        this.props.changeHomeData();
        this.bindEvents();
    }
    bindEvents() {
        window.addEventListener("scroll", this.props.changeScrollTopShow);
    }
}

const mapState = (state) => {
    return {
        showScroll: state.get("home").get("showScroll")
    }
}
const mapDispatch = (dispatch) => {
    return {
        changeHomeData () {
            const action = actionCreators.getHomeInfo();
            dispatch(action);
        },
        changeScrollTopShow () {
            console.log();
            if ( document.documentElement.scrollTop > 100) {
                dispatch(actionCreators.toggleShowScroll(true));
            } else {
                dispatch(actionCreators.toggleShowScroll(false));
            }
        }
    }
}
export default connect(mapState, mapDispatch)(Home);

然后在 actionCreators 中添加 toogleShowScroll 

import axios from 'axios';
import { fromJS } from 'immutable';
import * as actionTypes from './actionTypes';

const changeHomeData = (result) => ({
    type: actionTypes.CHANGE_HOME_DATA,
    topicList: result.topicList,
    articleList: result.articleList,
    recommendList: result.recommendList
});

const addHomeList = (result, page) => ({
    type: actionTypes.ADD_ARTICLE_LIST,
    articleList: fromJS(result.articleList),
    page: page
})

export const getHomeInfo = () => {
    return (dispatch) => {
        axios.get("/api/home.json").then((res) => {
            const result = res.data.data;
            const action = changeHomeData(result);
            dispatch(action);
        });
    }
}

export const getMoreList = (page) => {
    return (dispatch) => {
        axios.get("/api/homeList.json?page=" + page).then((res) => {
            const result = res.data.data;
            const action = addHomeList(result, page + 1);
            dispatch(action);
        })
    }
}

export const toggleShowScroll = (show) => ({
    type: actionTypes.TOGGLE_SCROLL_SHOW,
    show: show
})

最后,往 reducer 中添加一个case

import { fromJS } from 'immutable';
import * as actionTypes from './actionTypes';

const defaultState = fromJS({
    topicList: [],
    articleList: [],
    recommendList: [],
    articlePage: 1,
    showScroll: false
});

export default (state = defaultState, action) => {
    switch (action.type) {
        case actionTypes.CHANGE_HOME_DATA:
            return state.merge({
                "topicList": fromJS(action.topicList),
                "articleList": fromJS(action.articleList),
                "recommendList": fromJS(action.recommendList)
            });
        case actionTypes.ADD_ARTICLE_LIST:
            return state.merge({
                "articleList": state.get("articleList").concat(action.articleList),
                "articlePage": action.page
            });
        case actionTypes.TOGGLE_SCROLL_SHOW:
            return state.set("showScroll", action.show);
        default:
            return state;
    }
}

注意一点,我们在index 中写的是,当组件挂载后,会往 window 中绑定一个scroll 事件。我们一定别忘记了,当这个组件被从页面移除的时候,一定要把window 的scroll 事件也移除。

import React, {Component} from 'react';
import { connect } from 'react-redux';
import {HomeWrapper, HomeLeft, HomeRight, BackTop } from './style';
import List from './components/List';
import Recommend from './components/Recommend';
import Topic from './components/Topic';
import Writer from './components/Writer';
import bannerImage from '../../statics/ooo.jpg';
import { actionCreators } from './store';

class Home extends Component {
    handleScrollTop () {
        window.scrollTo(0,0);
    }
    render () {
        return (
            <HomeWrapper>
                <HomeLeft>
                    <img
                        className="banner-img"
                        src={bannerImage}
                        alt=''
                    />
                    <Topic></Topic>
                    <List></List>
                </HomeLeft>
                <HomeRight>
                    <Recommend></Recommend>
                    <Writer></Writer>
                </HomeRight>
                {this.props.showScroll ? <BackTop onClick={this.handleScrollTop}>顶部</BackTop> : null }
            </HomeWrapper>
        )
    }
    componentDidMount () {
        this.props.changeHomeData();
        this.bindEvents();
    }
    bindEvents() {
        window.addEventListener("scroll", this.props.changeScrollTopShow);
    }
    componentWillUnmount () {
        window.removeEventListener("scroll", this.props.changeScrollTopShow);
    }
}

const mapState = (state) => {
    return {
        showScroll: state.get("home").get("showScroll")
    }
}
const mapDispatch = (dispatch) => {
    return {
        changeHomeData () {
            const action = actionCreators.getHomeInfo();
            dispatch(action);
        },
        changeScrollTopShow () {
            console.log();
            if ( document.documentElement.scrollTop > 100) {
                dispatch(actionCreators.toggleShowScroll(true));
            } else {
                dispatch(actionCreators.toggleShowScroll(false));
            }
        }
    }
}
export default connect(mapState, mapDispatch)(Home);

Done.

猜你喜欢

转载自blog.csdn.net/purple_lumpy/article/details/89315669
2-9