├── .gitignore ├── images ├── down.png └── up.png ├── package.json ├── LICENSE ├── css ├── jquery.accordion.css └── demo.css ├── README.md ├── index.html └── js └── jquery.accordion.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /images/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vctrfrnndz/jquery-accordion/HEAD/images/down.png -------------------------------------------------------------------------------- /images/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vctrfrnndz/jquery-accordion/HEAD/images/up.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-accordion", 3 | "version": "1.0.0", 4 | "description": "jQuery Accordion", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/vctrfrnndz/jquery-accordion.git" 10 | }, 11 | "author": "Victor Fernandez", 12 | "license": "MIT", 13 | "bugs": { 14 | "url": "https://github.com/vctrfrnndz/jquery-accordion/issues" 15 | }, 16 | "homepage": "https://github.com/vctrfrnndz/jquery-accordion#readme" 17 | } 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 vctrfrnndz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /css/jquery.accordion.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Accordion 0.0.1 3 | * (c) 2014 Victor Fernandez 4 | * MIT Licensed. 5 | */ 6 | 7 | /* Requirements */ 8 | 9 | [data-accordion] [data-content] { 10 | overflow: hidden; 11 | max-height: 0; 12 | } 13 | 14 | /* Basic Theme */ 15 | 16 | [data-accordion] { 17 | line-height: 1; 18 | } 19 | 20 | [data-control], 21 | [data-content] > * { 22 | border-bottom: 1px solid #888; 23 | padding: 10px; 24 | } 25 | 26 | [data-content] [data-accordion] { 27 | border: 0; 28 | padding: 0; 29 | } 30 | 31 | [data-accordion] [data-control] { 32 | position: relative; 33 | padding-right: 40px; 34 | } 35 | 36 | [data-accordion] > [data-control]:after { 37 | content: ""; 38 | position: absolute; 39 | right: 10px; 40 | top: 12px; 41 | font-size: 25px; 42 | font-weight: 200; 43 | color: #444; 44 | height: 15px; 45 | width: 24px; 46 | background: url('../images/down.png') center center no-repeat; 47 | background-size: 50%; 48 | } 49 | 50 | [data-accordion].open > [data-control]:after { 51 | -webkit-transform: rotate(-180deg); 52 | -ms-transform: rotate(-180deg); 53 | transform: rotate(-180deg); 54 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | jQuery Accordion 2 | ================ 3 | 4 | Responsive, CSS powered, jQuery accordion plugin. 5 | 6 | Jquery Accordion uses CSS transitions to animate opening/closing with a fallback to jQuery's animate when CSS transitions are not supported. It takes little configuration or code to use it on your project. [Try out the demo](//vctrfrnndz.github.io/jquery-accordion). 7 | 8 | Supports IE9+ and modern browsers. 9 | 10 | Developed by [@vctrfrnndz](http://vctrfrnndz.com). Licensed under the MIT License. 11 | 12 | ### Usage 13 | 14 | ```javascript 15 | $('.accordion').accordion({ 16 | "transitionSpeed": 400 17 | }); 18 | ``` 19 | 20 | ### Options 21 | 22 | Name | Default | Type | Description 23 | :----------------|:---------------------------|:--------|:----------- 24 | transitionSpeed | `300` | int | Transition speed on miliseconds. 25 | transitionEasing | `'ease'` | string | CSS value for easing. 26 | controlElement | `'[data-control]'` | string | CSS selector for the element acting as a button. 27 | contentElement | `'[data-content]'` | string | CSS selector for the element containing hide/show content. 28 | groupElement | `'[data-accordion-group]'` | string | CSS selector for a parent element containing a group. 29 | singleOpen | `true` | boolean | Opens a single accordion a time. 30 | 31 | ### Events 32 | 33 | `accordion.open` fires when any accordion opens 34 | 35 | `accordion.close` fires when any accordion closes 36 | 37 | `accordion.toggle` toggles accordion open/close when triggered on a controlElement. This will not be triggered if it affects more than one accordion while `singleOpen`is enabled. 38 | 39 | `accordion.refresh` manually refreshes the height of an accordion. Useful when adding elements to the accordion dynamically. 40 | 41 | ### Sample Structure 42 | 43 | For a simple accordion/dropdown, use the following structure/data-attributes: 44 | 45 | ```html 46 |
47 |
Control
48 |
49 |
Row
50 |
Row
51 |
Row
52 |
53 |
54 | ``` 55 | 56 | For a group of accordions, you can use the `data-accordion-group` attribute on a parent, this will allow you to activate/deactivate the single open behavior by setting `singleOpen` to true/false. 57 | 58 | ```html 59 |
60 |
61 |
Control
62 |
63 |
Row
64 |
Row
65 |
Row
66 |
67 |
68 |
69 |
Control
70 |
71 |
Row
72 |
Row
73 |
Row
74 |
75 |
76 |
77 | ``` 78 | 79 | ### Starting with opened state 80 | 81 | To initialize the accordion with an open state just add the class `.open` to your accordion element. 82 | 83 | ```html 84 |
85 |
86 |
Control
87 |
88 |
Row
89 |
Row
90 |
Row
91 |
92 |
93 |
94 | ``` 95 | -------------------------------------------------------------------------------- /css/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0; 3 | margin: 0; 4 | font-family: "Helvetica Neue", "Helvetica", sans-serif; 5 | color: #333; 6 | min-width: 320px; 7 | } 8 | 9 | body > section { 10 | margin-bottom: 80px; 11 | } 12 | 13 | button { 14 | margin: 0; 15 | padding: 0; 16 | background: inherit; 17 | border: inherit; 18 | font: inherit; 19 | outline: none; 20 | width: 100%; 21 | display: block; 22 | text-align: left; 23 | color: inherit; 24 | } 25 | 26 | img { 27 | vertical-align: middle; 28 | max-width: 100%; 29 | } 30 | 31 | h1, h2 { 32 | font-weight: 400; 33 | text-align: center; 34 | padding: 0 20px; 35 | line-height: 0.85; 36 | } 37 | 38 | h1 { 39 | margin-bottom: 10px; 40 | } 41 | 42 | .intro { 43 | text-align: center; 44 | margin-bottom: 40px; 45 | padding: 0 20px; 46 | } 47 | 48 | a { 49 | color: #333; 50 | } 51 | 52 | .intro h1 { 53 | font-size: 40px; 54 | } 55 | 56 | .intro p { 57 | margin-bottom: 40px; 58 | } 59 | 60 | .intro .btn { 61 | display: inline-block; 62 | vertical-align: top; 63 | max-width: auto; 64 | margin: 0 auto; 65 | border: 1px solid #888; 66 | color: #333; 67 | padding: 10px 20px; 68 | border-radius: 3px; 69 | text-decoration: none; 70 | font-size: 14px; 71 | margin: 0 5px; 72 | margin-bottom: 15px; 73 | } 74 | 75 | .intro .btn:hover, 76 | .intro .btn:active { 77 | background: black; 78 | border-color: black; 79 | color: white; 80 | } 81 | 82 | .intro .btn:focus { 83 | text-decoration: underline; 84 | border-color: #333; 85 | } 86 | 87 | .intro .btn img { 88 | margin-right: 5px; 89 | } 90 | 91 | .snippet { 92 | max-width: 768px; 93 | padding: 0 20px; 94 | margin-left: auto; 95 | margin-right: auto; 96 | } 97 | 98 | .copyright { 99 | text-align: center; 100 | } 101 | 102 | [data-accordion] [data-content] { 103 | background: rgb(255, 237, 237); 104 | } 105 | 106 | [data-accordion] [data-content] [data-content] { 107 | background: rgb(221, 221, 255); 108 | } 109 | 110 | [data-accordion] [data-content] [data-content] [data-content] { 111 | background: rgb(228, 255, 228); 112 | } 113 | 114 | table { 115 | max-width: 100%; 116 | background-color: transparent; 117 | border-collapse: collapse; 118 | border-spacing: 0; 119 | } 120 | .table { 121 | width: 100%; 122 | margin-bottom: 22px; 123 | } 124 | .table th, 125 | .table td { 126 | padding: 16px; 127 | line-height: 24px; 128 | text-align: left; 129 | vertical-align: top; 130 | border-top: 1px solid #ffffff; 131 | } 132 | .table td { 133 | background: #FFF; 134 | border-top: 1px solid #E0E0E0; 135 | } 136 | .table th { 137 | font-weight: bold; 138 | } 139 | .table thead th { 140 | vertical-align: bottom; 141 | } 142 | .table caption + thead tr:first-child th, 143 | .table caption + thead tr:first-child td, 144 | .table colgroup + thead tr:first-child th, 145 | .table colgroup + thead tr:first-child td, 146 | .table thead:first-child tr:first-child th, 147 | .table thead:first-child tr:first-child td { 148 | border-top: 0; 149 | } 150 | .table tbody + tbody { 151 | border-top: 2px solid #ffffff; 152 | } 153 | .table .table { 154 | background-color: #ffffff; 155 | } 156 | .table-bordered { 157 | border: 1px solid #ffffff; 158 | border-collapse: separate; 159 | *border-collapse: collapse; 160 | border-left: 0; 161 | -webkit-border-radius: 3px; 162 | -moz-border-radius: 3px; 163 | border-radius: 3px; 164 | } 165 | .table-bordered caption + thead tr:first-child th, 166 | .table-bordered caption + tbody tr:first-child th, 167 | .table-bordered caption + tbody tr:first-child td, 168 | .table-bordered colgroup + thead tr:first-child th, 169 | .table-bordered colgroup + tbody tr:first-child th, 170 | .table-bordered colgroup + tbody tr:first-child td, 171 | .table-bordered thead:first-child tr:first-child th, 172 | .table-bordered tbody:first-child tr:first-child th, 173 | .table-bordered tbody:first-child tr:first-child td { 174 | border-top: 0; 175 | } 176 | .table-bordered thead:first-child tr:first-child > th:first-child, 177 | .table-bordered tbody:first-child tr:first-child > td:first-child, 178 | .table-bordered tbody:first-child tr:first-child > th:first-child { 179 | -webkit-border-top-left-radius: 3px; 180 | -moz-border-radius-topleft: 3px; 181 | border-top-left-radius: 3px; 182 | } 183 | .table-bordered thead:first-child tr:first-child > th:last-child, 184 | .table-bordered tbody:first-child tr:first-child > td:last-child, 185 | .table-bordered tbody:first-child tr:first-child > th:last-child { 186 | -webkit-border-top-right-radius: 3px; 187 | -moz-border-radius-topright: 3px; 188 | border-top-right-radius: 3px; 189 | } 190 | .table-bordered thead:last-child tr:last-child > th:first-child, 191 | .table-bordered tbody:last-child tr:last-child > td:first-child, 192 | .table-bordered tbody:last-child tr:last-child > th:first-child, 193 | .table-bordered tfoot:last-child tr:last-child > td:first-child, 194 | .table-bordered tfoot:last-child tr:last-child > th:first-child { 195 | -webkit-border-bottom-left-radius: 3px; 196 | -moz-border-radius-bottomleft: 3px; 197 | border-bottom-left-radius: 3px; 198 | } 199 | .table-bordered thead:last-child tr:last-child > th:last-child, 200 | .table-bordered tbody:last-child tr:last-child > td:last-child, 201 | .table-bordered tbody:last-child tr:last-child > th:last-child, 202 | .table-bordered tfoot:last-child tr:last-child > td:last-child, 203 | .table-bordered tfoot:last-child tr:last-child > th:last-child { 204 | -webkit-border-bottom-right-radius: 3px; 205 | -moz-border-radius-bottomright: 3px; 206 | border-bottom-right-radius: 3px; 207 | } 208 | .table-bordered tfoot + tbody:last-child tr:last-child td:first-child { 209 | -webkit-border-bottom-left-radius: 0; 210 | -moz-border-radius-bottomleft: 0; 211 | border-bottom-left-radius: 0; 212 | } 213 | .table-bordered tfoot + tbody:last-child tr:last-child td:last-child { 214 | -webkit-border-bottom-right-radius: 0; 215 | -moz-border-radius-bottomright: 0; 216 | border-bottom-right-radius: 0; 217 | } 218 | .table-bordered caption + thead tr:first-child th:first-child, 219 | .table-bordered caption + tbody tr:first-child td:first-child, 220 | .table-bordered colgroup + thead tr:first-child th:first-child, 221 | .table-bordered colgroup + tbody tr:first-child td:first-child { 222 | -webkit-border-top-left-radius: 3px; 223 | -moz-border-radius-topleft: 3px; 224 | border-top-left-radius: 3px; 225 | } 226 | .table-bordered caption + thead tr:first-child th:last-child, 227 | .table-bordered caption + tbody tr:first-child td:last-child, 228 | .table-bordered colgroup + thead tr:first-child th:last-child, 229 | .table-bordered colgroup + tbody tr:first-child td:last-child { 230 | -webkit-border-top-right-radius: 3px; 231 | -moz-border-radius-topright: 3px; 232 | border-top-right-radius: 3px; 233 | } 234 | table td[class*="span"], 235 | table th[class*="span"], 236 | .row-fluid table td[class*="span"], 237 | .row-fluid table th[class*="span"] { 238 | display: table-cell; 239 | float: none; 240 | margin-left: 0; 241 | } 242 | .table td.span1, 243 | .table th.span1 { 244 | float: none; 245 | width: 44px; 246 | margin-left: 0; 247 | } 248 | .table td.span2, 249 | .table th.span2 { 250 | float: none; 251 | width: 124px; 252 | margin-left: 0; 253 | } 254 | .table td.span3, 255 | .table th.span3 { 256 | float: none; 257 | width: 204px; 258 | margin-left: 0; 259 | } 260 | .table td.span4, 261 | .table th.span4 { 262 | float: none; 263 | width: 284px; 264 | margin-left: 0; 265 | } 266 | .table td.span5, 267 | .table th.span5 { 268 | float: none; 269 | width: 364px; 270 | margin-left: 0; 271 | } 272 | .table td.span6, 273 | .table th.span6 { 274 | float: none; 275 | width: 444px; 276 | margin-left: 0; 277 | } 278 | .table td.span7, 279 | .table th.span7 { 280 | float: none; 281 | width: 524px; 282 | margin-left: 0; 283 | } 284 | .table td.span8, 285 | .table th.span8 { 286 | float: none; 287 | width: 604px; 288 | margin-left: 0; 289 | } 290 | .table td.span9, 291 | .table th.span9 { 292 | float: none; 293 | width: 684px; 294 | margin-left: 0; 295 | } 296 | .table td.span10, 297 | .table th.span10 { 298 | float: none; 299 | width: 764px; 300 | margin-left: 0; 301 | } 302 | .table td.span11, 303 | .table th.span11 { 304 | float: none; 305 | width: 844px; 306 | margin-left: 0; 307 | } 308 | .table td.span12, 309 | .table th.span12 { 310 | float: none; 311 | width: 924px; 312 | margin-left: 0; 313 | } 314 | .table tbody tr.success > td { 315 | background-color: #dff0d8; 316 | } 317 | .table tbody tr.error > td { 318 | background-color: #f2dede; 319 | } 320 | .table tbody tr.warning > td { 321 | background-color: #fcf8e3; 322 | } 323 | .table tbody tr.info > td { 324 | background-color: #d9edf7; 325 | } 326 | .table tbody tr:hover { 327 | background: #ddd; 328 | } 329 | .table tbody tr td:first-child { 330 | font-weight: bold; 331 | } 332 | 333 | @media (max-width: 768px) { 334 | .hp-table table, .hp-table thead, .hp-table .hp-table tbody, .hp-table th, .hp-table td, .hp-table tr { 335 | display: block; 336 | } 337 | .hp-table thead tr { 338 | display: none; 339 | } 340 | .hp-table tr { border: 0px solid #ccc; margin-bottom: 10px; } 341 | 342 | .hp-table td:before { 343 | top: 6px; 344 | left: 6px; 345 | width: 45%; 346 | padding-right: 10px; 347 | white-space: nowrap; 348 | } 349 | 350 | .hp-table td:nth-of-type(2):before { 351 | content: "Default:"; 352 | font-weight: bold; 353 | } 354 | .hp-table td:nth-of-type(3):before { 355 | content: "Type:"; 356 | font-weight: bold; 357 | } 358 | .hp-table td:nth-of-type(4):before { 359 | content: "Description:"; 360 | font-weight: bold; 361 | } 362 | } 363 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | jQuery Accordion 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |

jQuery Accordion

18 |

The missing responsive, CSS powered (jQuery fallback) accordion plugin.

19 | 20 | Fork on Github 21 | Donate via Paypal 22 |
23 | 24 |

Accordion Group
(single open)

25 |
26 |
27 | 28 |
29 |
Item
30 |
31 | 32 |
33 |
Item
34 |
Hoodie ennui Godard aesthetic, art party whatever trust fund slow-carb kogi tattooed single-origin coffee banjo. Deep v tote bag brunch, artisan distillery chillwave Williamsburg sartorial. Mustache blog wayfarers Carles, forage biodiesel butcher street art. Hashtag small batch bitters deep v gluten-free. Semiotics butcher blog, paleo asymmetrical narwhal selvage pug Pitchfork DIY artisan Wes Anderson put a bird on it drinking vinegar whatever. Artisan McSweeney's Shoreditch, wolf yr Marfa street art locavore craft beer aesthetic 90's gentrify. Yr hella fingerstache, Echo Park VHS +1 church-key XOXO Vice selvage gastropub readymade literally wayfarers.
35 |
Item
36 |
Item
37 |
Item
38 |
Item
39 |
40 |
41 |
42 | 43 |
44 |
Item
45 |
Item
46 |
47 | 48 |
49 |
Item
50 |
Item
51 |
Item
52 |
Item
53 |
Item
54 |
Item
55 |
56 |
57 |
58 | 59 |
60 |
Item
61 |
Item
62 |
Item
63 |
Item
64 |
Item
65 |
Item
66 |
67 |
68 |
69 |
70 |
Item
71 |
Item
72 |
Item
73 |
74 |
75 | 76 |
77 | 78 |
79 |
Item
80 |
Item
81 |
Item
82 |
Item
83 |
Item
84 |
Item
85 |
86 |
87 |
88 | 89 |

Accordion Group
(multiple open)

90 |
91 |
92 | 93 |
94 |
Item
95 |
96 | 97 |
98 |
Item
99 |
Hoodie ennui Godard aesthetic, art party whatever trust fund slow-carb kogi tattooed single-origin coffee banjo. Deep v tote bag brunch, artisan distillery chillwave Williamsburg sartorial. Mustache blog wayfarers Carles, forage biodiesel butcher street art. Hashtag small batch bitters deep v gluten-free. Semiotics butcher blog, paleo asymmetrical narwhal selvage pug Pitchfork DIY artisan Wes Anderson put a bird on it drinking vinegar whatever. Artisan McSweeney's Shoreditch, wolf yr Marfa street art locavore craft beer aesthetic 90's gentrify. Yr hella fingerstache, Echo Park VHS +1 church-key XOXO Vice selvage gastropub readymade literally wayfarers.
100 |
Item
101 |
Item
102 |
Item
103 |
Item
104 |
105 |
106 |
107 | 108 |
109 |
Item
110 |
Item
111 |
112 | 113 |
114 |
Item
115 |
Item
116 |
Item
117 |
Item
118 |
Item
119 |
Item
120 |
121 |
122 |
123 | 124 |
125 |
Item
126 |
Item
127 |
Item
128 |
Item
129 |
Item
130 |
Item
131 |
132 |
133 |
134 |
135 |
Item
136 |
Item
137 |
Item
138 |
139 |
140 | 141 |
142 | 143 |
144 |
Item
145 |
Item
146 |
Item
147 |
Item
148 |
Item
149 |
Item
150 |
151 |
152 |
153 | 154 |

Single Accordion
(easeInOutQuad, 600ms duration)

155 |
156 | 157 |
158 |
Item
159 |
Item
160 |
Item
161 |
Item
162 |
Item
163 |
Item
164 |
165 |
166 | 167 |
168 |

Options

169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 |
VariableDefaultTypeDescription
transitionSpeed300intTransition speed on miliseconds.
transitionEasing'ease'stringCSS value for easing
controlElement'[data-control]'stringCSS selector for the element acting as a button inside accordions.
contentElement'[data-content]'stringCSS selector for the element containing hide/show content.
groupElement'[data-accordion-group]'stringCSS selector for a parent element containing a group of accordions.
singleOpentruebooleanOpens a single accordion a time. If false, multiple accordions can be open a time.
218 |
219 | 220 |
221 |

Defaults

222 | 223 | 224 |
225 | 226 | 229 | 230 | 231 | 232 | 246 | 247 | 248 | -------------------------------------------------------------------------------- /js/jquery.accordion.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Accordion 0.0.1 3 | * (c) 2014 Victor Fernandez 4 | * MIT Licensed. 5 | */ 6 | 7 | ;(function ( $, window, document, undefined ) { 8 | 9 | var pluginName = 'accordion', 10 | defaults = { 11 | transitionSpeed: 300, 12 | transitionEasing: 'ease', 13 | controlElement: '[data-control]', 14 | contentElement: '[data-content]', 15 | groupElement: '[data-accordion-group]', 16 | singleOpen: true 17 | }; 18 | 19 | function Accordion(element, options) { 20 | this.element = element; 21 | this.options = $.extend({}, defaults, options); 22 | this._defaults = defaults; 23 | this._name = pluginName; 24 | this.init(); 25 | } 26 | 27 | Accordion.prototype.init = function () { 28 | var self = this, 29 | opts = self.options; 30 | 31 | var $accordion = $(self.element), 32 | $controls = $accordion.find('> ' + opts.controlElement), 33 | $content = $accordion.find('> ' + opts.contentElement); 34 | 35 | var accordionParentsQty = $accordion.parents('[data-accordion]').length, 36 | accordionHasParent = accordionParentsQty > 0; 37 | 38 | var closedCSS = { 'max-height': 0, 'overflow': 'hidden' }; 39 | 40 | var CSStransitions = supportsTransitions(); 41 | 42 | function debounce(func, threshold, execAsap) { 43 | var timeout; 44 | 45 | return function debounced() { 46 | var obj = this, 47 | args = arguments; 48 | 49 | function delayed() { 50 | if (!execAsap) func.apply(obj, args); 51 | timeout = null; 52 | }; 53 | 54 | if (timeout) clearTimeout(timeout); 55 | else if (execAsap) func.apply(obj, args); 56 | 57 | timeout = setTimeout(delayed, threshold || 100); 58 | }; 59 | } 60 | 61 | function supportsTransitions() { 62 | var b = document.body || document.documentElement, 63 | s = b.style, 64 | p = 'transition'; 65 | 66 | if (typeof s[p] == 'string') { 67 | return true; 68 | } 69 | 70 | var v = ['Moz', 'webkit', 'Webkit', 'Khtml', 'O', 'ms']; 71 | 72 | p = 'Transition'; 73 | 74 | for (var i=0; i [data-content]'), 121 | $childs = $content.find('[data-accordion].open > [data-content]'), 122 | $matched; 123 | 124 | if(!opts.singleOpen) { 125 | $childs = $childs.not($currentAccordion.siblings('[data-accordion].open').find('> [data-content]')); 126 | } 127 | 128 | $matched = $content.add($childs); 129 | 130 | if($parentAccordion.hasClass('open')) { 131 | $matched.each(function() { 132 | var currentHeight = $(this).data('oHeight'); 133 | 134 | switch (operation) { 135 | case '+': 136 | $(this).data('oHeight', currentHeight + qty); 137 | break; 138 | case '-': 139 | $(this).data('oHeight', currentHeight - qty); 140 | break; 141 | default: 142 | throw 'updateParentHeight method needs an operation'; 143 | } 144 | 145 | $(this).css('max-height', $(this).data('oHeight')); 146 | }); 147 | } 148 | } 149 | 150 | function refreshHeight($accordion) { 151 | if($accordion.hasClass('open')) { 152 | var $content = $accordion.find('> [data-content]'), 153 | $childs = $content.find('[data-accordion].open > [data-content]'), 154 | $matched = $content.add($childs); 155 | 156 | calculateHeight($matched); 157 | 158 | $matched.css('max-height', $matched.data('oHeight')); 159 | } 160 | } 161 | 162 | function closeAccordion($accordion, $content) { 163 | $accordion.trigger('accordion.close'); 164 | 165 | if(CSStransitions) { 166 | if(accordionHasParent) { 167 | var $parentAccordions = $accordion.parents('[data-accordion]'); 168 | 169 | updateParentHeight($parentAccordions, $accordion, $content.data('oHeight'), '-'); 170 | } 171 | 172 | $content.css(closedCSS); 173 | 174 | $accordion.removeClass('open'); 175 | } else { 176 | $content.css('max-height', $content.data('oHeight')); 177 | 178 | $content.animate(closedCSS, opts.transitionSpeed); 179 | 180 | $accordion.removeClass('open'); 181 | } 182 | } 183 | 184 | function openAccordion($accordion, $content) { 185 | $accordion.trigger('accordion.open'); 186 | if(CSStransitions) { 187 | toggleTransition($content); 188 | 189 | if(accordionHasParent) { 190 | var $parentAccordions = $accordion.parents('[data-accordion]'); 191 | 192 | updateParentHeight($parentAccordions, $accordion, $content.data('oHeight'), '+'); 193 | } 194 | 195 | requestAnimFrame(function() { 196 | $content.css('max-height', $content.data('oHeight')); 197 | }); 198 | 199 | $accordion.addClass('open'); 200 | } else { 201 | $content.animate({ 202 | 'max-height': $content.data('oHeight') 203 | }, opts.transitionSpeed, function() { 204 | $content.css({'max-height': 'none'}); 205 | }); 206 | 207 | $accordion.addClass('open'); 208 | } 209 | } 210 | 211 | function closeSiblingAccordions($accordion) { 212 | var $accordionGroup = $accordion.closest(opts.groupElement); 213 | 214 | var $siblings = $accordion.siblings('[data-accordion]').filter('.open'), 215 | $siblingsChildren = $siblings.find('[data-accordion]').filter('.open'); 216 | 217 | var $otherAccordions = $siblings.add($siblingsChildren); 218 | 219 | $otherAccordions.each(function() { 220 | var $accordion = $(this), 221 | $content = $accordion.find(opts.contentElement); 222 | 223 | closeAccordion($accordion, $content); 224 | }); 225 | 226 | $otherAccordions.removeClass('open'); 227 | } 228 | 229 | function toggleAccordion() { 230 | var isAccordionGroup = (opts.singleOpen) ? $accordion.parents(opts.groupElement).length > 0 : false; 231 | 232 | calculateHeight($content); 233 | 234 | if(isAccordionGroup) { 235 | closeSiblingAccordions($accordion); 236 | } 237 | 238 | if($accordion.hasClass('open')) { 239 | closeAccordion($accordion, $content); 240 | } else { 241 | openAccordion($accordion, $content); 242 | } 243 | } 244 | 245 | function addEventListeners() { 246 | $controls.on('click', toggleAccordion); 247 | 248 | $controls.on('accordion.toggle', function() { 249 | if(opts.singleOpen && $controls.length > 1) { 250 | return false; 251 | } 252 | 253 | toggleAccordion(); 254 | }); 255 | 256 | $controls.on('accordion.refresh', function() { 257 | refreshHeight($accordion); 258 | }); 259 | 260 | $(window).on('resize', debounce(function() { 261 | refreshHeight($accordion); 262 | })); 263 | } 264 | 265 | function setup() { 266 | $content.each(function() { 267 | var $curr = $(this); 268 | 269 | if($curr.css('max-height') != 0) { 270 | if(!$curr.closest('[data-accordion]').hasClass('open')) { 271 | $curr.css({ 'max-height': 0, 'overflow': 'hidden' }); 272 | } else { 273 | toggleTransition($curr); 274 | calculateHeight($curr); 275 | 276 | $curr.css('max-height', $curr.data('oHeight')); 277 | } 278 | } 279 | }); 280 | 281 | 282 | if(!$accordion.attr('data-accordion')) { 283 | $accordion.attr('data-accordion', ''); 284 | $accordion.find(opts.controlElement).attr('data-control', ''); 285 | $accordion.find(opts.contentElement).attr('data-content', ''); 286 | } 287 | } 288 | 289 | setup(); 290 | addEventListeners(); 291 | }; 292 | 293 | $.fn[pluginName] = function ( options ) { 294 | return this.each(function () { 295 | if (!$.data(this, 'plugin_' + pluginName)) { 296 | $.data(this, 'plugin_' + pluginName, 297 | new Accordion( this, options )); 298 | } 299 | }); 300 | } 301 | 302 | })( jQuery, window, document ); 303 | --------------------------------------------------------------------------------