用javascript作一个通用向导说明


Posted in Javascript onAugust 30, 2011

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

Javascript 相关文章推荐
文本框根据输入内容自适应高度的代码
Oct 24 Javascript
利用javascript数组长度循环数组内所有元素
Dec 27 Javascript
js完美解决IE6不支持position:fixed的bug
Apr 24 Javascript
JavaScript中setUTCFullYear()方法的使用简介
Jun 12 Javascript
【JS+CSS3】实现带预览图幻灯片效果的示例代码
Mar 17 Javascript
BootStrap Table 后台数据绑定、特殊列处理、排序功能
May 27 Javascript
bootstrap timepicker在angular中取值并转化为时间戳
Jun 13 Javascript
Node.js中,在cmd界面,进入退出Node.js运行环境的方法
May 12 Javascript
在Vue项目中取消ESLint代码检测的步骤讲解
Jan 27 Javascript
vue实现在线翻译功能
Sep 27 Javascript
解决vue项目刷新后,导航菜单高亮显示的位置不对问题
Nov 01 Javascript
nuxt 路由、过渡特效、中间件的实现代码
Nov 06 Javascript
JS 无限级 Select效果实现代码(json格式)
Aug 30 #Javascript
javascript 原型继承介绍
Aug 30 #Javascript
dojo学习第二天 ajax异步请求之绑定列表
Aug 29 #Javascript
非常强大的 jQuery.AsyncBox 弹出对话框插件
Aug 29 #Javascript
新浪微博字数统计 textarea字数统计实现代码
Aug 28 #Javascript
Javascript面向对象编程(三) 非构造函数的继承
Aug 28 #Javascript
Javascript面向对象编程(二) 构造函数的继承
Aug 28 #Javascript
You might like
在线增减.htpasswd内的用户
2006/10/09 PHP
PHP数组排序函数合集 以及它们之间的联系分析
2013/06/27 PHP
PHP中让curl支持sock5的代码实例
2015/01/21 PHP
PHP生成二维码与识别二维码的方法详解【附源码下载】
2019/03/07 PHP
php传值和传引用的区别点总结
2019/11/19 PHP
JavaScript动态修改背景颜色的方法
2015/04/16 Javascript
jQuery ajax时间差导致的变量赋值问题分析
2016/01/22 Javascript
JavaScript数据结构与算法之链表
2016/01/29 Javascript
Bootstrap每天必学之工具提示(Tooltip)插件
2016/04/26 Javascript
JavaScript的变量声明提升问题浅析(Hoisting)
2016/11/30 Javascript
浅谈js中用$(#ID)来作为选择器的问题(id重复的时候)
2017/02/14 Javascript
canvas 实现中国象棋
2017/02/17 Javascript
深入浅析Vue.js中 computed和methods不同机制
2018/03/22 Javascript
详解jQuery中的easyui
2018/09/02 jQuery
详解将微信小程序接口Promise化并使用async函数
2019/08/05 Javascript
[54:19]完美世界DOTA2联赛PWL S2 Magma vs PXG 第二场 11.28
2020/12/01 DOTA
简述Python中的面向对象编程的概念
2015/04/27 Python
Python实现将DOC文档转换为PDF的方法
2015/07/25 Python
浅谈pyhton学习中出现的各种问题(新手必看)
2017/05/17 Python
浅谈python正则的常用方法 覆盖范围70%以上
2018/03/14 Python
Python3+OpenCV2实现图像的几何变换(平移、镜像、缩放、旋转、仿射)
2019/05/13 Python
Python OpenCV视频截取并保存实现代码
2019/11/30 Python
python 使用事件对象asyncio.Event来同步协程的操作
2020/05/04 Python
Python正则re模块使用步骤及原理解析
2020/08/18 Python
python实现企业微信定时发送文本消息的实例代码
2020/11/25 Python
牦牛毛户外探险服装:Kora
2019/02/08 全球购物
TheFork葡萄牙:欧洲领先的在线餐厅预订平台
2019/05/27 全球购物
小蚁科技官方商店:YI Technology
2019/08/23 全球购物
办公室副主任岗位职责
2013/11/25 职场文书
夜班门卫岗位职责
2013/12/09 职场文书
学前教育毕业生自荐信范文
2013/12/24 职场文书
党校培训思想汇报
2014/01/03 职场文书
公共场所标语
2014/06/30 职场文书
创业计划书之熟食店
2019/10/16 职场文书
详解Django中 render() 函数的使用方法
2021/04/22 Python
python 爬取京东指定商品评论并进行情感分析
2021/05/27 Python