用javascript作一个通用向导说明

1、界面设计
index.html:只提供了一个向导显示位置的占位符


代码如下:

<html>
<head>
<title>礼物推荐向导</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="jquery.js" type="text/javascript"></script>
<script src="wizard.js" type="text/javascript"></script>
</head>
<body>
<div id="wizard"></div>
</body>
</html>

style.css:默认情况下向导里有一个h2呈现的标题,一个ul呈现的主要内容,一个div呈现的按钮条,我们简单设计了一下他们的默认外观,实际应用中大家可以自由的美化它们。


代码如下:

body{
margin:0;
}
/*向导容器*/
#wizard{
height:400px;
width:600px;
background-color:#999;
}
/*向导的主体内容,用列表展示*/
#wizard ul{
margin:10px;
height:80%;
}
/*横向显示列表内容*/
#wizard li{
display:inline-block;
margin:10px;
cursor:pointer;
}
/*列表的标题*/
#wizard h2{
margin:10px;
}
/*列表的功能条,如返回按钮*/
#wizard .bar{
margin:10px;
clear:both;
}

2、准备每一步骤

向导可以分为每一步骤,每个步骤需要呈现内容,捕捉用户选择,提供标题等功能,我们让每一步都自己负责自己的事情,但要符合我们规定的一些契约。

每一个步骤用一个函数表示,第一个参数data_key是选择本步骤数据的关键字,一般用于上一个步骤的结果决定下一个步骤显示数据的情况,第二个参数result_callback是个回调函数,就是在本步骤获取结果时调用,它用于和向导类进行通信,向导类在得到上一步的结果后存储结果并跳向到下一步。

该函数返回一个二元组,第一个元素是本步骤的标题,第二个元素是本步骤主体部分的UI。

我们的示例是一个礼物推荐系统,共分三步,第一步选择送礼对象,第二步选择关键字,其中第一步的选择结果会影响到第二步显示,第三步选择价格区间,如下就是代码的实现,其中绘制界面和事件捕捉用了jquery来简化操作。


代码如下:

function step1(data_key, result_callback){
var targets = ['女朋友','男朋友','父亲','妈妈','孩子'];
var warpper = $('<ul></ul>')
$.each(targets, function(k,v){
$('<li>'+v+'</li>').click(function(){result_callback(v)}).appendTo(warpper);
});
return ['第一步:请选择送礼物的对象',warpper];
}
function step2(data_key, result_callback){
var tags = {
'女朋友':['创意','可爱','浪漫','激情','实用','数码',
'自制','毛绒玩具','衣服','包包'],
'男朋友':['男士用品','温馨','实用','数码','创意','衣物'],
'父亲' :['男士用品','健康','植物','衣物'],
'妈妈' :['温馨','健康','创意','护肤品','实用'],
'孩子' :['玩具','学习用品','实用','数码']
};
var warpper = $('<ul></ul>')
$.each(tags[data_key], function(k,v){
$('<li>'+v+'</li>').click(function(){result_callback(v)}).appendTo(warpper);
});
return ['第二步:请选择关键词',warpper];
}
function step3(data_key, result_callback){
var price_level = ['便宜','普通','稍贵','贵重'];
var warpper = $('<ul></ul>')
$.each(price_level, function(k,v){
$('<li>'+v+'</li>').click(function(){result_callback(v)}).appendTo(warpper);
});
return ['第三步:请选择价格区间',warpper];
}

3、向导类的实现

向导类要设置向导所在的DOM元素,要执行的步骤列表,向导完成后执行的回调,向导还应该提供上一步和下一步的方法,所以我们用一个类来表示向导,在构造函数里传入DOM容器,步骤列表和回调函数,用prototype给类增加三个方法。render用来呈现某一步骤的UI,并在本步骤收集结果的回调里推向下一步,如果本步骤是最后一步,则调用向导执行完成的回调函数。

另外两个next和back函数分别是执行上一个步骤和下一个步骤,这两个函数实用index的私有变量来维持整个向导的状态


代码如下:

function Wizard(container, steps, callback){
this.container = container; //向导容器
this.steps = steps; //向导步骤
this.callback = callback; //向导执行完毕执行的回调
this.collect_data = []; //保存向导每一步骤的结果
this.index = -1; //当前执行在那一步骤
}
//绘制某一步骤
Wizard.prototype.render = function(step, this_result){
var me = this;
//执行该步骤并得到该步骤的UI
var to_append = step(this_result,function(result){
me.collect_data.push(result); //收集本步骤结果
//向导执行完毕时调用回调函数,否则执行下一步
if(me.collect_data.length == me.steps.length)
me.callback(me.collect_data);
else
me.next(result);
});
//绘制本步骤的UI
this.container.empty();
this.container.append("<h2>"+to_append[0]+"</h2>");
this.container.append(to_append[1]);
if(this.index > 0){
//后退按钮
this.container.append($("<div class='bar'><a href='javascript:;'>后退</a></div>")
.click(function(){me.back()}
));
}
}
//执行下一步
Wizard.prototype.next = function(this_result){
if(this.index >= this.steps.length -1)
return;
var step = this.steps[++this.index];
this.render(step,this_result);
}
//后退到上一步
Wizard.prototype.back = function(){
if(this.index <= 0)
return;
var step = this.steps[--this.index];
//步骤回到上一步,但上一步的数据需要上上一步的结果来决定
this.collect_data = this.collect_data.slice(0, this.index);
this.render(step, this.collect_data[this.index - 1]);
}

4、小结

本向导结构简单,可定制性强,结合了javascript的函数式编程特性和面向对象的特性,体现了javascript的强大和便利。

其中wizard类里界面绘制的部分和步骤函数里界面绘制的部分还是存在一些耦合,继续重构的话,可以把所有绘制界面的部分再抽象到一起,使界面改动更方便。

(0)

相关推荐

  • 用javascript作一个通用向导说明

    1.界面设计 index.html:只提供了一个向导显示位置的占位符 复制代码 代码如下: <html> <head> <title>礼物推荐向导</title> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <link rel="stylesheet" type="text/css

  • Asp.net中使用DapperExtensions和反射来实现一个通用搜索

    前言 搜索功能是一个很常用的功能,当然这个搜索不是指全文检索,是指网站的后台管理系统或ERP系统列表的搜索功能.常见做法一般就是在搜索栏上加上几个常用字段来搜索.代码可能一般这样实现 StringBuilder sqlStr = new StringBuilder(); if (!string.IsNullOrEmpty(RealName)) { sqlStr.Append(" and RealName = @RealName"); } if (Age != -1) { sqlStr.

  • 详解如何用JavaScript编写一个单元测试

    目录 为什么要进行单元测试? 范围界定和编写单元测试 保持单元测试简短而简单 考虑正面和负面的测试用例 分解长而复杂的函数 避免网络和数据库连接 如何编写单元测试 创建一个新项目 实现一个类 配置和添加我们的第一个单元测试 添加更多单元测试 修复错误 最后 测试代码是确保代码稳定的第一步.能做到这一点的最佳方法之一就是使用单元测试,确保应用程序中的每个较小的功能都按应有的方式运行——尤其是当应用程序接收到极端或无效输入,甚至可能有害的输入时. 为什么要进行单元测试? 进行单元测试有许多不同的方法

  • JavaScript获取一个范围内日期的方法

    本文实例讲述了JavaScript获取一个范围内日期的方法.分享给大家供大家参考.具体分析如下: 指定开始和结束时间,范围该范围内的所有日期放入数组 Date.prototype.addDays = function(days) { var dat = new Date(this.valueOf()); dat.setDate(dat.getDate() + days); return dat; }; function getDates(startDate, stopDate) { var da

  • JavaScript判断一个字符串是否包含指定子字符串的方法

    本文实例讲述了JavaScript判断一个字符串是否包含指定子字符串的方法.分享给大家供大家参考.具体分析如下: 下面的JS代码,为String对象定义了一个contains方法用于判断字符串是否包含子字符串,非常有用. if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(obj, start) { for (var i = (start || 0), j = this.length; i < j; i++) {

  • JavaScript创建一个欢迎cookie弹出窗实现代码

    用JavaScript创建一个欢迎cookie 软件代码编辑器,我用的是editplus:当然还有浏览器. 步骤 先在编辑器里写入代码: 运行代码,并写入自己的名字:得到欢迎cookie.

  • 使用JavaScript实现一个小程序之99乘法表

    废话不多说了,直接给大家贴代码了,具体代码如下所示: <!DOCTYPE html> <html> <head> <title>99乘法表</title> <meta charset="utf-8"> </head> <body> <script type="text/javascript"> for (var i = 1; i <= 9; i++) {

  • JavaScript创建一个object对象并操作对象属性的用法

    本文实例讲述了JavaScript创建一个object对象并操作对象属性的用法.分享给大家供大家参考.具体分析如下: 下面的JS代码创建了一个myMovie对象,并给对象title和director属性赋值,通过Object定义对象,其属性可以不用定义,直接调用即可,非常简单. <script type="text/javascript"> var myMovie = new Object(); myMovie.title = "Aliens"; myM

  • JavaScript求一个数组中重复出现次数最多的元素及其下标位置示例

    本文实例讲述了JavaScript求一个数组中重复出现次数最多的元素及其下标位置.分享给大家供大家参考,具体如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>数组重复次数</title> </head> <body> <script language="Jav

  • 一个通用的Java分页基类代码详解

    分页的基类 import java.util.List; /** * 分页显示的标准类,基本操作,是先给予-当前页数一共的数据条数-每页显示的条数, * 然后在初始化该类,得到总共页数,和开始序号和结束序号, * 然后数据库分页用到开始序号和结束序号,得到数据集合后赋值给该类的list属性, * * 然后把该类发送到jsp页面,进行访问 * @author admin * * @param <T> */ public class PageBean<T> { private int

随机推荐