我如何在JavaScript中使用window.history? [英] How do I use window.history in JavaScript?

查看:137
本文介绍了我如何在JavaScript中使用window.history?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Stack Overflow上发现了很多关于这个的问题,但是他们都对某些部分非常具体。我发现这个问题的答案提供了一些很好的参考,但他们并没有真正解释它是如何工作的,而且他们的例子很难做任何事情。我想知道更多关于它如何一起工作,我想要使用香草JavaScript。



(另外,其他问题上的许多答案已有几年了。) 首先,您可以删除窗口部分。只要历史工作正常。但在我们讨论一切如何协同工作之前,我们需要知道我们可以使用什么。



重要事件



window.onload



加载网页时会触发此事件。有两种情况会触发此事件:


  1. 当您的网页从另一个网页导航时。请注意,我写了web ,而不是web 网站。在同一网站上的页面之间移动将触发此活动。

  2. 在您的网页刷新后。



window.onpopstate



当您在 you 设置的历史记录状态之间导航时,此事件触发。您的浏览器会在正常浏览期间自动设置历史状态(为空),但从这些状态导航到这些状态将不会触发此事件。


$ b

window.onunload



每当您的网页被卸载时,此事件就会触发。有两种情况会引发此事件:


  1. 当您从网页导航到其他网页时。



重要对象



历史界面包含五个函数(如下所述),两个只读对象(在这里描述),并且有点像链接列表。历史对象的每个链接中包含的两个对象是:


  • 长度 - 这是当前浏览器的历史状态数窗口。它从1开始。

  • state - 这是一个几乎可以包含任何内容的JavaScript对象。默认情况下它是 null



您可以通过调用 history.length history.state 虽然 history.state 只能用于获取当前历史状态。



重要功能



history.go(距离)



这个功能与在浏览器中按下后退或前进按钮的功能相同,具有额外的功能,可以指定距离你想去。例如, history.go(3)的效果与按下前进按钮三次的效果相同,但实际上并未在开始和结束位置之间加载页面。负值同样会让您在历史中向后移动。 history.go(0) history.go(),甚至 history.go (NaN)与刷新页面的效果相同(这不会触发 popstate 事件)。如果您无法向前/向后移动指定的范围,该功能将无效。



history.back()



此功能与浏览器中的后退按钮具有相同的功能。它相当于 history.go(-1)。如果它不能返回,该函数将什么都不做。



history.forward()



此函数有与浏览器中的前进按钮功能相同。它相当于 history.go(1)
$ b

history.replaceState(state,title [,location])


$ b $如果无法前进,函数将不会执行任何操作。 b

此函数替换当前的历史状态。它有三个参数,尽管最后一个是可选的。参数是:


  • 状态 - 这是最重要的参数。你给这个参数的对象将被保存到 history.state 中以供以后检索。这是一个深层复制,所以如果您稍后修改原始对象,它将不会更改保存的状态。您也可以将其设置为 null ,但如果您不打算使用它,那么使用历史记录
  • title - HTML标准建议传递给这个参数的字符串可以被用户界面中的浏览器使用,但是目前没有任何浏览器对它做任何事情。 / li>
  • location - 此参数允许您更改相对于当前页面的URL。它不能用于将网址更改为其他网站的网址,但可以用来将网址更改为 网站上另一个网页的网址。我会建议不要这样做,因为即使URL是另一个页面,页面实际上并没有重新加载。使用后退/前进将显示已更改的URL,但不会更改页面,并会触发 popstate 而不是加载卸载。在更改URL后刷新页面将加载由URL指定的页面,而不是您先前所在的页面。此功能可用于提供目前状态下页面的链接,但我建议只更改查询字符串而不是完整的URL。如果未使用此参数,则URL不会更改。



history.pushState(state,title [,location])



此函数与 history.replaceState 的工作方式相同,不同之处在于之后的新状态当前状态而不是替换当前状态。所有以前可以用 forward 访问的历史状态都将被丢弃,新状态将成为当前状态。



装配零件



历史记录界面对于允许用户在浏览器中浏览动态生成的内容而无需重新加载整个页面非常有用,但您需要请注意您的用户可能做的所有可能的事情,这可能会影响历史记录状态。


  1. 第一次导航到您的页面


    • 您的用户是否应该拥有菜单/列表,一些特定的动态生成内容或者一些随机动态生成的内容?

    • 如果没有历史记录,甚至是JavaScript,你的页面会正确显示吗?


  2. 使用返回/转发返回您的页面


    • 如果您的用户看到同一个内容,时间, 或者他们是否应该在内容中看到他们的访问结果? (欢迎回来消息可能对某些人来说很不错,但对其他人来说是一种不必要的分心。)


  3. 刷新页面


    • 如果您获得新页面,返回到开始页面或重新加载同一页面? (如果网址没有变化,用户可能不会期待最后一次)。


  4. 使用从刷新的页面返回/转发


    • 如果您获取了相对于刷新页面的新内容,或重新加载之前保存的状态?


  5. 离开您的页面


    • 您是否需要在离开前保存所有内容
    • 通过深层链接


      • 您是否有代码来识别和处理深层链接?


请注意,无法删除已保存的状态(除 pushState()>)。你只能用新的内容来替换它。



把它们放在一起



因为这开始得到有点罗嗦,让我们用一些代码完成它。

  //首次加载页面时调用此函数,页面刷新,
//以及使用后退/前进从其他页面返回页面时。
//使用history.pushState导航到不同的页面,然后返回
//不会触发此事件,因为页面实际上没有重新加载。
window.onload = function(){
//您可以通过检查performance.navigation.type来区分页面加载和重载。
if(window.performance& window.PerformanceNavigation){
let type = performance.navigation.type;
if(type == PerformanceNavigation.TYPE_NAVIGATE){
//页面已加载。
} else if(type == PerformanceNavigation.TYPE_RELOAD){
//页面被重新加载。
} else if(type == PerformanceNavigation.TYPE_BACK_FORWARD){
//通过后退或前进导航页面,
//虽然* not *来自已设置的历史记录状态。
}
}

//请记住,浏览器会在
//第一次访问时自动将状态设置为null,因此如果您检查并找到它为空,你知道
//表示用户还没有来过。
if(history.state == null){
//首次加载时填充。
} else {
//在刷新或从其他页面返回此页面
//使用后退/前进。您可能希望在命名函数下面创建window.onpopstate函数
//,并在此处调用该函数。
}

//您当然可以在所有三种情况下执行代码。它会去这里。

//你也可以在这个时候设置历史状态。如果你只想替换某些
//情况下的状态,这可能会出现在
// if..else语句中。立即设置状态的一个原因是,如果用户
//通过深层链接导航到您的页面。
让state = ...; //这里可能没有多少设置,因为页面是
//刚刚加载的页面,但如果页面获得随机内容或时间 -
//依赖内容,则可能需要保存这里的东西,所以它可以
//以后再次检索。
让title = ...; //由于您的浏览器尚未实际使用此功能,因此您可以将
//任何您想要的内容放入此处,但我会建议将它设置为
// null或document.title用于浏览器实际上开始做
//用它做点什么。
让URL = ...; //因为页面
//刚刚被加载,所以你可能不想改变URL,在这种情况下,你不应该使用这个
//变量。您可能想要更改网址的一个原因是,如果
//用户使用URL中的查询字符串导航到此页面。在
//读取查询字符串之后,可以通过将此
//变量设置为:location.origin + location.pathname
history.replaceState(state,title,URL)来删除它。 //由于页面刚加载,你
//不想推送新状态;你应该
//只需要替换当前状态。
}

//在您设置的状态之间导航时调用此函数。
//由于`history`的目的是允许在没有
// //重新加载页面(即联系服务器)的情况下进行动态内容更改,所以此函数
//中的代码应该相当公平简单。就像替换文字内容和图像一样。
window.onpopstate = function(){
//在这里执行history.state。
}

//这个函数在页面刷新前被调用,右边的
//在离开页面之前(不包括history.replaceState)。这是
//你离开之前设置页面历史状态的最后机会。
window.onunload = function(){
//在这里完成历史状态。
}

请注意,我从来没有调用 history.pushState 任何地方。这是因为不应在这些函数中的任何地方调用 history.pushState 。它应该由实际以某种方式更改页面的函数调用,您希望用户能够使用后退按钮来撤消。



所以最后,通用设置可能如下所示:




  • 检查 if(history.state == null) window.onload 函数中。


    • 如果为true,则使用新信息覆盖历史记录状态。 如果为false,则使用历史记录状态恢复页面。


  • 当用户浏览页面时,请致电 history.pushState 当重要的事情发生时,应该可以通过后退按钮撤消。

  • 如果/当用户使用他们的后退按钮和 popstate 事件时被触发,使用您设置的历史状态将页面返回到其以前的状态。


    • 当用户然后使用他们的前进按钮时,同样如此。


  • 使用 unload 事件在用户离开页面之前完成历史记录状态。


I found a lot of questions about this on Stack Overflow, but they were all very specific about certain parts. I did find this question whose answers provide some nice references, but they don't actually explain how it all works, and their examples hardly do anything. I want to know more about how it all works together, and I want to use vanilla JavaScript.

(Also, many of the answers on other questions are years old.)

解决方案

GETTING STARTED

First of all, you can remove the window part. Just history works fine. But before we get into how everything works together, we need to know what we can use.

Important Events

window.onload

This event fires whenever your webpage is loaded. There are two cases that will fire this event:

  1. When your webpage is navigated to from another webpage. Note that I wrote webpage, not website. Moving between pages on the same site will trigger this event.
  2. Just after your webpage is refreshed.

window.onpopstate

This event fires when you navigate between history states that you have set. Your browser automatically sets history states (to null) during normal browsing, but navigating to/from these states will not trigger this event.

window.onunload

This event fires whenever your webpage is unloaded. There are two cases that will fire this event:

  1. When you navigate to another webpage from your webpage.
  2. Just before your webpage is refreshed.

Important Objects

The history interface contains five functions (described below), two read-only objects (described here), and works a bit like a linked list. The two objects contained in each 'link' of the history object are:

  • length - This is the number of history states for the current browser window. It starts at 1.
  • state - This is a JavaScript object that can contain practically anything. It is null by default.

You can access them by calling history.length and history.state respectively, though history.state can only be used to get the current history state.

Important Functions

history.go(distance)

This function does the same thing as pressing the back or forward button in your browser, with the added functionality of being able to specify exactly how far you want to go. For example, history.go(3) has the same effect as would pushing your forward button three times, without actually loading the pages between your start and end locations. A negative value will likewise move you backwards through your history. history.go(0), history.go(), and even history.go(NaN) have the same effect as refreshing the page (this does not trigger the popstate event). If you cannot move forward/backward as far as specified, the function will do nothing.

history.back()

This function has the same functionality as the back button in your browser. It is equivalent to history.go(-1). If it cannot go back, the function will do nothing.

history.forward()

This function has the same functionality as the forward button in your browser. It is equivalent to history.go(1). If it cannot go forward, the function will do nothing.

history.replaceState(state, title[, location])

This function replaces the current history state. It takes three arguments, though the last one is optional. The arguments are:

  • state - This is the most important argument. The object you give to this argument will be saved to history.state for later retrieval. This is a deep copy, so if you later modify the original object it will not change the saved state. You could also set this to null, but if you aren't going to use it, there's not much point in using history at all.
  • title - The HTML Standard suggests that a string passed to this argument could be used by the browser in the user interface, but no browser currently does anything with it.
  • location - This argument allows you to change the URL relative to the current page. It cannot be used to change the URL to that of another website, but it can be used to change the URL to that of another page on your website. I would advise against this however, as the page is not actually reloaded even though the URL is of another page. Using back/forward will show the changed URL, but will not change the page, and will trigger popstate rather than load or unload. Refreshing the page after changing its URL will load the page specified by the URL rather than the page you were previously on. This functionality could be used to provide a link to your page in its current state, but I would recommend only changing the query string rather than the full URL. If this argument is not used, the URL will not change.

history.pushState(state, title[, location])

This function works the same as history.replaceState, except it puts the new state after the current state instead of replacing the current state. All history states that could have previously been accessed with forward are discarded, and the new state becomes the current state.

ASSEMBLING THE PIECES

The history interface is very useful for allowing your users to navigate through dynamically generated content from within their browser without having to reload the entire page, but you need to be mindful of all the possible things your users could do that could affect the history state.

  1. First time navigating to your page
    • Should your users be greeted with a menu/list, some specific dynamically generated content, or maybe some random dynamically generated content?
    • Will your page display correctly without history, or even JavaScript?
  2. Using back/forward to return to your page
    • Should your users see the same thing they saw their first time, or should they see the result of their visit reflected in the content? (A "Welcome Back" message might be a nice touch to some, but an unwanted distraction to others.)
  3. Refreshing your page
    • Should you get a new page, return to the start page, or reload the same page? (Your users probably won't expect that last one if the URL hasn't changed.)
  4. Using back/forward from a refreshed page
    • Should you get new content relative to the refreshed page, or reload the previously saved state?
  5. Navigating away from your page
    • Do you need to save anything before leaving?
  6. Returning to your page via a deep link
    • Do you have code in place to recognize and handle a deep link?

Note there is no way to delete a saved state (other than a specific case with pushState() mentioned above). You can only replace it with new content.

PUTTING IT ALL TOGETHER

Since this is starting to get a bit wordy, lets finish it off with some code.

// This function is called when the page is first loaded, when the page is refreshed,
// and when returning to the page from another page using back/forward.
// Navigating to a different page with history.pushState and then going back
// will not trigger this event as the page is not actually reloaded.
window.onload = function() {
  // You can distinguish a page load from a reload by checking performance.navigation.type.
  if (window.performance && window.PerformanceNavigation) {
    let type = performance.navigation.type;
    if (type == PerformanceNavigation.TYPE_NAVIGATE) {
      // The page was loaded.
    } else if (type == PerformanceNavigation.TYPE_RELOAD) {
      // The page was reloaded.
    } else if (type == PerformanceNavigation.TYPE_BACK_FORWARD) {
      // The page was navigated to by going back or forward,
      // though *not* from a history state you have set.
    }
  }

  // Remember that the browser automatically sets the state to null on the
  // first visit, so if you check for this and find it to be null, you know
  // that the user hasn't been here yet.
  if (history.state == null) {
    // Do stuff on first load.
  } else {
    // Do stuff on refresh or on returning to this page from another page
    // using back/forward. You may want to make the window.onpopstate function
    // below a named function, and just call that function here.
  }

  // You can of course have code execute in all three cases. It would go here.

  // You may also wish to set the history state at this time. This could go in the
  // if..else statement above if you only want to replace the state in certain
  // circumstances. One reason for setting the state right away would be if the user
  // navigates to your page via a deep link.
  let state = ...; // There might not be much to set at this point since the page was
                   // just loaded, but if your page gets random content, or time-
                   // dependent content, you may want to save something here so it can
                   // be retrieved again later.
  let title = ...; // Since this isn't actually used by your browser yet, you can put
                   // anything you want here, though I would recommend setting it to
                   // null or to document.title for when browsers start actually doing
                   // something with it.
  let URL = ...;   // You probably don't want to change the URL just yet since the page
                   // has only just been loaded, in which case you shouldn't use this
                   // variable. One reason you might want to change the URL is if the
                   // user navigated to this page with a query string in the URL. After
                   // reading the query string, you can remove it by setting this
                   // variable to: location.origin + location.pathname
  history.replaceState(state, title, URL); // Since the page has just been loaded, you
                                           // don't want to push a new state; you should
                                           // just replace the current state.
}

// This function is called when navigating between states that you have set.
// Since the purpose of `history` is to allow dynamic content changes without
// reloading the page (ie contacting the server), the code in this function
// should be fairly simple. Just things like replacing text content and images.
window.onpopstate = function() {
  // Do things with history.state here.
}

// This function is called right before the page is refreshed, and right
// before leaving the page (not counting history.replaceState). This is
// your last chance to set the page's history state before leaving.
window.onunload = function() {
  // Finalize the history state here.
}

Notice that I never called history.pushState anywhere. This is because history.pushState should not be called anywhere in these functions. It should be called by the function that actually changes the page in some way that you want your users to be able to use the back button to undo.

So in conclusion, a generic setup might work like this:

  • Check if (history.state == null) in the window.onload function.
    • If true, overwrite the history state with new information.
    • If false, use the history state to restore the page.
  • While the user is navigating the page, call history.pushState when important things happen that should be undoable with the back button.
  • If/When the user uses their back button and the popstate event is triggered, use the history state you set to return the page to its previous state.
    • Do likewise if/when the user then uses their forward button.
  • Use the unload event to finalize the history state before the user leaves the page.

这篇关于我如何在JavaScript中使用window.history?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆