返回上一页与返回上一级是两种语义
别名: 上一页 vs 上一级 · up versus back · 历史返回 · 层级返回
概念解释
返回上一页弹出的是会话里刚走过的那一帧,对象是 history stack(历史栈)的顶。返回上一级走到分类树或任务树上的父节点,对象是层级,与刚才怎么进来无关。两者都常被画成左箭头,但落点只有在「刚好从父级走进来」时才会重合。Android 长期把系统 back stack(返回栈)的 Back 和工具栏的 Up 分成两套动作,原因就是时间顺序和结构位置不是同一条轴。浏览器只有 Back,没有原生 Up;产品若把 Back 改写成 Up,等于改写了用户已经学过的撤销模型。
这条只划清两种语义,不讨论从站外链进来时栈顶是谁,也不讨论回到那一帧时滚动和筛选还在不在。
机制
人用 Back 当作逐步撤销:刚才那次前进被收回,连带着那次前进造成的上下文(搜索结果、筛选后的列表、未读完的另一篇文章)。Up 是在地图上往根走一格:不管刚才从搜索、通知还是推荐进来,父级都是同一个。把 Back 绑到父级,撤销粒度消失,搜索结果那一帧被丢掉,人会觉得「系统把我送去了一个我没来过的地方」。把 Up 做成 Back,祖先链不再稳定,同一商品页的「上一级」会随入口变成搜索、首页或广告落地页,地图失效。
单页应用的 SPA routing 更容易把两套语义焊死成一次 history.back()。路由若用 replace 而不是 push,栈上根本没有父级帧,Up 只能靠产品自己构造;若把所有离开都 push,Back 又会穿过本不该撤销的层级跳转。控件外观不能决定语义:系统手势、浏览器按钮、页内「返回」必须先声明自己弹的是哪一种栈。
怎么研究
经典做法是 up-versus-back 任务:同一详情页安排两条进入路径(从父类目进来 / 从搜索进来),分别点系统返回和点「上一级」,记录落点是否符合被试的事先预期。
- 范式:Cockburn、Tauscher 与 Greenberg 一类的网页重访日志说明 Back 是主导的时间性导航;实验室里再把层级控件和系统返回拆开测。
- 自变量:进入路径(树内 / 树外)、可见返回控件绑的是 history 还是 parent、文案是「返回」还是父级名。
- 因变量:落点与预期一致率、错误后改用哪一个控件、口头把两次点击当成同一动作的次数。
- 方法论注意点:只从父级进入再测返回,两种语义会假重合,会得出「一个按钮就够」的错误结论。必须包含至少一条非树入口。日志里的 Back 点击率高,不能用来证明产品里的 Up 可被删掉——它测的是时间撤销有多常用,不是层级跳转有没有独立需求。
边界
向导、结账这种线性流程没有「上一级」,只有上一步,Up 语义不成立,硬造父级会跳步。没有稳定分类树的信息流、聊天、画布,Up 没有合法目标,只保留 Back。嵌入式 WebView 若没有自己的 history,系统返回可能直接关掉容器,这时页内必须提供明确的时间性返回,不能指望「上一级」冒充。桌面多窗口里「关闭窗口」不是 Back,也不是 Up。
怎么落地
- 系统返回、浏览器 Back、边缘滑动一律弹出 history stack;需要「到父级」时用面包屑、工具栏 Up 或写成父级名字的链,不要改写系统返回的目标。
- 两种控件同时存在时,文案分开:「返回」对上一页,父级名对上一级。不要两个都画成无标签左箭头。
- SPA 里 Up 用指向父级路由的显式导航,Back 用真正的
history.back();不要用 replace 把父级帧偷换掉之后还显示返回箭头。 - 验证:从类目走进详情,再从搜索走进同一详情。系统返回应分别落到类目和搜索;「上一级」两次都应落到同一父类目。任一交叉,语义就被焊错了。