本文將探究京東競速榜H5頁面的核心前端技術,包括動畫、樣式配置化、皮膚切換、海報技術、調試技巧等方面,希望能夠為廣大前端開發者提供一些有用的參考和思路。 ...
前言
H5頁面作為移動端Web應用的重要形式之一,已經成為了現代Web開發的熱門話題。在H5頁面的開發過程中,前端技術的應用至關重要。本文將探究京東競速榜H5頁面的核心前端技術,包括動畫、樣式配置化、皮膚切換、海報技術、調試技巧等方面,希望能夠為廣大前端開發者提供一些有用的參考和思路。
技術要點
一、動畫
為提高用戶體驗,使頁面更加生動有趣,提高用戶的滿意度和留存率,頁面中添加了多個動畫。
其中為了突出頁面中的重點內容競速排名,添加了進度條、徽章、菜單、按鈕和彈框等動畫。
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);
}
}
1.2、徽章左右搖擺動畫
排名徽章需要跟著進度條一起彈性搖擺。首先先延遲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);
}
}
1.3、菜單滾動動畫
當切換下拉菜單時,菜單上會有滾動動畫,主要是通過監聽touchmove事件來獲取菜單元素的transform屬性值,計算元素位置後,為元素添加了一個transform屬性,使得元素在X軸方向上向右平移,並且添加了一個transition-duration屬性,使得元素的變換過程持續時間為0.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 = 100
menu.style.transform = 'translateX(' + (translateXValue + scrollDistance) + 'px)'
})
1.4、按鈕過渡動畫
為了讓用戶可以一屏查看更多關鍵信息,新增了簡潔版頁面。切換簡潔版時,按鈕採用了過渡動畫。為按鈕元素添加了一個過渡效果,使得元素的所有屬性在1秒內發生變化時會平滑過渡。其中當點擊按鈕時,將會按照1秒時間平滑更換背景圖片。
<div class="bc-controll-zoom-wrap bc-controll-zoom-wrap-deep"></div>
.bc-controll-zoom-wrap {
position: fixed;
bottom: 30px;
right: 0;
width: 83px;
height: 54px;
background: url('../../assets/images/float_btn_2023_618.png');
background-size: 100% 100%;
z-index: 1999;
display: flex;
justify-content: center;
align-items: center;
//all表示所有屬性都會發生過渡,1s表示過渡的持續時間為1秒
transition: all 1s;
}
.bc-controll-zoom-wrap-deep {
background: url('../../assets/images/float_btn_deep_2023_618.png');
background-size: 100% 100%;
}
1.5、彈框由小變大動畫
彈框由小變大動畫可以為彈框添加一個漸變的放大效果,使得彈框在出現時更加生動、自然,提高用戶的體驗感。因此競速榜海報現實用了漸變放大動畫。主要是定義了一個名為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;
}
二、動畫相容性
CSS樣式相容性的作用是確保網頁在不同瀏覽器和設備上都能夠正確地顯示和呈現,提高網頁的相容性和可訪問性。可以定義了一些CSS動畫和過渡效果的Mixin,在其他Less文件中引用這些Mixin來快速定義CSS動畫和過渡效果。CSS動畫相容性用mixin寫法的好處是可以提高CSS代碼的可重用性和可維護性,同時保證在不同瀏覽器中的相容性。具體mixin可參考下麵寫法。主要分為6種效果,animation 動畫效果,transform 變換效果,rotation 旋轉效果、scale 縮放效果、translate3d 平移效果、keyframes 關鍵幀動畫。
// Animation 定義CSS動畫效果
.animation(@animation) {
-webkit-animation:@animation;
-moz-animation:@animation;
-o-animation:@animation;
animation:@animation;
}
三、海報技術
頁面自動生成海報可以提高用戶的互動性和分享性,增強品牌的曝光度和口碑效應,提高用戶留存率和轉化率。將網頁的重要信息自動生成海報,並加上二維碼方便競速榜網頁分享和傳播。那麼純前端怎麼畫海報這塊,就是一個關鍵的技術。競速榜採用了通過 css 屬性畫 canvas 圖片的輕量級的 vue 組件Vue Canvas Poster。它可以使用類css屬性的方式,按照絕對定位佈局生成canvas圖。並且可以通過widthPixels設置生成圖片尺寸,解決圖片模糊問題。其中image屬性用來繪製圖片,text用來繪製文本,rect用來繪製矩形,qrcode用來繪製二維碼。根據width 寬度、height高度、top上邊距、left左邊距,來組裝對應元素位置,繪製海報內容。
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',
},
},
],
}
四、B版競速榜頁面UI升級
競速榜單的不斷升級,將更有效的捲動廠商,同時也能提高榜單引單引流效率,在大促期間成為手機品類與品牌博弈的重要工具之一。因此每年大促都會進行一次UI調整,主要涉及顏色調整。所以我們將主題色提取出,修改公共變數,提高開發效率。主要總結為6種常用變數,顏色、字體、邊框、佈局、動畫、響應式。
/* 顏色變數 */
@primary-color: #007bff;
/* 字體變數 */
@font-size-base: 16px;
/* 邊框變數 */
@border-color: #ccc;
/* 佈局變數 */
@container-width: 1200px;
/* 動畫變數 */
@animation-duration: 0.3s;
/* 響應式變數 */
@screen-xs: 576px;
五、實行皮膚選擇
用戶可以選擇皮膚可以提高網站的個性化和用戶體驗,滿足不同用戶的需求和喜好,從而提高用戶的滿意度和忠誠度。
這就需要開發時支持樣式配置化,提高網站的開發效率和可維護性,同時也可以減少樣式錯誤和重覆代碼,提高網站的穩定性和性能。
首先新增頁面配置後臺,使用戶可以選擇想要的皮膚。
在頁面中載入樣式配置文件,可以通過介面請求載入用戶選擇的皮膚,通過JavaScript動態設置樣式屬性和值,從而快速地修改頁面的樣式,實現頁面主題皮膚更換。
//背景顏色
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、歷史時間生成唯一標識時間戳SnapshotId,與歷史數據一起存儲下來。
2、當用戶選擇快照時間時,根據歷史時間生成唯一標識時間戳SnapshotId,添加到頁面URL中。當頁面進行分享時,SnapshotId可以一起分享。當頁面首屏載入時,讀取Url中的SnapshotId,傳入介面獲得歷史數據展示。
七、價格安全升級
由於競速榜單訪問量很高,吸引了大量爬蟲對價格數據的抓取和濫用,這樣會侵犯網站數據隱私,影響介面穩定性,破壞業務利益。那介面加反爬可以有效防止惡意爬蟲對價格數據的抓取和濫用,保護商家的利益和數據安全,同時也可以提高網站的穩定性和性能,提升用戶的體驗感。
於是競速榜網頁價格信息介面添加網關和對應的SDK完成加密操作。主要通過後臺下發的token和隨機密鑰演算法,由前端將特定信息通過演算法生成簽名,傳遞給後端進行識別,可有效識別/攔截刷單刷券所產生的業務損失,加強介面的對抗性,提升防刷能力。
八、調試技巧
8.1、新增vconsole
競速榜H5頁面主要在京東APP以及微信中打開,如果發現報錯等問題,無法在手機中調出開發者工具進行排查。vconsole是一個輕量級的前端調試工具,可以在移動端頁面中方便地查看日誌、調試代碼、性能分析等,幫助開發者快速定位和解決問題,提高開發效率和質量。因此,加入vconsole可以方便地進行移動端頁面的調試和優化,提高開發效率和用戶體驗。當URL中加入vconsole=1的參數時,會顯示控制台,提效移動端排查效率。
/**
* 參數攜帶了vconsole,就啟用vconsole
*/
import VConsole from 'vconsole'
if (location.href.indexOf('vconsole') !== -1) {
import('vconsole').then(({ default: VConsole }) => {
new VConsole();
})
}
8.2、新增nojump不跳轉
部分異常場景會自動跳轉到其他頁面中,之前異常報錯將被覆蓋無法查看,不利於排查,如當前活動不在對外時間範圍內時,會自動跳轉到首頁。於是需要加上不自動跳轉機制,當URL中加入nojump=1的參數時,頁面停留在當前頁,方便查看異常信息。
/**
* 返回結果處理控制器
*
* @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 = '//www.jd.com'
}
break
case '200':
resolve(result.data)
break
//未登錄ERP / 登錄異常 / 活動類型有誤
case '401':
window.location.href = `//ssa.jd.com/sso/login?ReturnUrl=${encodeURIComponent(location.href)}`
break
...
}
}
九、取消介面
當頁面跳轉或關閉時,需要取消正在進行的請求,避免出現響應錯誤,以及浪費伺服器資源和帶寬的情況。
具體實現方案為讀取介面時生成介面唯一標識,存入全局對象中。再在window對象添加了一個beforeunload事件監聽器,當用戶關閉或刷新頁面時,會執行監聽器中的回調函數。將之前存在全局變數window.globleAxioToken中的請求取消掉。
十、輪詢介面異常3次跳兜底頁面
由於競速榜要求實時性非常高,每秒都會輪詢拿最新數據。為了避免因為網路波動或伺服器異常等原因導致的偶發性錯誤,實行輪詢介面3次調用出異常後才跳錯誤頁面的做法。從而提高網站的穩定性和用戶體驗。如果只是偶發性的錯誤,那麼用戶在第一次或第二次嘗試時可能會重新嘗試,而不會立即放棄,從而減少了用戶的流失率。同時,這種做法也可以減少因為網路波動或伺服器異常等原因導致的誤報,避免對用戶造成不必要的困擾和影響。
十一、本地包拆分命令
為提高開發效率,需要新增多個快捷啟動命令如下所示:
1、啟動本地mock數據環境,方便後端介面未開發好時,前端Mock數據並行開發。
2、啟動測試環境數據環境,方便與後端進行連調。
3、啟動線上數據,模擬用戶真實環境排查問題。
4、編譯測試環境
5、編譯線上環境
"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"
將通過不同命令讀取不同文件,實現不同環境代理不同環境介面。
十二、監控
新增ump監控,每分鐘會去訪問頁面鏈接的連通性,判斷頁面是否返回除了200、301、302的異常狀態碼,如果連續3次頁面訪問異常。如返回異常狀態碼,則通過公司內部聊天工具咚咚、郵件等方式進行消息推送。
總結
本文介紹了京東競速榜H5頁面的核心前端技術,這些技術可以幫助開發者更好地開發H5頁面,提高網站的質量和用戶滿意度。同時,我們還有一些未來的規劃,如進一步加速頁面載入速度、優化頁面結構和佈局、加強網站的可訪問性等方面,以適應不斷變化的市場需求和用戶需求。未來,我們將繼續關註H5頁面的前沿技術和發展趨勢,不斷探索和實踐新的技術方案,為用戶提供更好的體驗和服務。
作者:京東零售 饒恩慧
來源:京東雲開發者社區