用一个js做全站导航菜单

结构简单,可定制性强
服务器君一共花费了142.607 ms进行了4次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

向导可以让你的网站用户快速上手使用你的web应用,提高网站的吸引力。向导一般分为好几个步骤,每个步骤收集一些数据,并且支持退回功能,所有步骤完成后可以得到每一步的收集结果。这里给大家展示一种比较通用,灵活且简单的向导框架。

index.html:只提供了一个向导显示位置的占位符

<html>
    <head>
        <title>简明现代魔法 - www.nowamagic.net</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;
}

向导可以分为每一步骤,每个步骤需要呈现内容,捕捉用户选择,提供标题等功能,我们让每一步都自己负责自己的事情,但要符合我们规定的一些契约。每一个步骤用一个函数表示,第一个参数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];
}

向导类要设置向导所在的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]);
}

本向导结构简单,可定制性强,结合了javascript的函数式编程特性和面向对象的特性,体现了javascript的强大和便利。其中wizard类里界面绘制的部分和步骤函数里界面绘制的部分还是存在一些耦合,继续重构的话,可以把所有绘制界面的部分再抽象到一起,使界面改动更方便。

本文地址:http://www.nowamagic.net/librarys/veda/detail/1657,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/1657

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《JavaScript高级程序设计(第2版)》 尼古拉斯·泽卡斯(Nicholas C.Zakas) (作者), 李松峰 (译者), 曹力 (译者)

《JavaScript高级程序设计(第2版)》在上一版基础上进行了大幅度更新和修订,融入了近几年来JavaScript应用发展的最新成果,几乎涵盖了所有需要理解的重要概念和最新的JavaScript应用成果。从颇具深度的JavaScript语言基础到作用域(链),从引用类型到面向对象编程,从极其灵活的匿名函数到闭包的内部机制,从浏览器对象模型(BOM)、文档对象模型(DOM)到基于事件的Web脚本设计,从XML(E4X)到Ajax及JSON,从高级前端开发技术到前沿的客户端存储,从最佳编程实践到即将成为现实的API,直至JavaScript未来的发展,全景式地展示了JavaScript高级程序设计的方方面面。

更多计算机宝库...