基于jQuery实现Accordion手风琴自定义插件


Posted in Javascript onOctober 13, 2020

目前网上有很多各种各样的手风琴插件,但是没有一个完整实现了的侧菜单,今天写了一个可以无限子节点的手风琴侧菜单,有需要的可以参考一下,有什么好的想法可以留言。(没有经过彻底测试,不过问题应该不大)

下面老规矩,直接贴代码:

(function ($) {
 'use strict';
 var defaults = {
  url: null,
  param: {},
  data: {},
  fill: true,
  level_space: 15,
  onitemclick: null,
  style: {
   header: "accordion-header",
   header_title: "accordion-header-title",
   content: "accordion-content",
   selected: "selected",
   icon_base: "fa",
   icon_collapse: "fa-angle-up",
   icon_expand: "fa-angle-down"
  }
 }
 var methods = {
  init: function (options) {
   return this.each(function () {
    var $this = $(this);
    if (!$this.hasClass("accordion")) {
     $this.addClass("accordion");
    }
    var settings = $this.data('tw.accordion');
    if (typeof (settings) == 'undefined') {
     settings = $.extend({}, defaults, options);
     $this.data('tw.accordion', settings);
    } else {
     settings = $.extend({}, settings, options);
     $this.data('tw.accordion', settings);
    }
    if (settings.url) {
     $.ajax({
      type: "post",
      async: false,
      url: settings.url,
      data: settings.param,
      success: function (data) {
       settings.data = data;
      }
     });
    }
    if (settings.fill) {
     $this.height("100%");
    }
    if (settings.data.length > 0) {
     $this.data("count", settings.data.length);
     $.each(settings.data, function () {
      this.level = 1;
      var item = $this.accordion("add", this);
      $this.append(item);
     });
     if ($this.find("." + settings.style.selected).length == 0) {
      var data = $this.find(">li:first-child").data("data");
      $this.accordion("select", data);
     }
    }
   });
  },
  add: function (data) {
   var $this = $(this);
   var settings = $this.data("tw.accordion");
   var item = $("<li class='" + settings.style.header + "'></li>");
   item.data("data", data);
   var header = $("<div class='" + settings.style.header_title + "' data-accordion='" + data.id + "'>" +
    "<i class='" + settings.style.icon_base + "" + data.icon + "'></i>" +
    "<span>" + data.name + "</span></div>");
   header.css("padding-left", settings.level_space * data.level);
   item.append(header);
   if (data.childrens) {
    var toggle = $("<i class='" + settings.style.icon_base + "" + settings.style.icon_collapse + "'></i>");
    toggle.css({ "font-size": "1.4em", "position": "absolute", "top": "7px", "right": "7px" });
    header.append(toggle);
    var content = $("<ul class='" + settings.style.content + "'></ul>");
    content.data("count", data.childrens.length);
    $.each(data.childrens, function () {
     this.level = data.level + 1;
     var child = $this.accordion("add", this);
     content.append(child);
    });
    item.append(content);
   }
   header.click(function () {
    $this.accordion("select", data);
   });
   if (data.selected) {
    $this.accordion("select", data);
   }
   return item;
  },
  select: function (data) {
   var $this = $(this);
   var settings = $this.data("tw.accordion");
   var header = $this.find("[data-accordion='" + data.id + "']");
   var item = header.parent();
   if (!header.hasClass(settings.style.selected) && !item.hasClass(settings.style.selected)) {
    var sibling = item.siblings();
    sibling.removeClass(settings.style.selected).children("." + settings.style.selected).removeClass(settings.style.selected);
    sibling.children("." + settings.style.icon_expand).removeClass(settings.style.icon_expand).addClass(settings.style.icon_collapse);
    if (data.childrens) {
     item.addClass(settings.style.selected);
     header.find("." + settings.style.icon_collapse).removeClass(settings.style.icon_collapse).addClass(settings.style.icon_expand);
     if (settings.fill) {
      var count = item.parent().data("count") - 1;
      item.css("height", "calc(100% - " + (item.height() * count) + "px)");
     }
    } else {
     header.addClass(settings.style.selected);
    }
   }
   if (settings.onitemclick) {
    settings.onitemclick(data);
   }
  },
  update: function (url, param) {
   var $this = $(this);
   var settings = $this.data("tw.accordion");
   if (typeof url == "object") {
    settings.param = url;
   } else {
    settings.url = url;
    settings.param = param;
   }
   $this.accordion("init", settings);
  },
  destroy: function (options) {
   return $(this).each(function () {
    var $this = $(this);
    $this.removeData('accordion');
   });
  }
 }
 $.fn.accordion = function () {
  var method = arguments[0];
  var args = arguments;
  if (typeof (method) == 'object' || !method) {
   method = methods.init;
  } else if (methods[method]) {
   method = methods[method];
   args = $.makeArray(arguments).slice(1);
  } else {
   $.error('Method ' + method + ' does not exist on tw.accordion');
   return this;
  }
  return method.apply(this, args);
 }
})(jQuery);
.accordion {
 margin:0;
 padding:0;
 font-size:14px;
}
 .accordion > .accordion-header {
  list-style: none;
  margin: 0;
  padding: 0;
  border-bottom: 1px solid #ddd;
 }
  .accordion > .accordion-header.selected > .accordion-header-title {
   color: #0094ff;
  }
  .accordion > .accordion-header > .accordion-header-title {
   position: relative;
   width: 100%;
   height: 35px;
   line-height: 35px;
   background: #eee;
   border-bottom: 1px solid #ccc;
   cursor: pointer;
  }
   .accordion > .accordion-header > .accordion-header-title > i:first-child {
    font-size: 1.3em;
   }
   .accordion > .accordion-header > .accordion-header-title > span {
    position: relative;
    top: -1px;
    left: 5px;
   }
  .accordion > .accordion-header > .accordion-content {
   display: none;
   width: 100%;
   height: calc(100% - 35px);
   margin: 0;
   padding: 0;
  }
  .accordion > .accordion-header.selected > .accordion-content {
   display: block;
  }
.accordion-content > .accordion-header {
  list-style: none;
  margin: 0;
  padding: 0;
}
 .accordion-content > .accordion-header.selected {
  color: #0094ff;
 }
 .accordion-content > .accordion-header > .accordion-header-title {
  position: relative;
  width: 100%;
  height: 32px;
  line-height: 32px;
  cursor: pointer;
  border-bottom: 1px solid #ccc;
 }
  .accordion-content > .accordion-header > .accordion-header-title:hover {
   background:#eee;
  }
  .accordion-content > .accordion-header > .accordion-header-title.selected {
   color: #fff;
   background: #0094ff;
   border-left: 3px solid #ff6a00;
   border-bottom: 0px;
  }
   .accordion-content > .accordion-header > .accordion-header-title > i:first-child {
    font-size: 1.2em;
   }
   .accordion-content > .accordion-header > .accordion-header-title > span {
    position: relative;
    top: -1px;
    left: 5px;
   }
   .accordion-content > .accordion-header > .accordion-header-title.selected > i:first-child {
    position:relative;
    left:-3px;
   }
   .accordion-content > .accordion-header > .accordion-header-title.selected > span {
    position: relative;
    top: -1px;
    left: 2px;
   }
  .accordion-content > .accordion-header > .accordion-content {
   display: none;
   width: 100%;
   height: calc(100% - 32px);
   margin: 0;
   padding: 0;
  }
  .accordion-content > .accordion-header.selected > .accordion-content {
   display: block;
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery Ajax文件上传(php)
Jun 16 Javascript
一些经常会用到的Javascript检测函数
May 31 Javascript
Javascript 闭包引起的IE内存泄露分析
May 23 Javascript
JS替换字符串中字符即替换全部而不是第一个
Jun 04 Javascript
Document.body.scrollTop的值总为零的快速解决办法
Jun 09 Javascript
前端框架Vue.js构建大型应用浅析
Sep 12 Javascript
JavaScript中双符号的运算详解
Mar 12 Javascript
JS Testing Properties 判断属性是否在对象里的方法
Oct 01 Javascript
jQuery实现导航样式布局操作示例【可自定义样式布局】
Jul 24 jQuery
jquery判断滚动条距离顶部的距离方法
Sep 05 jQuery
如何在Vue中使用CleaveJS格式化你的输入内容
Dec 14 Javascript
jQuery实现图片切换效果
Oct 19 jQuery
详解JSON1:使用TSQL查询数据和更新JSON数据
Nov 21 #Javascript
js原生实现FastClick事件的实例
Nov 20 #Javascript
常用原生js自定义函数总结
Nov 20 #Javascript
浅谈js之字面量、对象字面量的访问、关键字in的用法
Nov 20 #Javascript
浅谈jquery选择器 :first与:first-child的区别
Nov 20 #Javascript
关于js函数解释(包括内嵌,对象等)
Nov 20 #Javascript
浅谈js函数中的实例对象、类对象、局部变量(局部函数)
Nov 20 #Javascript
You might like
PHP使用array_merge重新排列数组下标的方法
2015/07/22 PHP
jQuery 数据缓存data(name, value)详解及实现
2010/01/04 Javascript
jQuery html() in Firefox (uses .innerHTML) ignores DOM changes
2010/03/05 Javascript
早该知道的7个JavaScript技巧
2013/03/27 Javascript
JS字符串拼接在ie中都报错的解决方法
2014/03/27 Javascript
Extjs的FileUploadField文件上传出现了两个上传按钮
2014/04/29 Javascript
javascript移动设备Web开发中对touch事件的封装实例
2014/06/05 Javascript
AngularJS中的过滤器使用详解
2015/06/16 Javascript
深入理解JavaScript中的箭头函数
2015/07/28 Javascript
Bootstrap每天必学之响应式导航、轮播图
2016/04/25 Javascript
深究AngularJS——ng-checked(回写:带真实案例代码)
2017/06/13 Javascript
从0到1搭建Element的后台框架的方法步骤
2019/04/10 Javascript
详解微信小程序-获取用户session_key,openid,unionid - 后端为nodejs
2019/04/29 NodeJs
Vue实现圆环进度条的示例
2021/02/06 Vue.js
[01:11:28]DOTA2-DPC中国联赛定级赛 RNG vs Phoenix BO3第一场 1月8日
2021/03/11 DOTA
Python基础篇之初识Python必看攻略
2016/06/23 Python
为Python的Tornado框架配置使用Jinja2模板引擎的方法
2016/06/30 Python
Python对数据进行插值和下采样的方法
2018/07/03 Python
OpenCV2从摄像头获取帧并写入视频文件的方法
2018/08/03 Python
Python基础学习之类与实例基本用法与注意事项详解
2019/06/17 Python
华为2019校招笔试题之处理字符串(python版)
2019/06/25 Python
python中property属性的介绍及其应用详解
2019/08/29 Python
python 实现Flask中返回图片流给前端展示
2020/01/09 Python
基于python 凸包问题的解决
2020/04/16 Python
浅析Python 中的 WSGI 接口和 WSGI 服务的运行
2020/12/09 Python
美国婴儿和儿童家具网上商店:ABaby.com
2018/07/02 全球购物
创业计划书六个要素
2013/12/26 职场文书
八年级英语教学反思
2014/01/09 职场文书
副护士长竞聘演讲稿
2014/04/30 职场文书
关于环保的活动方案
2014/08/25 职场文书
骨干教师事迹材料
2014/12/17 职场文书
婚宴来宾致辞
2015/07/28 职场文书
关于元旦的广播稿2016
2015/12/17 职场文书
护理专业毕业自我鉴定
2019/08/12 职场文书
pytorch训练神经网络爆内存的解决方案
2021/05/22 Python
Python+Pillow+Pytesseract实现验证码识别
2022/05/11 Python