angular页面返回保持页面原状

描述:

当我们是需求是返回页面时要保持页面在离开时的样子,这里会有两个方面的考虑,一个是路由一定要设置复用策略,然后发现当页面有列表的时候,那就肯定有滚动条,当离开页面前操作了列表滚动到了若干页的随机位置,当返回的时候即使复用路由策略生效,但是发现列表会自动滚到最顶部位置,也就是说列表位置变了
通过以上情况要实现返回页面保持原状态
1.路由复用,不重新加载,不走重建销毁的这个过程
2.解决列表list不会保持到原来浏览位置

解决路由复用策略问题

前面有专门针对路由策略做过笔记,实现angular路由复用策略
这里就不过多赘述了

熟悉三大家族

提到滚动该条很容易想到关于滚动条scroll相关的属性,scroll家族有4个属性,分别为scrollWidth、scrollHeight、scrollLeft、scrollTop,下面回忆复习一下相关含义
1、offset偏移量


offset.png

有以下常用属性
offsetWidth/offsetHeight:表示元素盒子的宽度和高度,包含border和padding ;
offsetLeft/offsetRight/offsetTop:表示是外边距,元素距离其他元素多少距离
offsetParent:表示获取父元素,如果父元素有用positon样式属性定位,那么获取的就是最近的父元素,如果没有用positon样式属性的,那么获取的是body
parentNode:获取的是最近父元素。

以上属性注意点

  • 获取到的值是一个number类型,不带单位
  • 获取的宽高包含border和padding
  • 只能读取,不能设置

2、client偏移量


image.png

clientWidth/clientHieght:元素的可是区域的宽高,包括内边距padding,不包括border;
clientLeft/clientTop:记录的是元素的border的距离
注意:
*只读属性,不可修改

3、scroll偏移量


image.png

scrollTop/scrollLeft:元素划出去的距离;
scrollWidht/scrollHeight:子元素的宽高
注意:
*scrollWidth/scrollHeight:是只读属性,不可编辑的

  • scrollTop/scrollLeft: 是可以编辑赋值的
    以上熟悉了一些属性,接下来的我们要使用的属性是scoll家族

解决返回时滚动条位置发生变化问题

image.png

如上图所示,返回时,我们A页面的参数count为10,说明返回时,路由复用策略生效,页面并没有调用ngOninit()初始化,但是滚动条却默认回到最初的位置,查询了很多有关angular的特性,并没有针对路由复用时滚动条变化相关的解决办法,那这里索性用最原生的scroll属性来控制列表list的滚动条位置,打算这样做,
1.页面中监听滚动元素,当列表滚动时,把滚动的距离保存下来,也就是scrollTop属性值
2.当页面返回时,我们再读取先前保存下来的scrollTop,然后赋值给元素
以上是解决返回页面保持滚动条不变的解决思路

import { GlobalSubscriptionService } from './../../services/global-subscription.service';
import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { Component, OnInit, ViewChild, ElementRef, Renderer2, AfterViewInit } from '@angular/core';

@Component({
  selector: 'app-route-strategy',
  templateUrl: './route-strategy.component.html',
  styleUrls: ['./route-strategy.component.scss']
})
export class RouteStrategyComponent implements OnInit, AfterViewInit {
  @ViewChild('content', { static: true }) content: ElementRef | any;
  public index: number = 0;
  constructor(
    private $http: HttpClient,
    private $router: Router,
    private $globalSub: GlobalSubscriptionService,
    private renderer: Renderer2
  ) { }

  ngOnInit(): void {
    /**返回时ngOnInit是不会重新加载的,所以我们这里要用到路由Router的订阅,路由进来时进行相关操作*/
    this.$router.events.subscribe(res => {
      let scrollTop = localStorage.getItem('list-scroll') || 0;
      this.content.nativeElement.scrollTop = scrollTop;
    })
  }

  ngAfterViewInit(): void {
    /**用Renderer2中方法的监听元素*/
    this.renderer.listen(this.content.nativeElement, 'scroll', res => {
      localStorage.setItem('list-scroll', res.target.scrollTop);
    })

  }
  public onAdd(): void {
    this.index++;
  }

  public onJump(): void {
    this.$globalSub.$routeIsReuse.next({ field: `/route-strategy/route-strategy-first`, value: false });
    this.$router.navigate(['/route-strategy/route-strategy-first'])
  }
}
image.png

此时不仅页面没有重新加载,连列表list的滚动条位置也没有发生变化,这里用了Renderer2中的listen方法监听元素的scroll事件,这是官方推荐的用法,当list滑动时,先把scollTop存浏览器缓存,再次进入页面时,需要在ngOninit中订阅一下路由,因为此时的页面不会重新加载任何东西,只有订阅才可以进行相关操作,此时去获取缓存中的scrollTop,并且对元素进行设置。

总结

1.先弄清楚angular路由复用策略机制,进行相应的配置,这个配置是很灵活的,根据需求配置
2.通过原生的scrollTop属性来控制列表滑动位置,这个是要手动设置,先存再设置

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 081.什么是 Polyfill ? Polyfill 指的是用于实现浏览器并不支持的原生 API 的代码。 比如...
    造了个轮子阅读 334评论 0 0
  • webpack相关 https://blog.csdn.net/sinat_17775997/article/de...
    蛋挞xjc阅读 618评论 0 1
  • 前端目录 HTML相关 CSS相关 JAVASCRIPT相关 DOM相关 HTTP相关 VUE相关 算法相关 网络...
    keyuan0214阅读 459评论 0 2
  • Vue返回记住滚动条位置 vue 项目返回上一页,滚动到离开时的位置,网上能找到不少方法,以下尝试一种。 一共分三...
    zsyyyyy阅读 3,003评论 0 0
  • 返回页面顶部的几种方式: 第一种: 实验代码如图: 第二种方式: 返回顶部 实验方法如图: 第三种:可以通过给页面...
    houxnan阅读 2,804评论 0 0