zoukankan      html  css  js  c++  java
  • jquery插件制作,下拉菜单

    要求输入框点击出现下拉菜单,并实现以下功能:

    1.首先点击地点标签页,选择好地点;

    2.自动显示相应节点标签页显示节点信息,选择好节点

    3.自动显示相应的连接点,选择连接点,连接点被选中并被传送的输入框input控件中

    这个控件实际上要在前面的tab的某个子项选中以后,动态更新后面的tab内容,并且跳到后面的tab,如果tab是最后一页,则将选择内容提交到input中。为了通用性,该控件从外部接收json数据,以及调用参数,可以生成对应下拉菜单。该tab菜单支持层次可以任意设置,根据接收到的json数据的层次,以及level_length限制

    参数:

    data_url:json数据的ajax地址;

    level_length:菜单层次,如果菜单为2层,则即使接收到3层的数据,也只显示二层tab。

     

    例子:

           点击连接点A的输入框

    选择北京

    选错了到地区tab页面重新选择上海

    选择上海东方广场

    选择上海东方广场1号

     

    制作了该控件的jquery插件,格式采用bootstrap的。

    调用方法:

    input控件写成

    <input class="form-control dropdown-toggle"id="dropdownMenu" type="text" value="" size="3"/>

    在script里面调用

    $('#dropdownMenu').endpoint();

    方法:对input元素添加一个兄弟节点(after),该兄弟节点即为下拉菜单,兄弟节点各个元素对click事件进行不同响应。

       1.关闭input里面的data-toggle,否则,bootstrap有一个全局监控,会在你点击地点后立即关闭下拉菜单

      2.使用手动的toggle,开启,关闭下拉菜单

       3.当同一个页面使用多个该控件的实例时候,为了避免控件之间元素的干扰,需要一个全局变量索引_index,表明是那个实例的,设置点击链接为 href='"#region'+_index+'"';这样各个实例之间不会干扰。

    jQuery.parent(expr)           //找父元素

    jQuery.parents(expr)          //找到所有祖先元素,不限于父元素

    jQuery.children(expr)        //查找所有子元素,只会找到直接的孩子节点,不会返回所有子孙

    jQuery.contents()            //查找下面的所有内容,包括节点和文本。

    jQuery.prev()                //查找上一个兄弟节点,不是所有的兄弟节点

    jQuery.prevAll()             //查找所有之前的兄弟节点

    jQuery.next()                //查找下一个兄弟节点,不是所有的兄弟节点

    jQuery.nextAll()             //查找所有之后的兄弟节点

    jQuery.siblings()            //查找兄弟节点,不分前后

    jQuery.find(expr)            //跟jQuery.filter(expr)完全不一样,jQuery.filter(expr)是从初始的

    这个代码经过了好几天的艰辛制作,可以接受json数据,然后生成下拉菜单控件;

    接收的数据格式为:

    json_data= {
            'tabs':[{'code':'region','name':'地区'},{'code':'node','name':'节点'},{'code':'endpoint','name':'连接点'}],
            'content':[
                {'region':{'code':'bj','name':'北京'},
                 'node':{'code':'bjdf','name':'北京东方广场'},
                 'endpoint':{'code':'bjdf1','name':'北京东方广场1号'}
                 },
                {'region':{'code':'bj','name':'北京'},
                 'node':{'code':'bjdf','name':'北京东方广场'},
                 'endpoint':{'code':'bjdf2','name':'北京东方广场2号'}
                 },
                {'region':{'code':'bj','name':'北京'},
                 'node':{'code':'bjyz','name':'北京亦庄广场'},
                 'endpoint':{'code':'bjyz1','name':'北京亦庄广场1号'}
                 },
                {'region':{'code':'bj','name':'北京'},
                 'node':{'code':'bjyz','name':'北京亦庄广场'},
                 'endpoint':{'code':'bjyz2','name':'北京亦庄广场2号'}
                 },
                {'region':{'code':'sh','name':'上海'},
                 'node':{'code':'shdf','name':'上海东方广场'},
                 'endpoint':{'code':'shdf1','name':'上海东方广场1号'}
                 },
                {'region':{'code':'sh','name':'上海'},
                 'node':{'code':'shdf','name':'上海东方广场'},
                 'endpoint':{'code':'shdf2','name':'上海东方广场2号'}
                 },
                {'region':{'code':'sh','name':'上海'},
                 'node':{'code':'shdf','name':'上海东方广场'},
                 'endpoint':{'code':'shdf3','name':'上海东方广场3号'}
                 },
            ]
        }

    菜单的js代码

    /* =========================================================
     * endpoint.js
     * =========================================================
     * Copyright 2016 xuyamin yamin_xu@163.com
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     * ========================================================= */
    
    (function ($) {
        //这里放入插件代码
        var endpoint_index=1;//实例索引,以便于生成的html块中的id不同
        $.fn.endpoint = function(options) { //定义插件的名称,这里为endpoint
            var dft = {
                //以下为该插件的属性及其默认值
                version: "0.1", //版本
                data_url: "/account/endpoint", //json链接
                level_length:2 //菜单层次,如果是三层,显示三层菜单,如果二层,显示二层菜单
            };
            var ops = $.extend(dft,options);//加入外部属性
            json_data=$.ajax({url:dft['data_url'],dataType: "json", async:false});
            var tab_data=$.parseJSON(json_data.responseText);//data的格式 {'tabs':[],'content':{ {},{}}}
            var levels=tab_data['tabs'];
            if (dft.level_length){levels=levels.slice(0,dft.level_length)}
            var style = ''; //调用默认的样式
            var _this=this;
            var _index=endpoint_index;
            var path1=[];//记录已经选择的路径,应该是level1的code,level2的code,level3的code
            endpoint_index=endpoint_index+1;
            var dropdown_tabs='<div class="dropdown-menu" aria-labelledby="'+$(this).attr('id')+'">'+
                '<ul class="nav nav-tabs" role="tablist">';
            for (var i = 0; i < levels.length; i++){
                item =levels[i];
                dropdown_tabs+='<li role="presentation"><a href="#'+item['code']+_index+'" aria-controls="home"'+' value="'+item['code']+'" role="tab" data-toggle="tab">'+item['name']+'</a></li>'
            }
            dropdown_tabs+='</ul>'+
            '<div class="tab-content">';
    
            for (var i = 0; i < levels.length; i++){
                //建立空的标签页内容
                item =levels[i];
                dropdown_tabs+='<div role="tabpanel" class="tab-pane" id="'+item['code']+_index+'" >';
                dropdown_tabs+='</div>'
            }
            dropdown_tabs+='</div>'+'</div>';
    
            function get_active_tab(){
                //获取当前active的tab的名字
                active_tab=$(_this).next().find('ul>li[class="active"]>a')
                return active_tab.attr('value')
            }
    
            function filter_array(choosed_code){
                //该函数根据目前的choosed_code,筛选出content
                filter_str="";
                current_tab=get_active_tab();
                content=tab_data['content'];
                var list=content.filter(function (item){
                    return item[current_tab]['code']==choosed_code
                });
                return list
            }
    
            function get_level_content(tab_code,content){
                //content为经过过滤的列表,返回某个tab页面下面所有项目,不可重复
                var list=[];
                var dict={};
                for (var i = 0; i < content.length; i++){
                    item=content[i];
                    if (!dict[item[tab_code]['code']]){
                        list.push({'code':item[tab_code]['code'],'name':item[tab_code]['name']});
                        dict[item[tab_code]['code']]=true
                    }
    
                }
                return list
            }
            function tab_content(tab_code,content){
                //该函数根据content,创建一个tab页;content是经过筛选过的
                content_page='<div role="tabpanel" class="tab-pane active" id="'+tab_code+_index+'" >';
                content_list=get_level_content(tab_code,content);
                for (var i = 0; i < content_list.length; i++){
                    item=content_list[i];
                    content_page+='<a value="'+item['code']+'">'+item['name']+'</a><br>'
                }
                content_page+='</div>';
                //找到相应的标签页,将其内容替换
                $(_this).next().find('#'+tab_code+_index).prop('outerHTML', content_page);
            }
            function get_next_tab(tab_code){
                //根据目前code获取下个code,到最后一页则返回空
                find_next=false;
                next_tab_code=false;
                for (var i = 0; i < levels.length; i++){
                    item=levels[i];
                    if (item['code']==tab_code) {find_next=true;continue;}
                    if (find_next) {next_tab_code=item['code'];break;}
                }
                return next_tab_code
            }
    
            function choose(choosed_code){
                //在当前tab下选择了某个标签,获取下个tab,以及下个tab的内容,并将其组合
                current_tab=get_active_tab();//当前的tab页
                next_tab=get_next_tab(current_tab);
                content_list=filter_array(choose_code);
                if (next_tab)
                {//有下个tab
                    tab_content(next_tab,content_list);//刷新下个页面的内容
                    return next_tab;//返回选中tab
    
                }
                else{//没有下个tab
                    return false
                }
    
            }
            $(this).after(dropdown_tabs); //下拉菜单载入
            $(this).click(function(){
                //点击input时候,初始化第一个标签
                tab_code=levels[0]['code'];
                content_list=tab_data['content'];
                tab_content(tab_code,content_list);
                reg_click(tab_code);
                $(this).next().toggle();
                $(this).next().find('a[href="#'+tab_id+'"]').tab('show');
            });
    
            function reg_click(tab_code){
                //注册某个tab的click响应事件
                tab_id=tab_code+_index;
                $(_this).next().find('#'+tab_id).find('a').click(function(e){
                    choose_code=$(this).attr('value');
                    next_tab=choose(choose_code);//
                    next_tab_id=next_tab+_index;
                    if (next_tab) {
                        reg_click(next_tab);//重新注册一下click事件,因为该tab该被生成}
                        $(this).parents('.dropdown-menu').children('.nav-tabs').find('a[href="#'+next_tab_id+'"]').tab('show');
                    }
    
                    else{
                        //最后一个标签页
                        $(this).parents('.dropdown-menu').prev().val($(this).text());
                        $(this).parents('.dropdown-menu').toggle();
                    }
                })
            }
        }
    })(jQuery);
  • 相关阅读:
    Java进阶之并发初探
    Java进阶之HashMap剖析
    Java进阶之反射
    Linux常用命令
    海量数据处理算法与面试题
    一些刷题时总结的重要知识点
    一些Java刷题时的小知识点
    九章算法知识点与题目总结(不定时更新...)
    c++设计模式之状态模式
    c++设计模式之抽象工厂模式
  • 原文地址:https://www.cnblogs.com/yasmi/p/5292402.html
Copyright © 2011-2022 走看看