【创新实训】前端开发记录(三):特殊效果

山软创新实训前端开发记录

【创新实训】前端开发记录(一):基础篇
【创新实训】前端开发记录(二):主页面
【创新实训】前端开发记录(三):特殊效果



渐变标题栏

效果描述

电影详情展示页的标题栏会随着页面的向下滚动,颜色逐渐由半透明变为不透明。类似于Material DesignCollapsingToolbarLayout的效果。
滚动效果

实现思路

如下图的红色框部分的高度是设定的,为300px。我们只需要让标题栏在滚动到300px时改变它的颜色即可。红框部分的模糊背景可以使用CSS中的filter: blur进行模糊即可。
布局

代码实现

滚动触发器

Material-UI提供了useScrollTrigger函数钩子来监听页面滚动事件。我们只需要设定这个监听器的触发阈值为300px即可。

const trigger = useScrollTrigger({
  disableHysteresis: true,
  threshold: 300,
  target: window ? window() : undefined,
});

trigger会返回一个布尔值,用来表示页面是否滚动超过了阈值。根据此布尔值我们调整AppBarclass即可。

return React.cloneElement(children, { className: trigger ? classes.appBar : classes.transAppBar });

样式部分的设定如下。为了增加渐变的效果,我们给定AppBartransition为500ms。

appBar: {
    width: '100%',
    backgroundColor: '#3f51b5',
    transition: '500ms'
},
transAppBar: {
    width: '100%',
    backgroundColor: 'rgba(0, 0, 0, 0.3)',
    transition: '500ms'
}

主页搜索状态保存

在之前的版本中,主页搜索栏和列表翻页的状态是无法保存的,即打开了详情页后再返回主页,数据都会被重置。要解决这个问题有两种解决方案:

  1. 详情页在新标签页中打开
  2. 跳转前保存主页状态,返回时再恢复

方案1较为简单,只需在a元素中加上target="_blank"属性即可。但方案一带来的缺点就是,在详情页的推荐或历史记录中打开新的电影详情页,将会导致过多的标签页被打开,严重影响性能(尤其是对于一个标签页占用一个进程的浏览器来说)。
方案2较为负责,但使用体验很好,所有操作只需在一个标签页中即可完成。

实现思路

手动处理页面跳转。在跳转前先将主页的状态保存至localStorage,再次返回主页时先检查localStorage中是否有保存的状态,如有则取出,否则使用默认状态。

代码实现

首先是localStorage的封装工具,提供存储和取出的操作。在执行取出操作后,将localStorage中保存的状态删除,以免造成重进主页状态无法恢复的BUG。

export const storeState = (state, id = 'home') => {
    localStorage.setItem('state_util_' + id, JSON.stringify(state))
}

export const fetchState = (id = 'home') => {
    var data = localStorage.getItem('state_util_' + id) ?? '{}'
    localStorage.removeItem('state_util_' + id)
    return JSON.parse(data)
}

在主页面的componentDidMount()方法中进行状态取出和恢复。

componentDidMount() {
  var tmpState = fetchState()
  if (Object.keys(tmpState).length > 0) {
    this.setState(tmpState)
  } else {
    this.doSearch(this.state.searchData);
  }
}

再手动处理下详情页的跳转。在列表页的代码中,取消Link的to属性,使用onClick属性调用我们自己的函数处理跳转。

const handleClick = (history, id) => {
  storeState(this.state)
  history.replace('/detail/' + id)
}

const pushDetail = (handleClick, history, id, home = false) => {
    if (!home) {
        // 非主页点击,直接跳转就行
        history.replace('/detail/' + id)
    } else {
        handleClick(history, id)
    }
}
<div
    className={classes.hoverCover}
    onClick={() => pushDetail(...)}>
    ...
</div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nullptrjzz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值