精华内容
下载资源
问答
  • 使用栈实现浏览器的前进后退当你一次访问 1、2、3 页面之后,点击浏览器的后退按钮就可以返回到 2 和 1.当后退到 1,点击前进按钮还可以继续查看页面 2、3。但是当你退到 2 页面,点击了新的页面 4,那就无法继续...

    使用栈实现浏览器的前进后退

    当你一次访问 1、2、3 页面之后,点击浏览器的后退按钮就可以返回到 2 和 1.当后退到 1,点击前进按钮还可以继续查看页面 2、3。但是当你退到 2 页面,点击了新的页面 4,那就无法继续通过前进、后退查看页面 3 了。

    「我们如何实现这个功能呢?」

    什么是栈

    「栈」我们都知道 Java 虚拟机 JVM 就有『本地方法栈』『虚拟机栈』的划分,每个方法执行的时候都会创建一个栈帧用于存放局部变量表、操作数栈、动态链接、方法出口信息。

    每一个方法从调用到结束,就对应着一个栈帧在「虚拟机栈」的入栈与出栈的过程。这里其实就是运用了「栈」数据结构的特性:「后进先出、先进后出」。就像一摞叠在一起的盘子,入栈就像我们放盘子,出栈就是我们从上往下一个个取。

    693489a5a9575074a2a842e29539dcc6.png

    「栈是一种「操作受限」的线性表」,只允许在一端插入和删除数据。

    是不是觉得这种数据结构有何意义,只有受限的操作,相比「数组」和「链表」感觉没有任何优势。为何还要用这个「操作受限」的「栈」呢?

    特定的数据结构用在特定的场景,数组与链表暴露太多的操作接口,操作灵活带来的就是不可控,也就更加容易出错。

    「当某个数据集合只涉及在一端插入和删除数据,并且满足后进先出、先进后出的特性,我们就应该首选“栈”这种数据结构」。

    比如我们的 JVM 栈结构,方法调用则是对应的入栈与出栈。

    栈的实现

    核心操作就是「入栈」「出栈」,也就是在栈顶插入元素、从栈顶取出元素。

    理解了两个核心操作后,我们可以使用数组或者链表来实现。

    数组实现的栈,叫做 「顺序栈」 。

    用链表实现,叫做 「链式栈」。

    这里我通过数组实现一个顺序栈,可用于实际开发中,我拓展了「清空栈」、「拓容」、「构建默认大小与最大限制」。代码我放在 GitHub https://github.com/UniqueDong/algorithms.git上,自己撸一遍,再对比下是否写的正确。

    这里不仅仅作为一个 示例,我的例子还考虑了栈默认初始大小以及最大限制,当超过默认大小但是还没有达到最大限制的时候,还需要扩容操作。

    import java.util.Arrays;

    /**

    * 基于数组实现的栈

    * @param 

    */

    public class ArrayStack {

    /**

    * 默认大小

    */

    public static final int DEFAULT_SIZE = 128;

    /**

    * 默认最大限制,-1 表示无限制

    */

    private static final int DEFAULT_LIMIT = -1;

    /**

    * 初始化栈大小

    */

    private int size;

    /**

    * 栈最大限制数,-1 表示无限制

    */

    private final int limit;

    /**

    * 指向栈顶元素的下标,默认没有数据 -1

    */

    private int index;

    /**

    * 保存数据

    */

    private Object[] stack;

    /**

    * 默认构造方法,创建一个 128 大小,无限制数量的栈

    */

    public ArrayStack() {

    this(DEFAULT_SIZE, DEFAULT_LIMIT);

    }

    // 指定大小与最大限制的栈

    public ArrayStack(int size, int limit) {

    this.index = -1;

    if (limit > DEFAULT_LIMIT && size > limit) {

    this.size = limit;

    } else {

    this.size = size;

    }

    this.limit = limit;

    this.stack = new Object[size];

    }

    /**

    * push obj to stack of top

    *

    * @param obj push data

    * @return true if push success

    */

    public boolean push(T obj) {

    index++;

    // 当下标达到 size,说明需要拓容了。判断是否需要拓容

    if (index == size) {

    // 若超过限制则返回 false,否则执行拓容

    if (limit != DEFAULT_LIMIT && size >= limit) {

    index--;

    return false;

    } else {

    // 拓容

    expand();

    }

    }

    stack[index] = obj;

    return true;

    }

    /**

    * pop stack of top element

    *

    * @return top of stack element

    */

    public T pop() {

    if (index == -1) {

    return null;

    }

    T result = (T) stack[this.index];

    stack[index--] = null;

    return result;

    }

    /**

    * 清空栈数据

    */

    public void clear() {

    // 判断是否空

    if (index > -1) {

    // 只需要将 index + 1 个元素设置 null,不需要遍历 size

    for (int i = 0; i 

    stack[i] = null;

    }

    }

    index = -1;

    }

    public int size() {

    return this.index + 1;

    }

    @Override

    public String toString() {

    return "ArrayStack{" +

    "size=" + size +

    ", limit=" + limit +

    ", index=" + index +

    ", stack=" + Arrays.toString(stack) +

    '}';

    }

    }

    复制代码

    我们来分析下「栈」的空间复杂度与实践复杂度。

    在「入栈」「出栈」的操作中,存储数据都是只需要一个 最大限制 n 的数组,所以空间复杂度是 O(1)。

    存储数据为 n 大小的数组,不是说空间复杂度是 O(n),这里一定要注意。因为 这个 n 是必须的,无法省。当我们说空间复杂度的时候,指的是除原本数据存储空间外,算法还需要额外的那部分存储空间。

    不管是链式栈还是顺序栈,出栈与入栈只是设计栈顶个别数据的操作,只是需要拓容的时候会 O(n),但是均摊以后最后还是 O(1)。

    所以栈的时间与空间复杂度都是 O(1)。

    拓容实现

    当容量达到指定默认值大小的时候再入栈数据则需要拓容知道拓容到最大限制大小。

    数组拓容可以通过 System.arraycopy(stack, 0, newStack, 0, size); 当空间不足的时候申请原数组两倍大小的数组,然后把原始数据复制到新数组中。

    b085eadd0d364df013c574c15db5d3ef.png拓容

    /**

    * 扩容两倍 ,若是两倍数值超过 limit 则只能拓容到 limit

    */

    private void expand() {

    int newSize = size * 2;

    if (limit != DEFAULT_LIMIT && newSize > limit) {

    newSize = limit;

    }

    Object[] newStack = new Object[newSize];

    System.arraycopy(stack, 0, newStack, 0, size);

    this.stack = newStack;

    this.size = newSize;

    }

    复制代码

    栈的应用场景

    经典的应用场景就是 「函数调用栈」。

    操作系统给每个线程分配了一块独立的内存空间,这块内存被组织成“栈”这种结构, 用来存储函数调用时的临时变量。每进入一个函数,就会将临时变量作为一个栈帧入栈,当被调用函数执行完成,返回之后,将这个函数对应的栈帧出栈。

    表达式求值

    为了方便解释,我将算术表达式简化为只包含加减乘除四则运算,比如:34+13*9+44-12/3 。 对于这个四则运算,我们人脑可以很快求解出答案,但是对于计算机来说,理解这个表达式本身就是个挺难的事儿。如果换作你,让你来实现这样一个表达式求值的功能,你会怎么做呢?

    实际上编译器就是通过两个栈实现的。一个保存操作数的栈、一个则保存操作运算符的栈。

    我们从左向右遍历表达式,当遇到数字,我们就直接压入操作数栈;当遇到运算符,就与运算符栈的栈顶元素进行比较。

    如果比运算符栈顶元素的优先级高,就将当前运算符压入栈;如果比运算符栈顶元素的优先级低或者相同,从运算符栈中取栈顶运算符,从操作数栈的栈顶取 2 个操作数,然后进行计算,再把计算完的结果压入操作数栈,继续比较。如下图所示

    1f943f484e2e1007e5ff4bf73124d8ee.png

    浏览器后退前进

    我们使用两个栈,X 和 Y,我们把首次浏览的页面依次压入栈 X,当点击后退按钮时,再依次从栈 X 中出栈,并将出栈的数据依次放入栈 Y。当我们点击前进按钮时,我们依次从栈 Y 中取出数据,放入栈 X 中。当栈 X 中没有数据时,那就说明没有页面可以继续后退浏览了。当栈 Y 中没有数据,那就说明没有页面可以点击前进按钮浏览了。

    比如你顺序查看了 a,b,c 三个页面,我们就依次把 a,b,c 压入栈,这个时候,两个栈的数据就是这个样子:

    977a01c959ae89a685db11f03612e724.png

    点击后退,从页面 c 后退到页面 a 之后,我们就依次把 c 和 b 从栈 X 中弹出,并且依次放入到栈 Y。这个时候,两个栈的数据就是这个样子:

    63af5efdb8a96fe5557eb8caa0b997b6.png

    这时候想看 b,于是你又点击前进按钮回到 b 页面,我们就把 b 再从栈 Y 中出栈,放入栈 X 中。此时两个栈的数据是这个样子:

    5b8c52d81a341043a1573896a07a8d23.png

    这个时候,你通过页面 b 又跳转到新的页面 d 了,页面 c 就无法再通过前进、后退按钮重复查看了,所以需要清空栈 Y。此时两个栈的数据这个样子:

    f343cc7367c9e9d81db36345ceb4ea31.png

    通过来两个栈来操作,快速的实现了前进后退。

    由于篇幅原因,具体实现代码我们下文再撸,关注我一手掌握最新文章。

    推荐阅读

    1.跨越数据结构与算法

    2.时间复杂度与空间复杂度

    3.最好、最坏、平均、均摊时间复杂度

    4.线性表之数组

    5.链表导论-心法篇

    6.单向链表正确实现方式

    7.双向链表正确实现

    原创不易,觉得有用希望读者随手「在看」「收藏」「转发」三连。

    本文使用 mdnice 排版

    展开全文
  • 通过了解下面的一些例子,并运用到你的WEB中,不久你马上成为JAVASCIPT的高手。例(一)、在运维例(二)、在页面加入文档最后修改日期< script language='JavaScript' >document.write('本页最后编辑日期:');...

    通过了解下面的一些例子,并运用到你的WEB中,不久你马上成为JAVASCIPT的高手。例(一)、在运维

    例(二)、在页面加入文档最后修改日期

    < script language='JavaScript' >

    document.write('本页最后编辑日期:');

    document.write(document.lastModified)

    例(三)、在窗口的状态提示窗显示移动信息

    (1) 在BODY之前

    < script language='JavaScript' >

    var msg='这是一个状态行滚动显示的JAVASCIPT程序,有兴趣的同志,可以粘贴!';

    var i=1

    function scroll()

    {

    mess=msg.substring(i,msg.length)+' '+msg.substring(0,i)

    window.status=mess

    i++;

    if (i>=msg.length) i=1;

    setTimeout('scroll()',200);

    }

    (2)在BODY标签中:

    通过以上两步即可完成。

    例(四)、提供前进、后退功能

    < form >

    < input type='button' value='

    οnclick='history.go(-1) >

    < input type='button' value='->'

    οnclick='history.go(1) >

    < /form >

    例(五)、在页面加入文档最后修改日期

    < script language='JavaScript' >

    document.write('本页最后编辑日期:');

    document.write(document.lastModified)

    例(六)、鼠标移到时发生动作

    < A HREF='MAILTO:ZZY71616@163.NET'

    οnmοuseοver='alert('写信给我');

    return true' > 信箱< /A >

    例(七)、提供前进、后退功能

    < H3 οnclick='history.go(-1)' > 前一页< /H3>

    < H3 οnclick='history.go(-2)' > 前两页< /H3>

    < H3 οnclick='history.go(-3)' > 前三页< /H3>

    < H3 οnclick='history.go(1)' > 后一页< /H3>

    < H3 οnclick='history.go(2)' > 后两页< /H3>

    < H3 οnclick='history.go(3)' > 后三页< /H3>

    本文由来源 21aspnet,由 system_mush 整理编辑,其版权均为 21aspnet 所有,文章内容系作者个人观点,不代表 Java架构师必看 对观点赞同或支持。如需转载,请注明文章来源。

    展开全文
  • 1. 需求如果要你实现一个前端路由,应该如何实现浏览器的前进后退 ?2. 问题首先浏览器中主要有这几个限制,让前端不能随意的操作浏览器的浏览纪录:•没有提供监听前进后退的事件。•不允许开发者读取浏览纪录,...

    1. 需求

    如果要你实现一个前端路由,应该如何实现浏览器的前进与后退 ?

    2. 问题

    首先浏览器中主要有这几个限制,让前端不能随意的操作浏览器的浏览纪录:

    •没有提供监听前进后退的事件。•不允许开发者读取浏览纪录,也就是 js 读取不了浏览纪录。•用户可以手动输入地址,或使用浏览器提供的前进后退来改变 url。

    所以要实现一个自定义路由,解决方案是自己维护一份路由历史的记录,从而区分 前进、刷新、回退。

    下面介绍具体的方法。

    3. 方法

    目前笔者知道的方法有两种,一种是 在数组后面进行增加与删除,另外一种是 利用栈的后进先出原理。

    我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我并添加我的web前端交流裙【六零零】+【六一零】+【一五一】,即可免费获取。

    3.1 在数组最后进行 增加与删除

    通过监听路由的变化事件 hashchange,与路由的第一次加载事件 load ,判断如下情况:

    •url 存在于浏览记录中即为后退,后退时,把当前路由后面的浏览记录删除。•url 不存在于浏览记录中即为前进,前进时,往数组里面 push 当前的路由。•url 在浏览记录的末端即为刷新,刷新时,不对路由数组做任何操作。

    另外,应用的路由路径中可能允许相同的路由出现多次(例如 A -> B -> A),所以给每个路由添加一个 key 值来区分相同路由的不同实例。

    注意:这个浏览记录需要存储在 sessionStorage 中,这样用户刷新后浏览记录也可以恢复。

    笔者之前实现的 用原生 js 实现的轻量级路由 ,就是用这种方法实现的,具体代码如下:

    // 路由构造函数function Router() { this.routes = {}; //保存注册的所有路由 this.routerViewId = "#routerView"; // 路由挂载点 this.stackPages = true; // 多级页面缓存 this.history = []; // 路由历史} Router.prototype = { init: function(config) { var self = this; //页面首次加载 匹配路由 window.addEventListener('load', function(event) { // console.log('load', event); self.historyChange(event) }, false) //路由切换 window.addEventListener('hashchange', function(event) { // console.log('hashchange', event); self.historyChange(event) }, false) }, // 路由历史纪录变化 historyChange: function(event) { var currentHash = util.getParamsUrl(); var nameStr = "router-history" this.history = window.sessionStorage[nameStr] ? JSON.parse(window.sessionStorage[nameStr]) : [] var back = false, // 后退 refresh = false, // 刷新 forward = false, // 前进 index = 0, len = this.history.length; // 比较当前路由的状态,得出是后退、前进、刷新的状态。 for (var i = 0; i < len; i++) { var h = this.history[i]; if (h.hash === currentHash.path && h.key === currentHash.query.key) { index = i if (i === len - 1) { refresh = true } else { back = true } break; } else { forward = true } } if (back) { // 后退,把历史纪录的最后一项删除 this.historyFlag = 'back' this.history.length = index + 1 } else if (refresh) { // 刷新,不做其他操作 this.historyFlag = 'refresh' } else { // 前进,添加一条历史纪录 this.historyFlag = 'forward' var item = { key: currentHash.query.key, hash: currentHash.path, query: currentHash.query } this.history.push(item) } // 如果不需要页面缓存功能,每次都是刷新操作 if (!this.stackPages) { this.historyFlag = 'forward' } window.sessionStorage[nameStr] = JSON.stringify(this.history) }, }

    3.2 利用栈的 后进者先出,先进者后出 原理

    在说第二个方法之前,先来弄明白栈的定义与后进者先出,先进者后出原理。

    3.2.1 定义

    栈的特点:后进者先出,先进者后出。

    举一个生活中的例子说明:就是一摞叠在一起的盘子。我们平时放盘子的时候,都是从下往上一个一个放;取的时候,我们也是从上往下一个一个地依次取,不能从中间任意抽出。

    d8e2bc0e35039e4b3b0a1b21ebb3681a.png

    因为栈的后进者先出,先进者后出的特点,所以只能栈一端进行插入和删除操作。这也和第一个方法的原理有异曲同工之妙。

    下面用 JavaScript 来实现一个顺序栈:

    // 基于数组实现的顺序栈class ArrayStack { constructor(n) { this.items = []; // 数组 this.count = 0; // 栈中元素个数 this.n = n; // 栈的大小 } // 入栈操作 push(item) { // 数组空间不够了,直接返回 false,入栈失败。 if (this.count === this.n) return false; // 将 item 放到下标为 count 的位置,并且 count 加一 this.items[this.count] = item; ++this.count; return true; } // 出栈操作 pop() { // 栈为空,则直接返回 null if (this.count == 0) return null; // 返回下标为 count-1 的数组元素,并且栈中元素个数 count 减一 let tmp = items[this.count-1]; --this.count; return tmp; }}

    其实 JavaScript 中,数组是自动扩容的,并不需要指定数组的大小,也就是栈的大小 n 可以不指定的。

    3.2.2 应用

    栈的经典应用: 函数调用栈

    操作系统给每个线程分配了一块独立的内存空间,这块内存被组织成“栈”这种结构, 用来存储函数调用时的临时变量。每进入一个函数,就会将临时变量作为一个栈帧入栈,当被调用函数执行完成,返回之后,将这个函数对应的栈帧出栈。为了让你更好地理解,我们一块来看下这段代码的执行过程。

    function add(x, y) { let sum = 0; sum = x + y; return sum;} function main() { let a = 1; let ret = 0; let res = 0; ret = add(3, 5); res = a + ret; console.log("res: ", res); reuturn 0;}

    上面代码也很简单,就是执行 main 函数求和,main 函数里面又调用了 add 函数,先调用的先进入栈。

    执行过程如下:

    d8cd68a3665a327c8bc0872b5ccc4d0f.png

    3.2.3 实现浏览器的前进、后退

    第二个方法就是:用两个栈实现浏览器的前进、后退功能。

    我们使用两个栈,X 和 Y,我们把首次浏览的页面依次压入栈 X,当点击后退按钮时,再依次从栈 X 中出栈,并将出栈的数据依次放入栈 Y。当我们点击前进按钮时,我们依次从栈 Y 中取出数据,放入栈 X 中。当栈 X 中没有数据时,那就说明没有页面可以继续后退浏览了。当栈 Y 中没有数据,那就说明没有页面可以点击前进按钮浏览了。

    比如你顺序查看了 a,b,c 三个页面,我们就依次把 a,b,c 压入栈,这个时候,两个栈的数据如下:

    7300b6767196673eef761851db633f53.png

    当你通过浏览器的后退按钮,从页面 c 后退到页面 a 之后,我们就依次把 c 和 b 从栈 X 中弹出,并且依次放入到栈 Y。这个时候,两个栈的数据就是这个样子:

    d270a84889308e394376a68d33d92d7c.png

    这个时候你又想看页面 b,于是你又点击前进按钮回到 b 页面,我们就把 b 再从栈 Y 中出栈,放入栈 X 中。此时两个栈的数据是这个样子:

    91388e54893b08ccb224a989807572f0.png

    这个时候,你通过页面 b 又跳转到新的页面 d 了,页面 c 就无法再通过前进、后退按钮重复查看了,所以需要清空栈 Y。此时两个栈的数据这个样子:

    14bfd5835ead833400485f33e233f411.png

    如果用代码来实现,会是怎样的呢 ?各位可以想一下。

    其实就是在第一个方法的代码里面, 添加多一份路由历史纪录的数组即可,对这两份历史纪录的操作如上面示例图所示即可,也就是对数组的增加和删除操作而已, 这里就不展开了。

    其中第二个方法与参考了 王争老师的 数据结构与算法之美。

    展开全文
  • 我们知道JavaScript中很早就提供了window.history对象,利用history对象的forward()、go()、back()方法能够方便实现不同页面之间的前进后退等这种导航功能。但是AJAX操作,是不能用浏览器的前进后退按钮进行导航...

    我们知道JavaScript中很早就提供了window.history对象,利用history对象的forward()、go()、back()方法能够方便实现不同页面之间的前进、后退等这种导航功能。但是AJAX操作,是不能用浏览器的前进和后退按钮进行导航的,因为浏览器并不会将AJAX操作加入到历史记录中。但是借助location.hash,我们能够自己实现AJAX操作的前进和后退。关于window.location.hash的详细介绍和使用方式,可以参考下面这2篇文章。

    location.hash详解和   6 Things You Should Know About Fragment URLs

    我们需要知道以下2点:

    1.如果location.hash发生了变化,那么浏览器地址栏url会发生变化,而且浏览器会产生1个历史记录。

    2.如果location.hash发生了变化,会产生一个hashchange事件,我们可以处理这个事件。

    <!DOCTYPE html> 
    <html>
    <head>
    	<meta charset="utf-8">
    	<script type="text/javascript" src="jquery-1.11.1.min.js"></script>		
    	<script type="text/javascript">		
    	
    		var currentPageIndex = 0;
    				
    		window.onload = function(){
    			currentPageIndex = 0;
    			showPageAtIndex(currentPageIndex);
    			recordHash(currentPageIndex);
    		}
    		
    		// onhashchange可以监控hash变化
    		window.οnhashchange=function(){
    			var hash = window.location.hash;
    			
    			var id = parseInt(hash.substr(1));
    			
    			showPageAtIndex(id);
    		};
    				
    		function toNextPageWhenClick()
    		{
    			currentPageIndex++;
    			
    			if(isValidPageIndex(currentPageIndex))
    			{
    				showPageAtIndex(currentPageIndex);
    				recordHash(currentPageIndex);
    			}
    			else
    			{
    				return;
    			}
    		}
    		
    		function showPageAtIndex(id)
    		{
    			$("div[id!="+id+"]").hide();
    			$("#"+id).show();
    			
    			if(isHomePage(id))
    			{
    				$("input").attr("value","current is home page,next page=1");
    			}
    			else if(isLastPage(id))
    			{
    				$("input").attr("value","current page="+id+", it is the end.");
    			}
    			else
    			{
    				$("input").attr("value","current page="+id+",next page="+(id+1));
    			}
    		}
    		
    		function isValidPageIndex(id)
    		{
    			return id <= 5;
    		}
    		
    		function isLastPage(id)
    		{
    			return id == 5;
    		}
    		
    		function isHomePage(id)
    		{
    			return id == 0;
    		}
    		
    		// hash改变,浏览器会自动生成一个历史记录
    		function recordHash(id)
    		{
    			window.location.hash=id;
    		}
    	</script>
    	
    	<style>
    		.navigate{
    			height:100px;
    			width:300px;
    			background-color:#0000ff;
    			display:none;
    		}
    		
    		.home{
    			height:100px;
    			width:300px;
    			background-color:#00ff00;
    			display:none;
    		}
    		
    		.last{
    			height:100px;
    			width:300px;
    			background-color:#ff0000;
    			display:none;
    		}
    	</style>
    </head> 
    <body>
    	<input type="button" value="" οnclick="toNextPageWhenClick();">
    	
    	<div class="home" id="0">HOME PAGE</div>
    	<div class="navigate" id="1">ajax1</div>
    	<div class="navigate" id="2">ajax2</div>
    	<div class="navigate" id="3">ajax3</div>
    	<div class="navigate" id="4">ajax4</div>
    	<div class="last" id="5">last page</div>
    </body>
    </html>
    


    在chrome下运行这个html文件,默认显示home page,点击按钮的时候回调到下一个页面(直到最后一个页面为止)。我们可以点击浏览器的前进、后退按钮,实现模拟ajax前进、后退的功能。




    展开全文
  • 现在路由默认前进刷新后退缓存,正常使用路由跳转方法即可,如: import { defineComponent } from "vue"; import { useRouter } from "vue-router"; export default defineComponent({ name: "PageA", setup() { ...
  • 2019 年第 79 篇文章,总第 103 篇文章数据结构与算法系列的第四篇文章,前三篇文章:前言浏览器的前进后退功能怎么用栈来实现呢?这里先介绍一下栈的定义和实现,并介绍它的一些常用的应用,最后再简单实现一个...
  • 如果要你实现一个前端路由,应该如何实现浏览器的前进后退 ? 2. 问题 首先浏览器中主要有这几个限制,让前端不能随意的操作浏览器的浏览纪录: 没有提供监听前进后退的事件。 不允许开发者读取浏览纪录,也就是 ...
  • macOS: 前进与返回按钮

    千次阅读 2020-07-03 11:54:55
    在macOS 上有许多程序都提供一个前进或返回按钮,例如 Finder 的(如下图)。 本文是关于如何在自己的程序中实现这个。 开发环境如下: Xcode: 11.0 Swift: 4 minimum macOS deployment target: 10.13. 1. 绑定 ...
  • store, render: h => h(App) }).$mount('#app') 至此已完成,下面简单说明路由使用方法: 页面必须添加 name 属性,如: export default { name: "PageA", } 现在路由默认前进刷新后退缓存,在 .vue 文件直接使用 ...
  • 原理:每个tab选项卡链接写成"#tab1","#tab2"这样点击选项卡的时候链接的hash会发生变化,一但hash发生变化时,浏览器的前进后退按钮就会发生变化,浏览器的前进后退按钮就会发生变化时,$(window).bind('hashchange...
  • 使用js,Jquery 禁用浏览器的back ...有时为了防治用户乱了访问顺序,不得不禁掉浏览器的前进后退按钮。 jQuery(document).ready(function () { if (window.history && window.history.pushState) { ...
  • 比如本文即将要说到的功能,native由于是多页应用,新页面可以启用一个的新的webview来打开,后退其实是关闭当前webview,其上一个webview就自然显示出来;但是在单页的webapp应用中,所有内容其实是在一个页面中...
  • vue实现前进刷新,后退不刷新

    千次阅读 2018-07-02 10:15:42
    项目中遇到可以有多个入口进入一个页面a,在a页面要调不通的接口进行判断所带过来的信息,可在mounted里面进行判断,此页面还有二级页面可以选择数据...说明:例子为从页面2进入页面3时,调用接口,并把数据存到vuex...
  • AJAX 网页保留浏览器前进后退等功能在一些AJAX被大量使用的页面,有时都不太敢刷新,因为刷新以后可能看到的是和原来有很大不同的页面。暂不讨论在某些页面内容大量更新的情况下是否该使用AJAX的问题,本文简单说...
  • 我们可以利用ajax进行无刷新改变文档内容,但是没办法去修改URL,即无法实现浏览器的前进后退、书签的收藏功能。 利用location的hash部分和使用window.onhashchange来实现,而html5的historyAPi,以及开源的PAJAX...
  • 通过history.go()完成 history.go(-1); 后退 history.go(0); 刷新 history.go(1); 前进通过三个按钮响应这三个消息即可 <p> 这是神奇的代码 function back(){ history.go(-1);
  • 今天做了个界面需要用到ajax进行页面跳转,当然使用ajax进行页面跳转有它的优点,比如降低服务器压力,缩短用户等待时间等,但是一个很明显的缺点就是浏览器的前进后退按钮失效了,好在HTML5的history对象的出现...
  • Jquery 监听浏览器前进后退

    千次阅读 2018-02-27 17:15:00
    ps: 如果浏览的网页有缓存, 当点击浏览器上的 前进后退 按钮时, 是优先加载浏览器的缓存数据,(重要一点是:不走服务器端代码,如果在服务器端代码加断点,是不过断点的, 这也是缓存的一个弊端,有时候容易导致...
  • 所谓单页面应用程序,简单的说,就是应用只有一个主网页,第一次加载后,后续页面只会利用js和ajax到服务器获取数据进行页面的局部刷新。因为实际一直只有一个页面,虽然看上去页面经常发生变化(比如点了一个链接或...
  • 有关iframe中前进后退的简单处理

    千次阅读 2011-11-22 10:05:52
    一直对iframe中的前进后退理解的不太深,特意找人学习了下。弄了个小例子,记下来。以便以后方便查查。 HTML代码: 首页  后退 前进 Javascript代码: var fram1 = document....
  • 查看版本 基于索引的操作 输入命令:git reset --hard [局部索引值] 使用^符号,只能后退 输入命令:git reset --hard HEAD^ ...举个例子: 若将已存在的a.txt删除,我们想回到a.txt状态 查看历史:...
  • #栈:如何实现浏览器的前进后退功能? 浏览器的前进后退功能,我想你肯定很熟悉吧? 当你依次访问完一串页面 a-b-c 之后,点击浏览器的后退按钮,就可以查看之前浏览过的页面 b 和 a。当你后退到页面 a,点击...
  • //后退 mWebView.goForward();//前进 mWebView.reload(); //刷新 一定要注意的地方:  实现的操作在webView.setOnKeyListener()中的onKey()方法,也可以再Activity的onKeyDown方法中(是
  • 细心的读者可能已经发现,在 前文给的例子 中,通过点击浏览器的前进与后台按钮,我们可以触发不同的视觉切换效果。这是如何实现的呢?答案是: View.js实时追踪浏览信息 View.js监听history的popstate事件,通过...
  • h5 history api实现无刷新前进后退

    千次阅读 2016-09-18 18:09:56
    popstate事件:当用户单击浏览器的后退或者前进按钮(或者调用history.go,history.back,history.forward方法也会触发popstate事件。调用history.pushState()或者history.replaceState()不会触发popstate事件,但...
  • Unity EZGUI:过渡前进后退

    千次阅读 2013-05-20 10:39:36
    unity3d教程: Unity EZGUI:过渡前进后退 之前使用EZGUI真的很偷懒,都不弄懂Panel Transition里Forward与Back的真正差异,今天终于下定决心搞定它。 说穿了就是Panel里index的 “向上增加” 或 “向...
  • 前言 本系列文章旨在讲解如何从零开始搭建前端监控系统。 项目已经开源 项目地址: https://github.com/bombayjs/bombayjs (web sdk) ...您的支持是我们不断前进的动力。 喜欢请start!!! 喜欢请star

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,179
精华内容 5,671
关键字:

后退就是前进的例子