1.1 动画
为提高用户体验,使页面更加生动有趣,提高用户的满意度和留存率,页面中添加了多个动画。
其中为了突出页面中的重点内容竞速排名,添加了进度条、徽章、菜单、按钮和弹框等动画。
进度条中包含2个动画效果:ProgressRise和moveScaleRight。这两个动画效果是通过CSS的animation属性同时应用在同一个元素上实现的,animation属性可以接受多个动画效果,用逗号分隔即可。当初始化加载数据时,进度条从0到100%,用缓动函数,即动画开始和结束时速度较慢,中间时速度较快的方式展开,只执行一次,ProgressRise动画结束。延迟4.6秒后,开始交替动画moveScaleRight,元素在X轴方向上进行了缩放,缩放比例为1.04倍,按照2秒时间无限循环,实现右侧弹性效果。

<div class="progress"></div><!--* 进度条 *-->.progress { z-index: 10; height: 7px; background-image: @progress-bar-color; border-radius: 8px;/* 这是一个CSS动画,包含两个动画效果:ProgressRise和moveScaleRight。这两个动画效果是通过CSS的animation属性同时应用在同一个元素上实现的。其中,animation属性可以接受多个动画效果,用逗号分隔。在这个例子中,表示同时应用ProgressRise和moveScaleRight两个动画效果。*/ animation: ProgressRise 2s ease, moveScaleRight 2s 4.6s alternate ease-out infinite; transform-origin: left center;}/* 当页面首屏渲染进度条的宽度 */@keyframes ProgressRise { 0% { width: 0; } 100% { width: 100%; } }@keyframes moveScaleRight { from { transform: translate3d(0, 0, 0) scale3d(1, 1, 1) skewX(0deg); } to { transform: translate3d(0, 0, 0) scale3d(1.04, 1, 1) skewX(0deg); }}排名徽章需要跟着进度条一起弹性摇摆。首先先延迟4.6秒后,无限次移动该元素X轴的位置,并且使用了alternate属性,使得动画在重复播放时会反向播放,实现摇摆动画效果。

<div class="light-theme-0"></div><!--* 排名徽章 *-->.light-theme-0 {position: absolute;top: -6px;right: -34px;width: 22px;height: 22px;background: url('~@/assets/images/bcmixin/1.png') no-repeat center center;background-size: 100% 100%;//这段代码为元素添加了一个名为lightMoveRight的动画效果,持续时间为2秒,时间函数为ease-out,延迟时间为4.6秒,重复次数为无限次,并且使用了alternate属性,使得动画在重复播放时会反向播放。animation: lightMoveRight 2s ease-out 4.6s alternate infinite; //右侧弹性效果动画transform-origin: left center;}@keyframes lightMoveRight {from {transform: translateX(0px);}to {transform: translateX(-8px);}}
当切换下拉菜单时,菜单上会有滚动动画,主要是通过监听touchmove事件来获取菜单元素的transform属性值,计算元素位置后,为元素添加了一个transform属性,使得元素在X轴方向上向右平移,并且添加了一个transition-duration属性,使得元素的变换过程持续时间为0.3秒,实现菜单平滑滚动效果。

图3.
<div class="menu" style="transform: translateX(257px); transition-duration: 0.3s;"><ul><li>菜单项1</li>...</ul></div>document.querySelector('.menu').addEventListener('touchmove', function () {var transformValue = window.getComputedStyle(menu).getPropertyValue('transform')var translateXValue = parseInt(transformValue.split(',')[4])var scrollDistance = 100menu.style.transform = 'translateX(' + (translateXValue + scrollDistance) + 'px)'})
为了让用户可以一屏查看更多关键信息,新增了简洁版页面。切换简洁版时,按钮采用了过渡动画。为按钮元素添加了一个过渡效果,使得元素的所有属性在1秒内发生变化时会平滑过渡。其中当点击按钮时,将会按照1秒时间平滑更换背景图片。

class="bc-controll-zoom-wrap bc-controll-zoom-wrap-deep"></div>{position: fixed;bottom: 30px;right: 0;width: 83px;height: 54px;background: url('../../assets/images/float_btn_2023_618.png');: 100% 100%;: 1999;display: flex;: center;: center;//all表示所有属性都会发生过渡,1s表示过渡的持续时间为1秒transition: all 1s;}{background: url('../../assets/images/float_btn_deep_2023_618.png');: 100% 100%;}
弹框由小变大动画可以为弹框添加一个渐变的放大效果,使得弹框在出现时更加生动、自然,提高用户的体验感。因此竞速榜海报现实用了渐变放大动画。主要是定义了一个名为zoomIn的动画,用于实现元素的缩放效果。在动画开始时,元素的opacity属性为0,即元素完全透明;同时,元素的transform属性为scale3d(0.3, 0.3, 0.3),即元素在三个方向上都缩小了0.3倍。在动画进行到50%时,元素的opacity属性变为1,即元素完全不透明;同时,元素的transform属性不再变化,保持缩小状态。

.zoomIn-enter-active {animation: zoomIn 0.3s;}@keyframes zoomIn {0% {opacity: 0;-webkit-transform: scale3d(0.3, 0.3, 0.3);transform: scale3d(0.3, 0.3, 0.3);}50% {opacity: 1;}
1.2 动画兼容性
// Animation 定义CSS动画效果.animation(@animation) { -webkit-animation:@animation; -moz-animation:@animation; -o-animation:@animation; animation:@animation;}
图6.1.3 海报技术

图8.import { VueCanvasPoster } from 'vue-canvas-poster'export default { components: { VueCanvasPoster, },}this.painting = { width: '334px', height: '600px', top: 0, background: backgroundImage, views: [ { // 小标题背景 type: 'image', url: subTitleBackgroundImage, css: { top: '125px', left: '16px', width: '297px', height: '70px', }, }, //页面文本 { type: 'text', text: currTitle, css: [ { left: '23px', top: '140px', fontFamily: 'PingFangSC-Semibold', fontSize: currTitleFontSize, color: textColor, width: '290px', height: '33px', textAlign: 'center', }, ], }, ... { // 底部白色背景 type: 'rect', css: { bottom: '10px', right: '24px', width: '53px', height: '53px', color: '#fff', }, }, //二维码 { type: 'qrcode', content: qrcodeSrc, css: { bottom: '14px', right: '28px', width: '44px', height: '44px', color: '#000', }, }, ], }1.4 B版竞速榜页面UI升级
图9./* 颜色变量 */@primary-color: #007bff;/* 字体变量 */@font-size-base: 16px;/* 边框变量 */@border-color: #ccc;/* 布局变量 */@container-width: 1200px;/* 动画变量 */@animation-duration: 0.3s;/* 响应式变量 */@screen-xs: 576px;
1.5 实行皮肤选择
用户可以选择皮肤可以提高网站的个性化和用户体验,满足不同用户的需求和喜好,从而提高用户的满意度和忠诚度。
这就需要开发时支持样式配置化,提高网站的开发效率和可维护性,同时也可以减少样式错误和重复代码,提高网站的稳定性和性能。
图10.
图11.//背景颜色this.posterConfig = getConfigBySkin(this.$store.state.skin)let getConfigBySkin = (skin) => { // 默认背景 let config = { globalBg:'#3F2786', //背景图 purpleTitleBg: require('../../../assets/images/skin_purple/bg-time-purple.png'), //标题背景图 rightArrow: require('../../../assets/images/skin_purple_pre/arrow-right.png'), titleBg: require('../../../assets/images/skin_common/purple-title-border.png'), number: 'skin_purple', progressBar: require('../../../assets/images/skin_common/purple-bar.png'), leftBg: require('../../../assets/images/skin_common/digital-l-b.png'), rightBg: require('../../../assets/images/skin_common/digital-r-t.png'), } //获取背景图片'red'、'golden'、'purple'、'blue' switch (skin) { case 'red': config.globalBg = '#780605' config.number = 'skin_red' ... break case 'blue': ... break case 'golden': ... break } return config}1.6 快照模式
为了满足用户查看历史关键节点数据的诉求,添加了快照模式来实现。具体方案如下:

1.7 价格安全升级
由于竞速榜单访问量很高,吸引了大量爬虫对价格数据的抓取和滥用,这样会侵犯网站数据隐私,影响接口稳定性,破坏业务利益。那接口加反爬可以有效防止恶意爬虫对价格数据的抓取和滥用,保护商家的利益和数据安全,同时也可以提高网站的稳定性和性能,提升用户的体验感。
图13.1.8 调试技巧
竞速榜H5页面主要在京东APP以及微信中打开,如果发现报错等问题,无法在手机中调出开发者工具进行排查。vconsole是一个轻量级的前端调试工具,可以在移动端页面中方便地查看日志、调试代码、性能分析等,帮助开发者快速定位和解决问题,提高开发效率和质量。因此,加入vconsole可以方便地进行移动端页面的调试和优化,提高开发效率和用户体验。当URL中加入vconsole=1的参数时,会显示控制台,提效移动端排查效率。
图14.

/** * 参数携带了vconsole,就启用vconsole */import VConsole from 'vconsole'if (location.href.indexOf('vconsole') !== -1) { import('vconsole').then(({ default: VConsole }) => { new VConsole(); })}
图16./*** 返回结果处理控制器** @param {function} resolve promise resolve function* @param {function} reject promise reject function* @param {object} result 接口返回数据* @param {boolean} isNeedReject 是否需要执行reject* @param {string} url 请求的接口地址*/const handlerResult = (resolve, reject, result, isNeedReject, url) => {//是否需要跳转const nojump = getQueryString('nojump') === '1'switch (result.code) {//时间小于“活动对外时间”或者时间大于“活动下线时间”case '103':if (nojump) {console.log('nojump非跳转模式', '状态码:103', '时间小于“活动对外时间”或者时间大于“活动下线时间”', '请求接口:', url, '当前页面地址:', location.href)} else {window.location.href = '//}breakcase '200':resolve(result.data)break//未登录ERP / 登录异常 / 活动类型有误case '401':window.location.href = `//ssa.jd.com/sso/login?ReturnUrl=${encodeURIComponent(location.href)}`break...}}
1.9 取消接口
当页面跳转或关闭时,需要取消正在进行的请求,避免出现响应错误,以及浪费服务器资源和带宽的情况。
图17.1.10 轮询接口异常3次跳兜底页面
由于竞速榜要求实时性非常高,每秒都会轮询拿最新数据。为了避免因为网络波动或服务器异常等原因导致的偶发性错误,实行轮询接口3次调用出异常后才跳错误页面的做法。从而提高网站的稳定性和用户体验。如果只是偶发性的错误,那么用户在第一次或第二次尝试时可能会重新尝试,而不会立即放弃,从而减少了用户的流失率。同时,这种做法也可以减少因为网络波动或服务器异常等原因导致的误报,避免对用户造成不必要的困扰和影响。
图18.1.11 本地包拆分命令
"start:dev": "node script/switch_env_server.js dev && cross-env BUILD_ENV=dev vue-cli-service serve --open","start:prod": "node script/switch_env_server.js prod && cross-env vue-cli-service serve --open","start:mock": "node script/switch_env_server.js local && cross-env MOCK=true vue-cli-service serve --open","build:dev": "node script/switch_env_build.js dev && cross-env BUILD_ENV=dev npm run oss","build:prod": "node script/switch_env_build.js prod && cross-env BUILD_ENV=prod npm run oss"
图19.1.12 监控

图20、21.
本文介绍了京东竞速榜H5页面的核心前端技术,这些技术可以帮助开发者更好地开发H5页面,提高网站的质量和用户满意度。同时,我们还有一些未来的规划,如进一步加速页面加载速度、优化页面结构和布局、加强网站的可访问性等方面,以适应不断变化的市场需求和用户需求。未来,我们将继续关注H5页面的前沿技术和发展趋势,不断探索和实践新的技术方案,为用户提供更好的体验和服务。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70024420/viewspace-2986528/ ,如需转载,请注明出处,否则将追究法律责任。