都是返回上一页闹得,打球都心不在焉了。
除了首页,其他的页面左上角都有一个返回上一页的按钮。这样的功能合情合理。一个window.history.go(-1)就能搞定的玩意儿。
新需求来了,如下:
需求一:
A页:列表页(不同的业务,不同的列表页)
B页:详细页(同一个详细页)
C页:表单页(同一个表单页)
A—>B—>C(提交成功)—>B(点击返回上一页)—>A
需求二:
客户端(浏览器、微信、APP)的回退按钮也需要同样的功能
解决方案(自以为是):
window.history.go(-3):本来欣喜,这么简单就搞定了,实践证明这是个错误
(1)页面见的跳转是通过A标签href或者window.location.href,这会在历史记录history中增加一条历史条目,A—>B—>C—>B—>A,go(-3)可以满足需求一。
(2)使用history.pushState()函数,popstate事件配合,事件处理程序中调用需求一的函数,想当然就这么觉得完成了。
(3)自测一下,全乱了都是哪里到哪里,迷路了,再也回不去了。
(4)就钻了-1…-N的牛角尖无法自拔了,埋头揉了一顿头发,发型已乱,现在是晚上10点,喊个滴滴回家。
(5)周末熄灯睡不着了,问问老伴儿有没有好的想法,还真有,由于此功能放到了公用模块了,pushState会在history中增加一条历史条目,导致不需要这个返回逻辑的页面,在go(-1)时出现了混乱。一个后端从逻辑给个行的同的建议还是,晚安好梦。
(6)周一,到了单位,迫不及待试一下,凌乱了。popstate想要触发,想这种情景下使用history.pushState()是最合适的,可是它会增加记录,只能这样乱着,虽然我属于总在放弃治疗边缘不断试探的人,可总归是试探,绝不玩真格儿的。电脑给面子,此时蓝屏了,哈哈哈哈,我已疯。
解决方案(靠谱点的):
-1…-N是控制不了了,MDN上的pushState、replaceState、popstate,看了N遍,榆木脑壳,没开窍,网上也有对比pushState、replaceState区别的,一个增加一条历史条目,一个把当前的替换掉,不增加。现在的情况就是增加一条导致的,如果没有pushState作妖儿,不就可以了吗,用replaceState试试吧。
(1)A—>B:replaceState(‘replaceurl’,null,‘B页面地址’);
(2)B—>C:replaceState(‘replaceurl’,null,‘C页面地址’);
(3)C—>B:replaceState(‘replaceurl’,null,‘B页面地址’);
这时候无论点击B页左上角的返回上一页,还是客户端的回退按钮,老老实实回到了来时的A列表页,这个由于replaceState指将当前历史条目进行替换,不会增加新历史条目。只在页面左上角返回按钮加事件处理程序go(-1)即可,客户端的回退按钮不用理。
当然也可以使用window.href.replace()实现。
混沌了三天,终于尘埃落定。万物必有其存在的道理,html5给出replaceState就是干这个的。
反省:
1:pushState、replaceState、popstate相关原理理解不透彻,误用乱用。
2:对需求只盯表象,不究本质。
如果有好建议,欢迎聊聊!!