<div>
<input type="range" id="myRange">
<span id="output"></span>
<div>
<progress id="myProgress" max="100"></progress>
</div>
</div>
function toggle() {
let value = $('#myRange').val()
$('#output').text(value)
$('#myProgress').val(value)
}
toggle()
$('#myRange').on('change', function () {
toggle()
})

以上这种不请求页面的情况是没有历史记录的,后退按钮用不了。

H5 API增加的​​window.history.pushState()​​​、​​window.onpopstate事件​​​和​​window.history.replaceState()​​可以在这种情况下进行历史记录的管理。

它们管理着一个​状态对象栈和对应的URL​,​​pushState()​​​可以为栈中添加一个新的状态对象和对应的URL,它们组成了一条记录,可以用这个对象设置页面状态。当点击后退按钮就触发​​onpopstate​​​事件,该事件回调参数中有​​event.state​​​保存着​​pushState​​添加的上一个状态对象,我们用这个旧的状态对象,就可以让页面恢复到旧的状态中。

​replaceState()​​​与​​pushState()​​​差不多,就是不添加新的状态,而是修改掉当前所在记录的状态。还有个​​go(n)​​,跟点击后退按钮差不多,就是可以指定后退多少,后退按钮只能一页一页退。

let state,initState
window.onpopstate = popState
window.onload = firstTimeLoad
function firstTimeLoad() {
state = {
id:1,
value: $('#myRange').val()
}
initState = Object.assign({},state)
$('#myRange').on('change',changeAction)
display(state)
}
function changeAction(){
state.id++
state.value = $(this).val()
save(state)
display(state)
}
function popState(event){
if(event.state){
state = event.state
display(state)
}else{
display(initState)
}
}
function save(state){
let url = '#history-' + state.id
window.history.pushState(state,'',url)
}
function display(state){
$('#myRange').val(state.value)
$('#output').text(state.value)
$('#myProgress').val(state.value)
}

注意​​popState(event)​​​方法中的​​else​​​部分,因为在页面​​onload​​​时浏览器本身会往栈内添加第一个状态对象,这个对象是null,栈就会这样​​[null,记录1,记录2...]​​​,因此在页面加载​​firstTimeLoad()​​方法里记录初始状态,好在回退到为null对象时,用这个初始状态设置页面。