背景
在挪动端页面中,因为屏幕空间无限,导航条扮演着十分重要的角色,提供了疾速导航到不同页面或性能的形式。用户也通常会在导航条中寻找他们感兴趣的内容,因而导航条的曝光率较高。在这样的背景下,提供一个动静灵便的导航条,为产品赋能,变得尤其重要。
应用原生导航栏现状
拿 iOS 原生导航条为例,导航条作为页面进出栈的根视图连接器,以及生命周期的管理器。尤其是在作为 webView Controller 的父容器的时候,面对 webview 中 h5 页面灵便的的路由属性,以及一些难料的异常情况,原生很难也不便于频繁操作根试图容器,因而也产生了一些性能差、体验差、开发成本高、测试场景难笼罩等问题。安卓也有相似状况。
1、性能问题
•ssr
预渲染时,无奈对原生导航条进行预加载。对于百亿,便宜包邮等应用 ssr 预渲染的频道,因为原生导航栏无奈进行预加载,导致上屏较慢等问题。
2、开发 / 测试老本高
•原生导航条生命周期耦合。原生导航条作为 webviewController 的根容器,一旦操作机会不当,很可能影响到线上页面,而且最大的问题在于这种场景测试很难笼罩。比方:window.href.url
应用这种形式更新以后页面时,因为不同频道操作同一根导航条,会引发不可预知的问题;
•场景无限。站外场景无奈应用原生导航条,一些业务方往往须要独自解决站内外,造成开发资源节约。
3、体验差
•webview 初始化时会预置一个默认的导航条,而后依据前端配置,再去设置导航条的不同款式,无奈防止的存在一个过渡期,体验较差。
•window.location.reload()
刷新以后页面的时候,即使是在 js 中暗藏了导航条,webview
为了兼容一个线上问题,执行 reload 时此时会先展现原生导航条,直到执行了 js 的暗藏逻辑,才会被暗藏,体验较差。
4、难扩大造成营销资源节约
•无奈扩大交互动效。得益于挪动端页面中,导航条得天独厚的地位,产品往往心愿有更活泼的交互性,来进步曝光、粘性、流动触达率等。比方导航栏上挂载搜寻框、以及吸顶、延长动画、沉迷式、炫酷的营销 icon 等等。遗憾的是原生零碎导航条不能全副反对,其实无论从视图层级上来说,还是从导航条职责上来说,apple
并不心愿过多操作导航栏上的元素。也就造成了高曝光地位的资源节约。
5、依赖性强
•因为要依赖原生 JS 桥,就肯定会存在版本限度问题。造成需要迭代慢,甚至随着工夫的推移,版本卡口起因无迹可寻,代码调整战战兢兢,版本审核慢、周期长等问题。
解决方案
基于原生导航条现状,百亿补贴频道积淀出了通用 H5 导航条组件@pango/navigation-bar
,具备以下劣势:
1、性能好
•反对 ssr 预渲染,上屏较快。
2、开发 / 测试成本低
•人力节俭百分之 90% 以上,以 plus 95 折为例,对接只需 0.5/ 人日。
•无场景限度。可用于站内外,ssr 以及 csr 场景,无需站内外屡次开发。
•可配置。@pango/navigation-bar
应用 config 的模式配置 item,这么做的益处是一旦业务需要改变,只需调整配置,无需调整组件逻辑,极大升高开发和测试老本。另外如果你应用主站的 webview 并且配置了 config,那么只须要简略的改变 config,代码迁徙成本低。
•导航条在频道内和其余一般楼层无异,生命周期隔离清晰,不会影响别的页面,测试成本低。
•单向数据流设计,内部数据变动,组件 UI 及时响应,不存在原生的操作窗口问题,开发体验佳;
3、用户体验好
•生命周期和其余楼层放弃同步,躲避了原生容器和 H5 页面人造的生命周期无奈同步的问题,也就不存在两者之间的过渡问题,体验佳。
4、灵便定制
•采纳左、中、右、状态栏、导航栏分层设计的模式,反对传入 React.ReactElement,比原生定制性更强,可灵便定制目前站内绝大部分导航条款式以及交互动画,正当高效利用导航条资源;
5、机型、零碎兼容性好
•参考原生导航栏异形屏适配计划,参考原生相对布局思路,完满适配折叠屏、异形屏。
•iOS9 – 最新、Android5 – 最新均兼容性良好,未发现线上兼容异样。
6、不对外依赖
纯手工打造,未应用第三方库,不会对宿主造成依赖抵触,随时改变随时公布不存在版本控制,最大水平的升高和隔断对原生容器的版本依赖。
异样解决
原生导航条作为根试图容器,容器内子视图异样不会影响根试图的展现,所以不必非凡解决 html 下载失败,js 执行异样,服务挂掉等异常情况。然而 H5 导航条遇到这些异常情况,也要保障用户能够点击返回按钮返回上一页。
百补计划
目前计划已和通天塔以及 hybrid 团队买通,计划如下:
异样场景 1 :业务 js 执行异样。
• @pango/navigation-bar 组件应用 a 标签渲染返回按钮,保障 js 执行异样时仍然展现返回按钮,并且能失常响应返回事件。
•业务展现兜底谬误页时,会应用导航条兜底数据渲染导航条确保可返回上一级。
异样场景 2 :webview 加载 html 失败。
为了打消下面提到的过渡问题,业务链接中新增了 qurey
参数hideNavi=1
,原生 webview 会通过该字段在 webview 呈现之前暗藏导航条。然而因而也引发了一个危险:html 加载失败时,会造成无头的问题。因而须要 webview 配合革新,一旦监测到 html 加载失败,原生 webview 要展现原生导航条。
异样场景 3 :通天塔服务异样。
同样是场景 2 中的问题,须要通天塔配合革新通天塔服务异样的场景:根据链接中 hideNavi
字段增加返回按钮或者告诉 webview 展现默认导航条。
竞品和兄弟频道比照
察看多个竞品以及兄弟频道,发现在上述的异样场景 2、3 下,均未做特地解决,展现无头谬误页。如果此时原生禁用了右滑返回手势,页面将无奈返回上一级,这无异是一个十分重大的缺点(事实上有些竞品页面以及咱们某些频道的确无奈返回上一级)。
线上我的项目
目前应用该组件的我的项目:百亿补贴、月黑风高、PLUS95 折。
线上成绩展现
设计思路
参考原生 navigationBar
的设计思路,把整个导航栏分为 左、右、中
三个区域,左、右区域依据内容自适应宽度,残余空间为两头区域。左右区域承受 items 数组,可依据 item 接口协议设置左右的 items,协定可自定义图片、尺寸、事件、间距、下拉菜单、是否动画响应等,已默认蕴含了关注、返回、更多、频道 logo 等罕用元素,当然如有须要也能够自定义一个 React.ReactElement
。两头区域只承受React.ReactElement
,你能够自在定制元素,传入navigation-bar
即可,一张图片一段文字,或者是一个搜寻框……不论是伸缩或者是上滑吸顶,都可自定义。
@pango/navigation-bar
该组件应用 react + ts 开发,大小只有 4.1K。
文件构造:
应用形式
装置
npm i @pango/navigation-bar --registry=http://registry.m.jd.com
配置
你能够自在配置 items 除了 ”follow","more","back","logo"
,这些已知的元素外还能够设置 type:"common",
是一个通用类型的 item;
scrollCallBack
会回调上滑比例,可依据该比例做交互动画;
import {
BACK_ICON,
FEEDBACK_ICON,
FEEDBACK_URL,
INavigationParams,
MORE_ICON,
RULE_ICON,
SHARE_ICON,
} from "@pango/navigation-bar";
setH5NavigationButton = (headerData) => {
const extend = headerData?.navigationBar?.extend;
const followInfo = headerData?.navigationBar?.followInfo;
const follow = {
type: "follow",
collectionId: String(followInfo?.themeId),
gapWidth: 12,
width: 55,
height: 22,
};
const moreItem = {
type: "more",
menuBackgroundColor: "white",
img: MORE_ICON,
title: "更多",
menuList: [],};
moreItem.menuList.push({
icon: RULE_ICON,
title: "规定页",
menuEventData: extend?.guideUrl,
});
moreItem.menuList.push({
icon: SHARE_ICON,
title: "分享",
type: "share",
menuEventData: extend?.share,
});
const backItem = {
type: "back",
img: BACK_ICON,
canClick: !margicWindow,
title: "返回",
};
const backLogo = {
type: "logo",
img: DEFAULT_LOGO,
isAnimation: true,
gapWidth: 5,
width: 176,
height: 34
};
const navBarParams: INavigationParams = {leftItems: [],
rightItems: [],
backgroundColor: "#FD4D00",
navHeight: this.status.navHeight,
};
navBarParams.leftItems.push(backItem,backLogo);
navBarParams.rightItems.push(moreItem, follow);
navBarParams.titleImgItem = TitleSearch({});
navBarParams.scrollCallBack = (scale) => {
this.setStatus({
navigationBarParams: Object.assign(this.status.navigationBarParams, {titleImgItem: TitleSearch({ isCollapse: scale === 1})
})
});
}
return navBarParams;
};
titleImgItem
特地留神 titleImgItem,这个属性是导航条两头区域的展现内容,TitleSearch
是百亿补贴的搜寻框,你能够参考该元素自定义两头区域。
挂载
import {INavigationParams, NavigationBar} from "@pango/navigation-bar";
import "@pango/navigation-bar/lib/navigation-bar.scss";
css
.nav-bar {
width: 750px;
z-index: 1;
top: 0px;
}
<NavigationBar
className="nav-bar"
params={data.navParams}
barHeight={200} // 自定义导航栏高度
event={do somethings}
/>
遇到了哪些问题
Q: 若原生导航条暗藏,此时异样怎么办?
异样分为以下 3 类:
异样场景 1 :业务 js 执行异样。
• @pango/navigation-bar 组件应用 a 标签渲染返回按钮,保障 js 执行异样时仍然展现该标签,并且能失常相应出栈事件。
•业务展现兜底谬误页时,会应用导航条兜底数据渲染导航条。
异样场景 2 :webview 加载 html 失败。
为了打消下面提到的过渡问题,业务链接中新增了 qurey
参数hideNavi=1
,原生 webview 会通过该字段在 webview 呈现之前暗藏导航条。然而因而也引发了一个危险:html 加载失败时,会造成无头的问题。因而须要 webview 配合革新,一旦监测到 html 加载失败,原生 webview 要展现原生导航条。
异样场景 3 :通天塔服务异样。
同样是场景 2 中的问题,须要通天塔配合革新通天塔服务异样的场景:根据链接中 hideNavi
字段增加返回按钮或者告诉 webview 展现默认导航条。
若发现其余异样,麻烦揭示我。
Q: 折叠屏怎么适配?
折叠屏适配始终是前端适配的噩梦,噩梦的根本原因在于:宽度于高度的比例十分值,前端布局是往往会把 px 转换成 vw,因而造成了异形屏适配难的问题。
•参考原生零碎导航栏的相对布局计划:@pango/navigation-bar
把导航条拆分为状态栏和导航栏高低两局部,导航条宽度屏幕自适应,导航条高度追随设施变动,并采纳大写的 PX
单位来固定元素尺寸。依据协定 item 宽高、间距仍可自定义,然而大写的 PX
保障了 item 不会随着屏幕宽度而异样变动。
navigation-bar {
width: 750px; // 会转换成 vw
height: 44PX; // 不会转换成 vw
display: flex;
position: absolute;
.left-items-bg {
margin-left: 16PX; // 不会转换成 vw
height: 22PX;
margin-top: 11PX;
width: fit-content;
display: flex;
align-items: center;
justify-content: center;
}
}
Q: 原生导航条优化?
现状中的几个异样场景,仍须要 webview 配合一起整改,所以目前整改计划为:
业务链接中新增 qurey
参数hideNavi=1
,此时 webview 通过该字段在 webview 呈现之前暗藏导航条。由 webview 负责整改,跟版 12.1.4。
开源打算
经安全部门审核之后,会向外开源。
迭代打算
•导航条在挪动端页面中的重要性无需多言,咱们最终的目标是面向全团体,和通天塔以及 hybrid 团队,一起打造一根标准通用的 H5 导航栏,如果你在应用过程中发现一些咱们没有思考到的异样场景或者设计规范,请与我分割,咱们独特欠缺。
•目前该组件下拉刷新还是要依赖原生的下拉刷新事件,前期会定制 H5 本人的下拉刷新。
•一个标准的 UI 组件应该是一个有严格 UI 设计规范的,比方间距,字体大小、图片标准等。然而一期的设计中咱们为了灵便,通过协定把 UI 把控留给了用户,也心愿前面的迭代开发中融入更多标准的设计语言。
作者:京东批发 张松超
起源:京东云开发者社区 转载请注明起源