React单页面Url路径及懒加载react-lazyload

昨天下午临时来了个活⬇️

做个移动端页面专题,页面开发的内容不多,但是做完之后有些分享链接上的需求,今天记录一下。


专题内容:

  • 首页:展示十五条线路内容
  • 详情页:每条线路的详情内容,图片、文字内容、电话信息

内容没什么好说的,很简单,敲页面就行了

首页:当天就要出,所以首页的十五条信息直接切了15张图
详情页:很丑的一个页面,swiper、flex布局,打电话调window.location.href = 'tel:' + phonenumber就行

思路

就两个页面,没必要用路由,直接用弹窗的形式position: absolute;就行把,开始敲~
详情页弹窗:弹之前记录当前页面位置(x,y),页面回顶部,这样详情页就是从头开始看了。关闭弹窗,页面回到之间记录的位置

相关代码:

// 详情页
function DetailPage(props){
	return (
		<div>......</div>
	)
}

class Qdxha extends Component{
	state = {
		//控制详情页的开关
		isopenDetail:false,
		// 记录位置
		scroll_y:0
	}
	
  	// 记录页面位置
  	recordposition(){
      this.setState({
      	scroll_y:window.scrollY
      },()=>{window.scrollTo(0,0)})
    }
    // 恢复页面位置
    restoreposition = ()=>{
    	const {scroll_y} = this.state
    	this.setState({isOpenDetail:false},()=>{window.scrollTo(0,scroll_y)})
   }

	render() {
		const {isOpenDetail} = this.state
		return (
			<div>
				<div>{"首页"}</div>
				{
					isopenDetail && <DetailPage props={"详情页内容参数"}/>
				}
			</div>
		)
	}
}

然后通过点击事件开启/关闭详情页,并把需要的数据传给详情页


okk,问题来了~~~

Q1:不管是首页还是十五条线路的详情页,url地址都是一样的。因为react是单页面应用,而且一开始并没有用路由的形式,然后嘞,甲方需要每个线路都有一个不同的地址(因为需要给每条线路弄一个二维码,直接扫码访问不同的详情页),okk,在原有基础上改~

思路:15条线路都有自己的“名字”,把它当成参数弄在Url里面,举例:https://www.服务器.cn/目录?page=“15条线路自己的名字”
然后,在componentDidMount钩子里判断url,如果是带参数的,直接就打开isopenDetail,让详情页弹出来。

注意注意哦~,这里判断url打开要在数据获取完之后呦~

相关代码

componentDidMount(){
    // 获取静态资源
    axios({
      url:"https://www.sdta.cn/json/m-topic/qdxha10line.json?t="+new Date().getTime(),
    })
    .then((res)=>{
      this.setState({
      	// 全部的数据
        allDetailContent:res.data,
        // 详情页数据,默认第一条线路数据
        detailShowContent:{...res.data.one}
		
		//回调,判断url
      },()=>{this.autoOpenDetail()})
    })
  }

autoOpenDetail(){
    const {allDetailContent} = this.state
    // 当前url
    let url = window.location.href
	//如果有参数
    if(url.includes("?")){
    	// 获取参数
        let params = url.split("?")[1].split("&")
        let obj = {}
        params.map(v => obj[v.split("=")[0]] = v.split("=")[1])
        // 打开详情弹窗,且赋值详情页数据
        this.setState({
        isOpenDetail:true,
        detailShowContent:{...allDetailContent[obj.page]}
      })
    }
    else return
  }

okk,这样打开带线路参数的url就能自动打开相对于的详情页了!!!


Q2:虽然每一页都有自己的url地址了,可以生成自己的二维码了!But,试想一下:如果打开的是首页,url地址是aaa.html,点击某条线路那现在的地址是什么,没错,地址还是aaa.html。这样不行呀,别人打开首页然后点到详情页,要分享详情页,那现在的地址得是aaa.html?page=“参数”。继续改!

思路:首页上的内容点击打开详情页就不要打开弹窗了,直接window.open()开一个新窗口,详情页(带参数)的窗口,正好Q1问题刚刚解决带参数问题

相关代码

openDetailPage = (page)=>{
  return ()=>{
  	// 当前url添加上详情页的参数
    let urlObj = new URL(window.location.href)
    urlObj.searchParams.append("page",page)
    let newUrl = urlObj.href
    window.open(newUrl,'_self')
  }
}

render() {
	const {isOpenDetail} = this.state
	return (
		<div>
			<div>{"首页"}
				<img src="" alt="" onClick={this.openDetailPage('详情页参数')} className="img_item"/>
			</div>
			{
				isopenDetail && <DetailPage props={"详情页内容参数"}/>
			}
		</div>
	)
	}

okk,这样就解决了Url的两个问题了。

Q3:唉,果然改了一个问题就会有其他的问题出现。那在详情页返回首页咋办了,来吧!

思路:之前的返回首页,就是把弹窗关上,现在肯定不行呀。那就是得浏览器的窗口问题了
1、如果是从首页过来了,窗口就window.history.back()
2、如果扫码或直接访问别人分享的链接,窗口就window.open("首页")
怎么判断呢,用浏览器历史页面栈的长度
唯一的优点就是不用像文章开头说的弹窗前记录当前页面的位置了

相关代码

restoreposition = ()=>{
  if(window.history.length<3){
    window.open(window.location.origin + window.location.pathname,'_self')
  }
  else {
    window.history.back()
  }
}

这里是做完的页面专题:https://www.sdta.cn/m-topic/qdxha/

Okk没啥问题了,优化一下别的地方吧,图片的懒加载react-lazyload

首页是15张图片,这也太难受了,不写点别点难受,用用懒加载吧!

npm地址
GitHub地址

相关代码

import LazyLoad from 'react-lazyload';
{
  图片数组.map(item=>{
    return (
      <LazyLoad once>
        <img src={item.url} alt="" onClick={this.openDetailPage(item.page)} className="img_item"/>
      </LazyLoad>
    )
  })
}

这里主要是用到了LazyLoad的两个参数

1、height

有关懒加载的内容,要理解占位符这个概念,有了占位符撑起来内容,代码才知道啥时候我该动态加载了

这里的height就是给占位符一个高度⬇️

// 这个类名是LazyLoad自己的
.lazyload-wrapper{
  height: rem(436);
}

这里的rem()是适配移动端尺寸的方法,参考另一篇文章—CSS3有关响应式的原理学习过程

2、once

懒加载内容只需要加载一次。
官方解释:Once the lazy loaded component is loaded, do not detect scroll/resize event anymore. Useful for images or simple components.
谷歌翻译:加载延迟加载的组件后,不再检测滚动/调整大小事件。 对于图像或简单组件很有用。


okk,在记一下遇到的小坑,没啥用!

  • 弹窗的形式——如果弹出的窗口高度不如首页的高度,那么弹窗最底部还会显示首页的内容。解决办法:打开弹窗后,将首页的内容高度设为0,超出隐藏。
  • 后期想了想,关于一开始打开弹窗前记录页面位置的代码,如果打开弹窗后就禁止首页的内容滚动是否可以,这样关闭弹窗后页面还是在原来的位置。
  • 详情页返回首页那里,通过页面栈的长度来判断总感觉不严谨,但是没有找到合适方法。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值