欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS中多步驟多分步的StepJump組件實例詳解

 更新時間:2016年04月01日 09:27:15   投稿:mrr  
這篇文章主要介紹了JS中多步驟多分步的StepJump組件實例詳解的相關(guān)資料,需要的朋友可以參考下

最近的工作在做一個多步驟多分步的表單頁面,這個多步驟多分步的意思是說這個頁面的業(yè)務是分多個步驟完成的,每個步驟可能又分多個小步驟來處理,大步驟之間,以及小步驟之間都是一種順序發(fā)生的業(yè)務關(guān)系。起初以為這種功能很好做,就跟tab頁的實現(xiàn)原理差不多,真做下來才發(fā)現(xiàn),這里面的相關(guān)邏輯還是挺多的(有可能是我沒想到更好地辦法~),尤其是當這個功能跟表單,還有業(yè)務數(shù)據(jù)的狀態(tài)結(jié)合起來的時候。我把這個功能相關(guān)的一些邏輯抽象成了一個組件StepJump,這個組件能夠?qū)崿F(xiàn)純靜態(tài)的分步切換和跳轉(zhuǎn),以及跟業(yè)務相結(jié)合的復雜邏輯,有一定的通用性和靈活性,本文主要介紹它的功能要求和實現(xiàn)思路。

實現(xiàn)效果:


里面有兩個效果頁面:demo.html和regist.html,相關(guān)js分別是demo.js和regist.js,組件封裝在stepJump.js里面,采用seajs做的模塊化。demo.html演示的是一個純靜態(tài)的多步驟多分步的內(nèi)容切換,regist.html是一個完整地跟業(yè)務結(jié)合起來的效果,是我從最近的工作中抽出來的,只不過里面的業(yè)務數(shù)據(jù)狀態(tài)是用一個常量(STEP_STATUS)來模擬的。


1. 需求分析

前面給的效果圖不完整,但是設計圖太大,不方便貼出。為了把這個頁面的功能要求描述清楚,我只能盡可能地在文字上多花功夫,盡量把每一個細節(jié)都講清楚:

1)這個頁面一共有四個大步驟,其中1,3,4都只對應了一個小步驟,而2對應了三個小步驟,也就說1,3,4分別是1步就能完成的,而2需要3步才能完成;

2)這些步驟是順序發(fā)生的關(guān)系,必須先完成第1大步,才能進行第2大步;必須先完成第1個小步,才能進行第2個小步;

3)每個大步驟的第一個小步可能有一個按鈕能夠返回到上一大步;

4)每個大步驟位于中間的小步可能有2個按鈕,一個返回上一小步,一個跳轉(zhuǎn)到下一小步;

5)每個大步驟的最后一個小步可能有一個按鈕能夠跳轉(zhuǎn)到下一大步;

6)如果一個大步驟只包含一個小步驟,那么它既是第一個小步,也是最后一個小步;

7)每個大步驟的每個小步驟要顯示的內(nèi)容都是不一樣的,每次只能顯示一個小步驟;

8)已經(jīng)完成的大步驟,正在進行的大步驟,后面待執(zhí)行的大步驟,應該具有不同的UI效果;(不過從實現(xiàn)效果來說,已經(jīng)完成的跟正在執(zhí)行做成了一個效果)

9)后面待執(zhí)行的大步驟必須通過上一個大步驟最后一個小步驟里面的按鈕點擊才能跳轉(zhuǎn);已經(jīng)完成的和正在執(zhí)行的大步驟可通過點擊步驟名稱跳轉(zhuǎn);

10)點擊大步驟名稱時,跳轉(zhuǎn)至該大步驟的第一個小步。

以上部分是頁面的靜態(tài)功能分析,下面要分析的是該頁面實際的業(yè)務需求:

1)這個頁面是開放給登錄用戶使用的,用來給某個平臺做用戶入住申請用的,只有完成這個入住流程,才能正式進入平臺使用其它功能;

2)主要的業(yè)務數(shù)據(jù)都是跟用戶相關(guān)的,按入住流程來說,用戶的入住流程狀態(tài)可以分為:

a. 待填寫資料,如果每次進入這個頁面時是這個狀態(tài)值,那么就顯示【1 入住須知】這個大步驟,表示正在進行該步驟;

b. 待提交資料,如果每次進入這個頁面時是這個狀態(tài)值,那么就顯示【2 公司信息提交】這個大步驟,小步驟默認顯示它的第一個;

c. 審核未通過,如果每次進入這個頁面時是這個狀態(tài)值,那么就顯示【3 等待審核】這個大步驟;

d. 審核已通過,如果每次進入這個頁面時是這個狀態(tài)值,那么就顯示【3 等待審核】這個大步驟;

e. 待確認合同,如果每次進入這個頁面時是這個狀態(tài)值,那么就顯示【4 合同簽訂】這個大步驟;

3)需要注意的是【3 等待審核】和【4 合同簽訂】各包含3個和2個內(nèi)容,它們各自的這幾個內(nèi)容是互斥顯示的關(guān)系,但是它們不是分步的關(guān)系,具體要顯示哪個完全是由業(yè)務狀態(tài)決定的。比如說【3 等待審核】有下面3種可能的效果:



 

當從【2 公司信息提交】跳轉(zhuǎn)到【3 等待審核】顯示第一個效果;
如果進入頁面時是審核已通過的狀態(tài)顯示第2個效果;
如果進入頁面時是審核未通過的狀態(tài)顯示第3個效果,而且這個情況下,步驟名稱還有特殊效果要求:

當直接點擊步驟名稱時,比如點擊【2 公司信息提交】,這個效果得還原成默認的效果;當再點擊【3 等待審核】,又得設置成這種特殊的效果;只有通過【2 公司信息提交】的小步跳轉(zhuǎn)到【3 等待審核】時,才能完全撤銷這種特殊效果。

大體上的需求就是以上這些部分,可能還有一些細節(jié)沒有描述,因為用文字不太容易說清楚,所以只能根據(jù)實際效果去體會了。 從最終實現(xiàn)來說,前面的需求中,靜態(tài)功能需求才是組件實現(xiàn)的核心,后面的業(yè)務需求并不具備通用性,我開發(fā)這個組件的出發(fā)點是根據(jù)靜態(tài)功能需求寫出組件的基本功能,然后再結(jié)合業(yè)務需求設計合理的API跟回調(diào),并且盡可能地將js與html分離,組件與業(yè)務分離,以便最終的實現(xiàn)能夠?qū)㈧`活性最大化。

2. 實現(xiàn)思路

首先說html結(jié)構(gòu):我考慮在前面的需求中,有2個很重要的概念:大步驟,小步驟,并且這些大步驟跟小步驟有包含關(guān)系,步驟之間還有順序的約定,所以得設計兩個集合,分別用來存放所有大步驟相關(guān)項和所有小步驟相關(guān)項,html結(jié)構(gòu)可以設計如下:

- Hide code
<nav class="nav-step">
<ul id="steps" class="steps">
<li><a href="javascript:;">1<span class="gap"></span>入住須知</a></li>
<li><a href="javascript:;">2<span class="gap"></span>公司信息提交</a></li>
<li><a href="javascript:;">3<span class="gap"></span>等待審核</a></li>
<li><a href="javascript:;">4<span class="gap"></span>合同簽訂</a></li>
</ul>
</nav>
<div id="step-content" class="step-content">
<div class="step-pane" >
</div>
<div class="step-pane">
</div>
<div class="step-pane">
</div>
<div class="step-pane">
</div>
<div class="step-pane">
</div>
<div class="step-pane"
</div>
</div>

其中#steps li 就是所有的大步驟項,所有的#step-content .step-pane就是所有的小步驟項。這兩個集合僅僅解決了步驟項的存放和順序問題,對于它們之間的包含關(guān)系還沒有解決。在需求當中,大步驟與小步驟是這樣的包含關(guān)系:

這樣的話,我們只要通過一個簡單的配置數(shù)組就能把這種關(guān)系體現(xiàn)出來,比如以上這個結(jié)構(gòu)就可以用[1,3,1,1]來說明,表示一共有4個大步驟,其中1,3,4都只有一個小步驟,2有3個小步驟。由于大步驟與小步驟是分開存放在兩個集合里面的,所以我們在對這兩個集合進行存取的時候,都用的是相對集合的索引位置,但是在實際使用過程中:大步驟的位置是比較好識別的,小步驟的絕對位置就不好識別了,而且相對集合的位置都是從0開始,如果每個小步的內(nèi)容里面都有定義其它的一些組件,比如表單相關(guān)的組件,我們肯定會把這些組件的實例存放到一個配置表里:

var STEP_CONFIG = {
0: {
form: {
//....
}
},
1: {
form: {
//....
}
},
2: {
form: {
//....
}
},
3: {
form: {
//....
}
}
//...
}

這種配置表是按小步驟的絕對索引來標識的,在實際使用的時候會很不方便,而且當小步的html結(jié)構(gòu)有調(diào)整的時候,這個結(jié)構(gòu)就得改,所有引用到它來獲取相關(guān)組件的地方都得改。最好是完成下面這種配置方式:

var STEP_PANES_CONFIG = {
//2,1表示第二個步驟的第一個小步內(nèi)容
//2,2表示第二個步驟的第二個小步內(nèi)容
//2,3表示第二個步驟的第三個小步內(nèi)容
2: {
1: {
//配置小步驟相關(guān)的東西
},
2: {
//配置小步驟相關(guān)的東西
},
3: {
//配置小步驟相關(guān)的東西
}
//配置大步驟相關(guān)的東西
}
}

相當于把前面的包含結(jié)構(gòu)抽象成:

這個結(jié)構(gòu)有兩個好處:一是不考慮集合索引從0開始的問題,STEP_PANES_CONFIG[2]就表示第2個大步驟;二是小步驟的索引也不考慮從0開始的問題,而且是相對大步驟來標識的,比如STEP_PANES_CONFIG[2][1]就表示第2個大步驟的第一個小步,這樣的話,大步驟跟小步驟就都能很好的通過索引來識別,配置表也更穩(wěn)定一點。也就是說組件在對外提供索引相關(guān)的接口或參數(shù)的時候,都是按常規(guī)思維方式提供的,在組件內(nèi)部得解決邏輯索引(比如[2][1])跟物理索引的轉(zhuǎn)化關(guān)系,以及物理索引跟邏輯索引的轉(zhuǎn)換關(guān)系。比如外部調(diào)用的時候,告訴組件初始化需要顯示第2大步的第1個小步,那么組件就得根據(jù)這個信息找到相應的大小步驟項去顯示;外部已知步驟項的物理索引位置時,組件得提供方法能夠?qū)⑽锢硭饕恢棉D(zhuǎn)換成邏輯索引。

再來說效果:

1)每個步驟的內(nèi)容只要控制顯示哪個即可,所以步驟內(nèi)容如果用css來控制狀態(tài)的話就只有2種,默認態(tài)和active態(tài),默認態(tài)不顯示,active態(tài)顯示;

2)每個步驟的邊角可以用css邊框畫三角的原理實現(xiàn);

3)為了正確控制步驟的效果,每個步驟如果用css來控制狀態(tài)的話有3種,默認態(tài),done態(tài)和current態(tài),分別表示未執(zhí)行,已執(zhí)行和正在執(zhí)行的步驟。另外第三大步還有一個alerts態(tài),不過這是一個跟業(yè)務相關(guān)的狀態(tài),跟組件倒是沒有關(guān)系。這三個狀態(tài)的控制實現(xiàn),跟網(wǎng)上那種評分組件是類似的。

大概的思路就是這些,另外還有關(guān)于API和回調(diào)的設計,我會在下一部分的實現(xiàn)細節(jié)里去描述。

3. 實現(xiàn)細節(jié)

先來看看組件的配置項:

var DEFAULTS = {
config: [], //必傳參數(shù),步驟項與步驟內(nèi)容項的配置,如[1,2,3]表示一共有三個(config.length)步驟,第1個步驟有1個(config[0])內(nèi)容項,第2個步驟有2個(config[1])內(nèi)容項,第3個步驟有3個(config[2])內(nèi)容項
stepPanes: '', //必傳參數(shù),步驟內(nèi)容項的jq 選擇器
navSteps: '', //必傳參數(shù),步驟項的jq 選擇器
initStepIndex: 1, //初始時顯示的步驟位置,如果一共有4個步驟,該參數(shù)可選值為:1,2,3,4
initPaneIndex: 1, //初始時顯示的步驟內(nèi)容項位置,基于initStepIndex,如果initStepIndex設置成2,且該步驟有3個內(nèi)容項,則該參數(shù)可選值為:1,2,3
onStepJump: $.noop, //步驟項跳轉(zhuǎn)時候的回調(diào)
onBeforePaneChange: $.noop, //步驟內(nèi)容項切換之前的回調(diào)
onPaneChange: $.noop, //步驟內(nèi)容項切換之后的回調(diào)
onPaneLoad: $.noop //步驟內(nèi)容項第一次顯示時的回調(diào)
};

注釋部分已經(jīng)說得比較清楚了,前5個在實現(xiàn)思路里面都有相關(guān)內(nèi)容提及。下面我把那四個回調(diào)作用和調(diào)用做一個詳細說明:

1)onStepJump(oldStepIndex, targetStep)

這個回調(diào)是在大步驟跳轉(zhuǎn)的時候觸發(fā)的,作用很清楚,就是為了在步驟跳轉(zhuǎn)的時候做一些邏輯處理,比如業(yè)務需求中【3 等待審核】的特殊效果控制就得借助這個回調(diào),傳遞有兩個參數(shù)oldStepIndex表示跳轉(zhuǎn)前的步驟的物理索引(從0開始), targetStep表示要跳轉(zhuǎn)到的步驟的物理索引。

2)onBeforePaneChange(currentPane, targetPane, currentStep)

這個回調(diào)的作用是在切換小步驟的時候,可能小步驟里面有的表單校驗未通過,此時就得取消小步驟的切換,通過在這個回調(diào)里返回false就能達到這個效果。傳遞的三個參數(shù)都是物理索引,分別表示當前小步驟的位置,要切換的小步驟位置和當前大步驟的位置。

3)onPangeChange(currentPane, targetPane, currentStep)

這個跟第二個是差不多的,只不過發(fā)生在小步驟切換完成之后調(diào)用。

4)onPaneLoad(e,currentStep, currentPane)

這個回調(diào)作用很大,小步驟里面的其它組件,比如表單組件等,都可以在這個回調(diào)里定義,目的是為了實現(xiàn)延遲初始化的功能。同時這個回調(diào)在執(zhí)行的時候已經(jīng)把this指向了當前小步驟對應的DOM元素,以便可以快速地通過該DOM元素找到其它組件初始化需要的子元素,比如form等。這個回調(diào)對于每個小步驟來說都只會觸發(fā)一次。傳遞三個參數(shù)e表示相關(guān)的jq事件,后面兩個分別表示當前大步驟和小步驟的物理索引。

回調(diào)觸發(fā)順序是:onBeforePaneChange,onPangeChange,onPaneLoad,onStepJump。另外onPaneLoad在組件初始化完成的時候也會調(diào)用一次。

通過以上這些回調(diào)基本上就能解決前面業(yè)務需求的那些問題。

再來看看API,我根據(jù)前面的需求只考慮3個API實例方法:

return {
goStep: function(step) {
goStep(step - 1);
},
goNext: function() {
go(currentPane + 1);
},
goPrev: function() {
go(currentPane - 1);
}
}

goStep可以跳轉(zhuǎn)到指定步驟的第一個小步,goNext跳轉(zhuǎn)到下一個小步,goPrev跳轉(zhuǎn)到上一個小步。另外還有一個靜態(tài)方法:

//根據(jù)步驟內(nèi)容項的絕對索引位置,獲取相對于步驟項的位置
//step從0開始,pane表示絕對索引位置,比如stepPanes一共有6個,那么pane可能的值就是0-5
//舉例:config: [1,3,1,1], step: 2, pane: 4,就會返回1,表示第三個步驟的第1個步驟內(nèi)容項的位置
StepJump.getRelativePaneIndex = function(config, step, pane) {
return pane - getPaneCountBeforeStep(config, step) + 1;
};

因為前面那些回調(diào)傳遞的參數(shù)都是物理索引,外部如果需要把物理索引轉(zhuǎn)換成邏輯索引的話,就得使用這個方法。

其它細節(jié)說明:

1)maxStepIndex

這個變量也很關(guān)鍵,通過它來控制哪些大步驟不能通過直接點擊的方式來跳轉(zhuǎn)。

2)大步驟項的UI控制

//步驟項UI控制
function showStep(targetStep) {
$navSteps.each(function(i) {
var cname = this.className;
cname = $.trim(cname.replace(/current|done/g, ''));
if (i < targetStep) {
//當前步驟之前的狀態(tài)全部設置為done
cname += ' done';
} else if (i == targetStep) {
//當前步驟項狀態(tài)設置為current
cname += ' current';
}
this.className = cname;
});
}

整體實現(xiàn)如下,代碼優(yōu)化程度受水平限制,但是邏輯還是很清楚的:

define(function(require, exports, module) {
var $ = require('jquery');
//step: 表示步驟項
//pane: 表示步驟內(nèi)容項
var DEFAULTS = {
config: [], //必傳參數(shù),步驟項與步驟內(nèi)容項的配置,如[1,2,3]表示一共有三個(config.length)步驟,第1個步驟有1個(config[0])內(nèi)容項,第2個步驟有2個(config[1])內(nèi)容項,第3個步驟有3個(config[2])內(nèi)容項
stepPanes: '', //必傳參數(shù),步驟內(nèi)容項的jq 選擇器
navSteps: '', //必傳參數(shù),步驟項的jq 選擇器
initStepIndex: 1, //初始時顯示的步驟位置,如果一共有4個步驟,該參數(shù)可選值為:1,2,3,4
initPaneIndex: 1, //初始時顯示的步驟內(nèi)容項位置,基于initStepIndex,如果initStepIndex設置成2,且該步驟有3個內(nèi)容項,則該參數(shù)可選值為:1,2,3
onStepJump: $.noop, //步驟項跳轉(zhuǎn)時候的回調(diào)
onBeforePaneChange: $.noop, //步驟內(nèi)容項切換之前的回調(diào)
onPaneChange: $.noop, //步驟內(nèi)容項切換之后的回調(diào)
onPaneLoad: $.noop //步驟內(nèi)容項第一次顯示時的回調(diào)
};
function StepJump(options) {
var opts = $.extend({}, DEFAULTS, options),
$stepPanes = $(opts.stepPanes),
$navSteps = $(opts.navSteps),
config = opts.config,
stepPaneCount = sum.apply(null, config), //步驟內(nèi)容項的總數(shù)
currentStep = opts.initStepIndex - 1, //當前步驟項的索引
currentPane = sum.apply(null, config.slice(0, currentStep)) + (opts.initPaneIndex - 1), //當前內(nèi)容項的索引
maxStepIndex = currentStep, //允許通過直接點擊步驟項跳轉(zhuǎn)的最大步驟項位置
$activePane = $stepPanes.eq(currentPane);
//注冊僅觸發(fā)一次的stepLoad事件
$stepPanes.each(function() {
$(this).one('stepLoad', $.proxy(function() {
opts.onPaneLoad.apply(this, [].slice.apply(arguments).concat([currentStep, currentPane]));
}, this));
});
//初始化UI
showStep(currentStep);
$activePane.addClass('active').trigger('stepLoad');
//注冊點擊步驟項的回調(diào)
$navSteps.on('click.step.jump', function() {
var $this = $(this),
step = $this.index(opts.navSteps); //找到當前點擊步驟項在所有步驟項中的位置
if (step > maxStepIndex || $this.hasClass('current')) return;
//跳轉(zhuǎn)到該步驟項的第一個步驟內(nèi)容項
goStep(step);
});
//步驟項UI控制
function showStep(targetStep) {
$navSteps.each(function(i) {
var cname = this.className;
cname = $.trim(cname.replace(/current|done/g, ''));
if (i < targetStep) {
//當前步驟之前的狀態(tài)全部設置為done
cname += ' done';
} else if (i == targetStep) {
//當前步驟項狀態(tài)設置為current
cname += ' current';
}
this.className = cname;
});
}
function goStep(step) {
go(getPaneCountBeforeStep(config, step));
}
//通過步驟內(nèi)容項查找步驟項的位置
function getStepByPaneIndex(targetPane) {
var r = 0,
targetStep = 0;
for (var i = 0; i < stepPaneCount; i++) {
r = r + config[i];
if (targetPane < r) {
targetStep = i;
break;
}
}
return targetStep;
}
function go(targetPane) {
if (targetPane < 0 || targetPane >= stepPaneCount) {
return;
}
//在切換步驟內(nèi)容項之前提供給外部的回調(diào),以便外部可以對當前步驟內(nèi)容項做一些校驗之類的工作
//如果回調(diào)返回false則取消切換
var ret = opts.onBeforePaneChange(currentPane, targetPane, currentStep);
if (ret === false) return;
var $targetPane = $stepPanes.eq(targetPane),
targetStep = getStepByPaneIndex(targetPane);
$activePane.removeClass('active');
$targetPane.addClass('active');
opts.onPaneChange(currentPane, targetPane, currentStep);
$activePane = $targetPane;
currentPane = targetPane;
var oldStepIndex = currentStep;
currentStep = targetStep;
currentStep > maxStepIndex && (maxStepIndex = currentStep);
$targetPane.trigger('stepLoad');
if (targetStep !== oldStepIndex) {
showStep(targetStep);
opts.onStepJump(oldStepIndex, targetStep);
}
}
return {
goStep: function(step) {
goStep(step - 1);
},
goNext: function() {
go(currentPane + 1);
},
goPrev: function() {
go(currentPane - 1);
}
}
}
//根據(jù)步驟內(nèi)容項的絕對索引位置,獲取相對于步驟項的位置
//step從0開始,pane表示絕對索引位置,比如stepPanes一共有6個,那么pane可能的值就是0-5
//舉例:config: [1,3,1,1], step: 2, pane: 4,就會返回1,表示第三個步驟的第1個步驟內(nèi)容項的位置
StepJump.getRelativePaneIndex = function(config, step, pane) {
return pane - getPaneCountBeforeStep(config, step) + 1;
};
//求和
//注:slice(start,end)返回的數(shù)據(jù)不包含end索引對應的元素
function sum() {
var a = [].slice.apply(arguments),
r = 0;
a.forEach(function(n) {
r = r + n;
});
return r;
}
//統(tǒng)計在指定的步驟項之前一共有多少個步驟內(nèi)容項,step從0開始,比如config: [1,3,1,1], 當step=2,就會返回4
function getPaneCountBeforeStep(config, step) {
return sum.apply(null, config.slice(0, step));
}
return StepJump;
});

4. 調(diào)用舉例

demo.html里的使用方式:

define(function(require, exports, module) {
var $ = require('jquery');
var StepJump = require('components/stepJump'),
stepJump = new StepJump({
config: [1,3,1,1],
stepPanes: '#step-content .step-pane',
navSteps: '#steps > li',
initStepIndex: 1
});
$(document).on('click.stepPane.switch', '.btn-step', function(e) {
var $this = $(this);
if ($this.hasClass('next')) {
stepJump.goNext();
} else {
stepJump.goPrev();
}
});
});

由于這是個靜態(tài)的功能,所以不用加任何回調(diào)。

regist.html里的使用方式:

//STEP_STATUS取值:
//0 待填寫資料,如果每次進入這個頁面時是這個狀態(tài)值,那么就顯示【1 入住須知】這個大步驟,表示正在進行該步驟;
//1 待提交資料,如果每次進入這個頁面時是這個狀態(tài)值,那么就顯示【2 公司信息提交】這個大步驟,小步驟默認顯示它的第一個;
//2 審核未通過,如果每次進入這個頁面時是這個狀態(tài)值,那么就顯示【3 等待審核】這個大步驟;
//3 審核已通過,如果每次進入這個頁面時是這個狀態(tài)值,那么就顯示【3 等待審核】這個大步驟;
//4 待確認合同,如果每次進入這個頁面時是這個狀態(tài)值,那么就顯示【4 合同簽訂】這個大步驟;
var STEP_STATUS = 3,
MODE = STEP_STATUS == 2 || STEP_STATUS == 4 ? 3 : 2, //3表示只讀,在公司信息提交步驟只能看不能改
STEP_AUDIT_ALERTS = STEP_STATUS == 3, //這個變量用來控制在等待審核步驟的時候是否給步驟項添加alerts樣式
STEP_STATUS_MAP = {
0: 1,
1: 2,
2: 3,
3: 3,
4: 4
},
initStepIndex = STEP_STATUS_MAP[STEP_STATUS],
STEP_PANES_DATA = [1, 3, 1, 1],
STEP_PANES_CONFIG = {
//3,1表示第三個步驟的第一個步驟內(nèi)容
3: {
1: {
onPaneLoad: function(e, currentStep, currentPane, conf) {
var $stepPane = $(this);
conf.vc = new VisibleController($stepPane.children('div'));
if (STEP_AUDIT_ALERTS) {
$auditStep = $('#audit-step');
$auditStep.addClass('alerts');
conf.vc.show('#audit-no');
} else if (STEP_STATUS == 2 || STEP_STATUS == 4) {
conf.vc.show('#audit-yes');
} else {
conf.vc.show('#audit-wait');
}
}
},
onLeaveStep: function() {
STEP_AUDIT_ALERTS && $auditStep.removeClass('alerts');
},
onEnterStep: function(step, conf) {
if (STEP_AUDIT_ALERTS) {
$auditStep.addClass('alerts');
} else {
conf[1].vc.show('#audit-wait');
}
}
},
4: {
1: {
onPaneLoad: function(e, currentStep, currentPane, conf) {
var $stepPane = $(this);
conf.vc = new VisibleController($stepPane.children('div'));
conf.vc.show('#contract-confirm');
}
}
}
},
GET_STEP_PANES_CONFIG = function(step, pane) {
if (pane == undefined) return STEP_PANES_CONFIG[step + 1];
return STEP_PANES_CONFIG[step + 1] && STEP_PANES_CONFIG[step + 1][StepJump.getRelativePaneIndex(STEP_PANES_DATA, step, pane)];
};
var $auditStep,
stepJump = new StepJump({
config: STEP_PANES_DATA,
stepPanes: '#step-content .step-pane',
navSteps: '#steps > li',
initStepIndex: initStepIndex,
onBeforePaneChange: function(currentPane, targetPane, currentStep) {
var conf = GET_STEP_PANES_CONFIG(currentStep, currentPane);
return conf && conf.onBeforePaneChange && conf.onBeforePaneChange.apply(this, [].slice.apply(arguments).concat[conf]);
},
onPaneChange: function() {
window.scrollTo(0, 0);
},
onPaneLoad: function(e, currentStep, currentPane) {
var conf = GET_STEP_PANES_CONFIG(currentStep, currentPane);
conf && conf.onPaneLoad && conf.onPaneLoad.apply(this, [].slice.apply(arguments).concat([conf]));
},
onStepJump: function(currentStep, targetStep) {
var conf = GET_STEP_PANES_CONFIG(currentStep);
conf && conf.onLeaveStep && conf.onLeaveStep(currentStep, conf);
conf = GET_STEP_PANES_CONFIG(targetStep);
conf && conf.onEnterStep && conf.onEnterStep(targetStep, conf);
}
});

StepJump組件的初始化在最后面,前面都是一些配置相關(guān)的內(nèi)容。更換STEP_STAUS這個變量的值,就能模擬實際業(yè)務中的不同業(yè)務狀態(tài),就能看到不同狀態(tài)進入頁面時這個組件的顯示的效果。

5. 小結(jié)

本文把最近工作的一部分成果總結(jié)了一下,提供了一個StepJump組件,也許在你的工作中也有用得著的地方,當然每個人的思路跟做法都不一定相同,我也僅僅是分享的目的。其實這幾天的工作思考的東西還是挺多的,除了這個組件之外,更多的想法都集中在樣式分離,CSS命名跟表單組件的分離這一塊,只不過現(xiàn)在這些思想還不夠系統(tǒng),還不到總結(jié)分享的水平,這些工作方法層面的理論,很少人去總結(jié)跟分享,我目前只見到張鑫旭的博客上有較完整的一套思路,學習下來,確實有不少收獲跟體會,但是這畢竟是別人的,有一些只可意會不可言傳的精華,還是掌握不到,只能一步步去積累才行,等將來我自己的思路成形了,我會考慮把我的想法全部分享出來,相信這件事情會成為我今年分享的最有價值的內(nèi)容。

以上內(nèi)容給大家介紹了JS中多步驟多分步的StepJump組件,希望對大家有所幫助!

相關(guān)文章

最新評論