算法高级(10)-如何实现浏览器的前进、后退功能

一、引言

我们浏览网页,会发现“前进”和“后退”是 Web 浏览器的常用功能,实现该功能的一种方式是使用两个栈(backward 栈和forward 栈)来存储用户访问的网址,用户的不同操作对应的具体实现方法如下:

  • 后退(BACK):如果backward 栈为空,则该命令被忽略。否则,将当前页面压入forward栈,并从backward 栈中弹出一个页面作为当前页面。
  • 前进(FORWARD):如果forward 栈为空,则该命令被忽略。否则,将当前页面压入backward 栈,并从forward 栈中弹出一个页面作为当前页面。
  • 访问某网址(VISIT <URL>):将当前页面压入backward 栈,并将此次访问的网页作为当前页面,清空forward 栈。

二、整体思路

根据栈结构后进先出的顺序,我们很容易想到,可以把用户当前浏览的网页入栈,当用户在新界面点击回退按钮的时候,直接让栈顶元素出栈,让浏览器加载,不就实现了后退功能了吗?前进的功能也类似,于是乎,我们想到用两个栈分别存储在用户当前浏览网页之前/之后的所有页面地址。理想的结构(BackStack回退栈,ForwardStack前进栈),如下图所示:

三、c++实现代码

#include<iostream>
#include<string>
#include<stack>
using namespace std;
int main(){
 stack<string> backward,forward;
 string now,b,c="csw.jlu.edu.cn";
 while(1){
  cin>>b;
  if(b=="VISIT"){
   cin>>now;
   cout<<now<<endl;
   backward.push(c);
   while(!forward.empty()){
    forward.pop();
   }
  }
  if(b=="BACK"){
   if(backward.size()!=0){
    c=backward.top();
    backward.pop();
    cout<<c<<endl;
    forward.push(now);
    now=c;
   }
   else{
    cout<<"Ignored"<<endl;
    c="csw.jlu.edu.cn";
   }
  }
  if(b=="FORWARD"){
   if(forward.size()!=0){
    c=forward.top();
    forward.pop();
    cout<<c<<endl;
    backward.push(now);
    now=c;
   }
   else{
    cout<<"Ignored"<<endl;
   }
  }
  if(b=="QUIT"){
   break; 
  }
  if(b!="VISIT"&&b!="BACK"&&b!="FORWARD"&&b!="QUIT"){
   cout<<"输入错误!"<<endl;
  }
 } 
}

四、页面按钮实现的前进后退

<input type=button value=刷新 onclick="window.location.reload()"> 
<input type=button value=前进 onclick="window.history.go(1)"> 
<input type=button value=后退 onclick="window.history.go(-1)"> 
<input type=button value=前进 onclick="window.history.forward()"> 
<input type=button value=后退 onclick="window.history.back()"> 
<input type=button value=后退并刷新  onclick="window.history.go(-1);window.location.reload()">

下面是history源码,有没有什么发现呢?

interface History {
    readonly length: number;
    scrollRestoration: ScrollRestoration;
    readonly state: any;
    back(distance?: any): void;
    forward(distance?: any): void;
    go(delta?: any): void;
    pushState(data: any, title?: string, url?: string | null): void;
    replaceState(data: any, title?: string, url?: string | null): void;
}

五、总结

  1. 此面试题在安卓面试中出现比较多。
  2. history对象的存储结构与栈相同,先进后出。

我的微信公众号:架构真经(id:gentoo666),分享Java干货,高并发编程,热门技术教程,微服务及分布式技术,架构设计,区块链技术,人工智能,大数据,Java面试题,以及前沿热门资讯等。每日更新哦!

参考资料:

  1. https://blog.csdn.net/qq_39187019/article/details/86555730
  2. https://blog.csdn.net/mgsky1/article/details/71036856

 

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

十步杀一人_千里不留行

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

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

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

打赏作者

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

抵扣说明:

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

余额充值