异步文档树解决方案

最近有个文档树选择需求,然后自己动手封装了个jq插件

方法只是简单封装了一下,未做过多处理,可根据业务需求自由定制

兼容:(>=ie7)

敬上代码,抛砖引玉

调用

    var $btn = $('.btn');

    $btn.click(function(){
      $(this).asyncSelectTree();
    })

 

方法

(function($){
  // 模拟全局参数
  var config = {}
  // 全局变量
  var $this = '' ;//获取控件
  var $container = ''; //获取容器
  var $tree = ''; //列表树

  // 模拟参数
  var res = [
    {
      title: "test",
      child:[
        {
          title: "test1",
          child: []
        },
        {
          title: "test2",
          child: []
        },
        {
          title: "test3",
          child: []
        },
        {
          title: "test4",
          child: []
        }
      ]
    },
    {
      title: "admin",
      child:[
        {
          title: "admin1",
          child: []
        },
        {
          title: "admin2",
          child: []
        },
        {
          title: "admin3",
          child: []
        },
        {
          title: "admin4",
          child: []
        }
      ]
    },
    {
      title: 'member',
      child: []
    }
  ]
  $.fn.asyncSelectTree = function(conf){
    // 接收配置参数
    // config = conf;
    $this = $(this);

    // 初始化布局
    initLayout();
  }

  // 初始化布局
  function initLayout(){
    var astId = $this.prop('id')?$this.prop('id'): (new Date).valueOf();
    astId = 'ast_'+astId
    $container = $(
      '<div class="ast-container" id="'+ astId +'">\
        <div class="ast-wrap">\
        <div class="ast-title">选择父资源id</div>\
          <div class="ast-tree"></div>\
          <div class="ast-footer">\
            <button class="ast-btn ast-ok">确定</button>\
            <button class="ast-btn ast-no">取消</button>\
          </div>\
        </div>\
      </div>'
    );
    $this.after($container);

    // 获取确定,取消按钮
    var $ok = $container.find('.ast-btn.ast-ok');
    var $no = $container.find('.ast-btn.ast-no');
    $tree = $container.find('.ast-tree');
    
    // 创建树
    var tree = createTreeNode(res,true);
    $tree.append(tree)
    
    // 选择节点
    $tree.on('click', '.lt-title', function(e){
      var $ev = $(e.target);
      // 判断是否生成节点,是则不再生成
      if($ev.next('.lt-child').length){
        $ev.next('.lt-child').toggle();
      }else{
        var index = $ev.data('index');
        // 获取返回模板
        var $resTree = createTreeNode(res);
        // 插入模板
        $ev.after($resTree);
      }

      // 切换图标
      $ev.toggleClass("toggle");
    })

    // 选择树叶
    $tree.on('click', '.lt-leaf', function(e){
      var $ev = $(e.target);
      $container.find('.lt-leaf').removeClass("current");
      $ev.addClass("current");
    })
    


    $ok.click(function(){
      
      $container.remove();
    })
    $no.click(function(){
      
      $container.remove();
    })
  }

  // 创建树节点 levelTree---lt
  function createTreeNode(data,firstCall){
    var createTreeTemp = ''
    if(firstCall){
      createTreeTemp += '<div class="lt">'
    }else{
      createTreeTemp += '<div class="lt-child">'
    }
    $.each(data,function(n,item){
      if(item.child && item.child.length){
        createTreeTemp += '\
          <div class="lt-node"><div class="lt-title" data-index="'+ n +'">'+ item.title +'</div></div>\
        ';
      }else{
        createTreeTemp += '\
          <div class="lt-leaf">'+ item.title +'</div>\
        ';
      }
    })
    
    createTreeTemp += '</div>'

    return createTreeTemp

  }


  // 获取浏览器信息
  var browserInfo = function() {
    var NT = {
        '4.90': 'Windows ME',
        '4.0': 'Windows NT',
        '5.0': 'Windows 2000',
        '5.01': 'Windows 2000 SP1',
        '5.1': 'Windows XP',
        '5.2': 'Windows XP 64-bit / Windows Server 2003',
        '6.0': 'Windows Vista / Windows Server 2008',
        '6.1': 'Windows 7 / Windows Server 2008 R2',
        '6.2': 'Windows 8',
        '6.3': 'Windows 8.1',
        '6.4': 'Windows 10 Technical Preview',
        '10.0': 'Windows 10'
    }
    var userAgent = navigator.userAgent.toLowerCase();
    var platform = navigator.platform;
    var browserName = /(msie\s|trident.*rv:)([\w.]+)/.test(userAgent) ? 'Internet Explorer': (window.opera && window.opera.version ? 'Opera': ((userAgent.indexOf('edge') > -1) ? 'Microsoft Edge': ((userAgent.indexOf('chrome') > -1) ? 'Chrome': ((userAgent.indexOf("firefox") > -1) ? 'Firefox': (userAgent.indexOf('safari') > -1 ? 'Safari': 'Unknown')))));
    var browserVersion = browserName == 'Internet Explorer' ? (userAgent.indexOf('rv:') > -1 ? userAgent.match(/rv:[\d.]+/gi)[0].replace('rv:', '') : userAgent.match(/msie\s[\d.]+/gi)[0].replace('msie ', '')) : (browserName == 'Microsoft Edge' ? userAgent.match(/edge\/[\d.]+/gi)[0].replace('edge/', '') : (browserName == 'Firefox' ? userAgent.match(/firefox\/[\d.]+/gi)[0].replace('firefox/', '') : (browserName == 'Chrome' ? userAgent.match(/chrome\/[\d.]+/gi)[0].replace('chrome/', '') : (browserName == 'Safari' ? userAgent.match(/safari\/[\d.]+/gi)[0].replace('safari/', '') : 'Unknown'))));
    var browserEdition = browserVersion.split('.')[0];
    var kernelName = userAgent.indexOf('trident') > -1 ? 'Trident': userAgent.indexOf('edge') > -1 ? 'Edge': (((userAgent.indexOf('applewebkit') > -1) ? 'Webkit': ((userAgent.indexOf('gecko') > -1) ? 'Gecko': 'Unknown')));
    var kernelVersion = kernelName == 'Trident' ? (userAgent.match(/Trident\/[\d.]+/gi)[0].replace('Trident/', '')) : (browserName == 'Firefox' ? userAgent.match(/gecko\/[\d.]+/gi)[0].replace('gecko/', '') : ((browserName == 'Chrome' || browserName == 'Safari') ? userAgent.match(/applewebkit\/[\d.]+/gi)[0].replace('applewebkit/', '') : (browserName == 'Microsoft Edge' ? userAgent.match(/edge\/[\d.]+/gi)[0].replace('edge/', '') : 'Unknown')));
    var kernelEdition = kernelVersion.split('.')[0];
    var osName = userAgent.indexOf('android') > -1 ? 'Android': (userAgent.indexOf('ipad') > -1 ? 'iOS(iPad)': (userAgent.indexOf('iphone') > -1 ? 'iOS(iPhone)': userAgent.indexOf('windows phone') > -1 ? 'Windows Phone': (((platform == "Win32") || (platform == "Windows") ? 'Microsoft Windows': (navigator.platform == "Mac68K") || ((navigator.platform == "MacPPC") || (navigator.platform == "Macintosh") || (navigator.platform == "MacIntel") ? 'Apple Mac': 'Unknown')))));
    var osEdition = osName == 'Android' ? userAgent.match(/android\s[\d.]+/gi)[0].replace('android ', '') : ((osName == 'iOS(iPad)' || osName == 'iOS(iPhone)') ? userAgent.match(/os\s[\d_]+/gi)[0].replace('os ', '').replace('_', '.') : (osName == 'Windows Phone' ? userAgent.match(/windows\sphone\s[\d.]+/gi)[0].replace('windows phone ', '').replace('_', '.') : (osName == 'Microsoft Windows' ? (NT[userAgent.match(/windows\snt\s[\d.]+/gi)[0].replace('windows nt ', '')] ? NT[userAgent.match(/windows\snt\s[\d.]+/gi)[0].replace('windows nt ', '')] : 'Unknown') : 'Unknown')));
    return {
        browser: {
            name: browserName,
            edition: browserEdition,
            version: browserVersion
        },
        kernel: {
            name: kernelName,
            edition: kernelEdition,
            version: kernelVersion
        },
        os: {
            name: osName,
            edition: osEdition
        }
    };
  }
})(jQuery)

 

样式

.ast-container{
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(51,51,51,0.3);
    color: #333;
}
.ast-container .ast-wrap{
    position: absolute;
    top: 50%;
    left: 50%;
    background: white;
    display: inline-block;
    width: 600px;
    text-align: left;
    margin-top: -350px;
    margin-left: -300px;
}
.ast-container .ast-title{
    padding-left: 10px;
    height: 40px;
    line-height: 40px;
    border-bottom: 1px solid #f1f1f1;
    background: #f8f8f8;
}
.ast-container .ast-tree{
    padding: 20px 20px 40px;
    height: 600px;
    width: 400px;
    display: inline-block;
    overflow: auto
}
.ast-container .ast-footer{
    text-align: right;
    padding: 5px 0;
    padding-right: 20px;
    border-top: 1px solid #f1f1f1;
}
.ast-container .ast-btn{
    height: 26px;
    line-height: 26px;
    padding: 0 15px;
    margin-right: 10px;
    background: transparent;
    border: 1px solid #999;
    color: #333;
    outline: none;
    cursor: pointer;
}
.ast-container .ast-btn.ast-ok{
    border-color: #1e9fff;
    background-color: #1e9fff;
    color: #fff;
}
.ast-container .ast-btn:hover{
    opacity: 0.7;
}
.ast-container .lt{
    /* display: inline-block; */
}
.ast-container .lt-title:before{
    content: '+';
    position: relative;
    width: 10px;
    left: -5px;
    text-align: right;
    margin-right: 5px;
}
.ast-container .lt-title.toggle:before{
    content: '-';
}
.ast-container .lt-node{
    padding-left: 0px;
}
.ast-container .lt-title{
    cursor: pointer;
    line-height: 26px;
    white-space: nowrap;
}
.ast-container .lt-title:hover{
    color: #333;
}
.ast-container .lt>.lt-child,.ast-container .lt-node>.lt-child{
    padding-left: 20px;
    line-height: 26px;
}
.ast-container .lt .lt-leaf{
    white-space: nowrap;
    cursor: pointer;
}
.ast-container .lt .lt-leaf:before{
    content: '·';
    position: relative;
    display: inline-block;
    width: 10px;
    left: -5px;
    text-align: center;
    margin-right: 5px;
}
/* .ast-container .lt .lt-leaf:hover{
    color: red;
    cursor: pointer;
} */
.ast-container .lt .lt-leaf.current{
    /* color: red; */
}
.ast-container .lt .lt-leaf.current:after{
    content: "√";
    display: inline-block;
    width: 16px;
    height: 16px;
    line-height: initial;
    margin-left: 5px;
    background: #0ad30a;
    border-radius: 50%;
    color: white;
    vertical-align: middle;
    text-align: center;
    font-size: 12px;
}

/* --取消双击选中-- */
.ast-container .lt{
    -moz-user-select:none;/*火狐*/
    -webkit-user-select:none;/*webkit浏览器*/
    -ms-user-select:none;/*IE10*/
    -khtml-user-select:none;/*早期浏览器*/
        user-select:none;
}

 

posted @ 2018-07-05 10:00  欲戴王冠,必承其重  阅读(221)  评论(0编辑  收藏  举报