1/**################################################ 2## 3## project: awsAccordion - a vertical/horizontal accordion plugin for jQuery 4## author: @anotherwebstorm 5## demo: code.anotherwebstorm.com/apps/awsaccordion.html 6## Version: 1.0 7## Copyright: (c) 2012-2013 Marco Cardoso 8## 9################################################**/ 10 11(function ($) { 12 13 var AwsAccordion = function (elem, options) { 14 15 // ### DEFAULT OPTIONS 16 var defaults = { 17 18 //Visual Settings and Attributes 19 type: 'vertical', //Type of accordion. By default i set to vertical. You can change it to horizontal [string] 20 cssAttrsVer: { //Only use if type of accordion is vertical 21 ulWidth: 700, //Width for ul [integer/string]. If you specify string 'responsive' it will take full width of parent container 22 liHeight: 40 //Height for li [integer/string] 23 }, 24 cssAttrsHor: { //Only use if type of accordion is horizontal 25 ulWidth: 700, //Width for ul [integer/string]. If you specify string 'responsive' it will take full width of parent container 26 liWidth: 40, //Width for li [integer] 27 liHeight: 300, //Height for li [integer] 28 responsiveMedia: false //If you want a responsive accordion write here your media query. [string]. By default it will be '(max-width: 600px)' 29 }, 30 startSlide: 1, //Start accordion with slide number X opened. By default is 1 [integer/false] 31 openCloseHelper: { //Show or hide numbers or icons on opening and closing tabs 32 numeric: false, //Set to true and show numbers [boolean] 33 openIcon: false, //icon for opening the tab. (example: 'plus') [string] - Refer to http://fortawesome.github.com/Font-Awesome/#all-icons to check all icons 34 closeIcon: false //icon for closing the tab. (example: 'minus') [string] - Refer to http://fortawesome.github.com/Font-Awesome/#all-icons to check all icons 35 }, 36 openOnebyOne: true, //Open Tabs one by one [boolean] 37 38 //HTML 39 classTab: 'active', //Opened tab by default has class active [string/false] 40 41 //Events 42 slideOn: 'click', //Event for Tab slide, can use click or mouseover [string] 43 44 //Animation Settings 45 autoPlay: false, //Set accordion autoPlay [boolean] 46 autoPlaySpeed: 2000 //By Default autoPlay speed is set at 3000ms [integer] 47 }, 48 49 // ### MERGE DEFAULTS WITH OVERWRITTEN SETTINGS 50 settings = $.extend(true, {}, defaults, options), 51 52 // ### GLOBAL VARIABLES 53 horUlParentWidth = parseInt($(elem.parent()).css('width'), 10), 54 horElemContent = $(elem).html(), 55 headLis = elem.children().children(), 56 countHeads = headLis.length, 57 playing = '', 58 versionIE = parseFloat(navigator.appVersion.split("MSIE")[1]), 59 60 // ### METHODS 61 methods = { 62 63 // start autoplay 64 play: function () { 65 var i;
66 if (settings.startSlide && (settings.startSlide !== countHeads)) { 67 i = settings.startSlide; 68 } else { 69 i = 0; 70 } 71 playing = setInterval(function () { 72 //While 73 if (i < countHeads) { 74 var next = i++; 75 //Execute click action on li 76 $(headLis[next]).trigger('click'); 77 //Reset Counter if last li is achieved 78 if (i === countHeads) { 79 next = 0; 80 i = 0; 81 } 82 } 83 }, settings.autoPlaySpeed); 84 }, 85 86 // Stop autoplay 87 stop: function () { 88 //Clear Interval setted in var playing 89 window.clearInterval(playing); 90 }, 91 92 //Get border width sum to define correctly width for horizontal accordion 93 calcBordWidthHor: function () { 94 var borRight, 95 borLeft; 96 97 //Small tweaks with isNaN for reading in ie7/ie8 98 if (!isNaN(parseInt($(headLis).parent().find('li').css('border-right-width'), 10))) { 99 borRight = parseInt($(headLis).parent().find('li').css('border-right-width'), 10); 100 } else { 101 borRight = 0; 102 } 103 104 if (!isNaN(parseInt($(headLis).parent().find('li').css('border-left-width'), 10))) { 105 borLeft = parseInt($(headLis).parent().find('li').css('border-left-width'), 10); 106 } else { 107 borLeft = 0; 108 } 109 110 return borRight + borLeft; 111 }, 112 113 //Get div width for horizontal accordion 114 calcDivWidthHor: function () { 115 if ($.type(settings.cssAttrsHor.ulWidth) === "number") { 116 return settings.cssAttrsHor.ulWidth - ($(headLis).parent().find('li').length * (settings.cssAttrsHor.liWidth + methods.calcBordWidthHor())); 117 } else { 118 //if is 'responsive' 119 return horUlParentWidth - ($(headLis).parent().find('li').length * (settings.cssAttrsHor.liWidth + methods.calcBordWidthHor())); 120 } 121 }, 122 123 //! matchMedia() polyfill for IE made by Scott Jehl, Paul Irish and Nicholas Zakas. 124 matchQueryMedia: function () { 125 126 window.matchMedia = window.matchMedia || (function (doc, undefined) { 127 128 var docElem = doc.documentElement, 129 refNode = docElem.firstElementChild || docElem.firstChild, 130 // fakeBody required for <FF4 when executed in <head> 131 fakeBody = doc.createElement('body'), 132 div = doc.createElement('div'), 133 mqRun, 134 getEmValue, 135 mqSupport, 136 eminpx; 137 138 div.id = 'mq-test-1'; 139 div.style.cssText = "position:absolute;top:-100em"; 140 fakeBody.style.background = "none"; 141 fakeBody.appendChild(div); 142 143 mqRun = function (mq) { 144 var bool; 145 div.innerHTML = '­<style media="' + mq + '"> #mq-test-1 { width: 42px; }</style>'; 146 docElem.insertBefore(fakeBody, refNode); 147 bool = div.offsetWidth === 42; 148 docElem.removeChild(fakeBody); 149 150 return { matches: bool, media: mq }; 151 }; 152 153 getEmValue = function () { 154 var ret, 155 body = docElem.body, 156 fakeUsed = false; 157 158 div.style.cssText = "position:absolute;font-size:1em;width:1em"; 159 160 if (!body) { 161 body = fakeUsed = doc.createElement("body"); 162 body.style.background = "none"; 163 } 164 165 body.appendChild(div); 166 167 docElem.insertBefore(body, docElem.firstChild); 168 169 if (fakeUsed) { 170 docElem.removeChild(body); 171 } else { 172 body.removeChild(div); 173 } 174 175 //also update eminpx before returning 176 ret = eminpx = parseFloat(div.offsetWidth);
177 178 return ret; 179 }; 180 181 //cached container for 1em value, populated the first time it's needed 182 eminpx; 183 184 // verify that we have support for a simple media query 185 mqSupport = mqRun('(min-width: 0px)').matches; 186 187 return function (mq) { 188 if (mqSupport) { 189 return mqRun(mq); 190 } else { 191 var min = mq.match(/\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/) && parseFloat(RegExp.$1) + (RegExp.$2 || ""), 192 max = mq.match(/\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/) && parseFloat(RegExp.$1) + (RegExp.$2 || ""), 193 minnull = min === null, 194 maxnull = max === null, 195 currWidth = doc.body.offsetWidth, 196 em = 'em', 197 bool; 198 199 if (!!min) { min = parseFloat(min) * (min.indexOf(em) > -1 ? (eminpx || getEmValue()) : 1); } 200 if (!!max) { max = parseFloat(max) * (max.indexOf(em) > -1 ? (eminpx || getEmValue()) : 1); } 201 202 bool = (!minnull || !maxnull) && (minnull || currWidth >= min) && (maxnull || currWidth <= max); 203 204 return { matches: bool, media: mq }; 205 } 206 }; 207 208 } (document)); 209 210 }, 211 212 //Define Responsive Actions for horizontal accordion 213 responsiveAction: function (mq) { 214 //If media query matches 215 if (mq.matches) { 216 $(elem).empty().removeAttr('class').addClass('accordion-ver').html(horElemContent); 217 $(elem).awsAccordion({ 218 type: 'vertical', 219 cssAttrsVer: { 220 ulWidth: 'responsive', 221 liHeight: settings.cssAttrsVer.liHeight 222 }, 223 startSlide: settings.startSlide, 224 openCloseHelper: { 225 numeric: settings.openCloseHelper.numeric, 226 openIcon: settings.openCloseHelper.openIcon, 227 closeIcon: settings.openCloseHelper.closeIcon 228 }, 229 openOnebyOne: true, 230 classTab: settings.classTab, 231 slideOn: settings.slideOn, 232 autoPlay: settings.autoPlay, 233 autoPlaySpeed: settings.autoPlaySpeed 234 }); 235 } else { 236 $(elem).empty().removeAttr('class').addClass('accordion-hor').html(horElemContent); 237 $(elem).awsAccordion({ 238 type: 'horizontal', 239 cssAttrsVer: { 240 ulWidth: 'responsive', 241 liHeight: settings.cssAttrsVer.liHeight 242 }, 243 cssAttrsHor: { 244 ulWidth: 'responsive', 245 liWidth: settings.cssAttrsHor.liWidth, 246 liHeight: settings.cssAttrsHor.liHeight, 247 responsiveMedia: settings.cssAttrsHor.responsiveMedia 248 }, 249 startSlide: settings.startSlide, 250 openCloseHelper: { 251 numeric: settings.openCloseHelper.numeric, 252 openIcon: settings.openCloseHelper.openIcon, 253 closeIcon: settings.openCloseHelper.closeIcon 254 }, 255 classTab: settings.classTab, 256 slideOn: settings.slideOn, 257 autoPlay: settings.autoPlay, 258 autoPlaySpeed: settings.autoPlaySpeed 259 }); 260 } //end of matches 261 } 262 263 }, 264 265 // ### CORE 266 core = { 267 268 // bind events 269 bindEvents: function () { 270 271 var trigger = $(headLis).find("[data-accordion='trigger']"); 272 273 274 if (trigger.length > 0) { 275 headLis = trigger; 276 } 277 278 279 //on click or mouseover 280 headLis.on(settings.slideOn, core.slideContent); 281 //clean up heads first 282 headLis.each(core.resetSlideContent); 283 //clean up heads first 284 // headLis.each(core.resetSlideContent); 285 286 //Set Visual Attributes for Accordeons 287 core.setAttrs(); 288 289 //Set Autoplay 290 if (settings.autoPlay) { 291 methods.play(); 292 } 293 294 }, 295 296 //Set Visual Attributes for Accordeons 297 setAttrs: function () { 298 299 //define i for for and mediaquerie to obtain max-width and/or min-width value defined by user 300 var i, 301 mq, 302 numberHeight, 303 iconHeight, 304 h1Height, 305 h1HeightIe, 306 currentHeight, 307 currentWidth, 308 windowHeight, 309 windowWidth; 310 311 //Set vertical accordion attrs 312 if (settings.type === 'vertical') { 313 314 //Set attrs for ul 315 if ($.type(settings.cssAttrsVer.ulWidth) === "
315number") { 316 $(headLis).parent().css({ 317 'width': settings.cssAttrsVer.ulWidth + 'px' 318 }); 319 } else { 320 $(headLis).parent().css({ 321 'width': '100%' 322 }); 323 } 324 325 //Set attrs for li 326 if (settings.cssAttrsVer.liHeight) { 327 $(headLis).css({ 328 'padding-top': settings.cssAttrsVer.liHeight + 'px' 329 }); 330 } 331 332 //Workout for IE bug onresize 333 if (versionIE === 7 || versionIE === 8) { 334 $('body').css({ 'height': 'auto', 'overflow-y': 'scroll', 'overflow-x': 'hidden' }); 335 } 336 337 } 338 339 340 //Set horizontal accordion attrs 341 if (settings.type === 'horizontal') { 342 343 //Workout for IE bug onresize 344 if (versionIE === 7 || versionIE === 8) { 345 $('body').removeAttr('style'); 346 } 347 348 //Check if ulWidth is integer 349 if ($.type(settings.cssAttrsHor.ulWidth) === "number") { 350 //Set attrs for ul 351 $(headLis).parent().css({ 352 'width': settings.cssAttrsHor.ulWidth + 'px' 353 }); 354 } else { 355 //if it's 'responsive' 356 //run matchQueryMedia and set mq with matchmedia 357 methods.matchQueryMedia(); 358 mq = window.matchMedia(settings.cssAttrsHor.responsiveMedia); 359 360 if (mq.matches) { 361 //if it matches execute responsiveAction 362 methods.responsiveAction(mq); 363 } else { 364 //if doesn't matches let horizontal still be an horizontal accordion instead of a responsive and vertical accordion and set elem parent width 365 $(headLis).parent().css({ 366 'width': horUlParentWidth + 'px' 367 }); 368 } 369 370 //Tweaking onresize method for IE7 and IE8 due to bug launching various events of onresize when body loads. 371 if (versionIE === 7 || versionIE === 8) { 372 373 $(window).resize(function () { 374 windowHeight = $(window).height(); 375 windowWidth = $(window).width(); 376 377 if (currentHeight === undefined || currentHeight !== windowHeight || currentWidth === undefined || currentWidth !== windowWidth) { 378 379 currentHeight = windowHeight; 380 currentWidth = windowWidth; 381 382 methods.matchQueryMedia(); 383 mq = window.matchMedia(settings.cssAttrsHor.responsiveMedia); 384 methods.responsiveAction(mq); 385 386 } 387 }); 388 389 } else { 390 391 window.onresize = function (event) { 392 methods.matchQueryMedia(); 393 mq = window.matchMedia(settings.cssAttrsHor.responsiveMedia); 394 methods.responsiveAction(mq); 395 }; 396 397 } 398 } 399 400 //Set attrs for each li and div inside Horizontal 401 for (i = 0; i < $(headLis).parent().find('li').length; i++) { 402 403 $(headLis).parent().find('li').eq(i).css({ 404 'width': settings.cssAttrsHor.liWidth + 'px', 405 'height': settings.cssAttrsHor.liHeight + 'px' 406 }).find('div').css({ 407 'left': settings.cssAttrsHor.liWidth + 'px', 408 'width': methods.calcDivWidthHor() + 'px', 409 'height': settings.cssAttrsHor.liHeight + 'px' 410 }); 411 412 } 413 } 414 415 //Set Numeric or Icon Helper when opening and closing tabs 416 if (settings.openCloseHelper) { 417 418 if (settings.openCloseHelper.numeric) { 419 //Set a number 420 for (i = 0; i <= countHeads; i++) { 421 $(headLis[i]).append('<span class="numericTab tab' + [i + 1] + '">' + [i + 1] + '</span>'); 422 } 423 424 } else if (settings.openCloseHelper.openIcon) { 425 //Set a icon 426 for (i = 0; i <= countHeads; i++) { 427 $(headLis[i]).append('<i class="icon-' + settings.openCloseHelper.openIcon + '"></i>'); 428 } 429 430 } 431 432 //Search for height attrs in number, icon and h1 and divi
432de it by two to get their correct height 433 numberHeight = parseInt($(headLis).find('span.numericTab').css("height"), 10) / 2; 434 iconHeight = parseInt($(headLis).find('i').css("height"), 10) / 2; 435 h1Height = parseInt($(headLis).find('h1').css("height"), 10) / 2; 436 h1HeightIe = parseInt($(headLis).find('h1').css("width"), 10) / 2; //For IE height is not working, we have to use width 437 438 //Set css attrs to Icon, Number and h1 439 if (settings.type === 'horizontal') { 440 if ((headLis).find('h1').length > 0) { 441 //Check if it's IE 442 if (versionIE === 7 || versionIE === 8 || versionIE === 9) { 443 $(headLis).find('h1').css({ 'top': '0px', 'width': 'auto', 'left': ((settings.cssAttrsHor.liWidth / 2) - h1HeightIe) + 'px' }); 444 } else { 445 $(headLis).find('h1').css('left', ((settings.cssAttrsHor.liWidth / 2) - h1Height) + 'px'); 446 } 447 } 448 if (settings.openCloseHelper) { 449 if (settings.openCloseHelper.numeric) { 450 $(headLis).find('span.numericTab').css("width", settings.cssAttrsHor.liWidth + 'px'); 451 } else if (settings.openCloseHelper.openIcon) { 452 $(headLis).find('i').css("width", settings.cssAttrsHor.liWidth + 'px'); 453 } 454 } 455 } else if (settings.type === 'vertical') { 456 if ((headLis).find('h1').length > 0) { 457 $(headLis).find('h1').css('padding-top', ((settings.cssAttrsVer.liHeight / 2) - h1Height) + 'px'); 458 } 459 if (settings.openCloseHelper) { 460 if (settings.openCloseHelper.numeric) { 461 $(headLis).find('span.numericTab').css('padding-top', ((settings.cssAttrsVer.liHeight / 2) - numberHeight) + 'px'); 462 } else if (settings.openCloseHelper.openIcon) { 463 $(headLis).find('i').css('padding-top', ((settings.cssAttrsVer.liHeight / 2) - iconHeight) + 'px'); 464 } 465 } 466 } 467 } 468 469 // Set Open slide by default 470 if (settings.startSlide) { 471 if (settings.type === 'vertical') { 472 core.animateSlideDown(headLis[settings.startSlide - 1]); //Minus 1 to start array in 1 and not in 0 473 } else { 474 core.animateSlideRight(headLis[settings.startSlide - 1]); //Minus 1 to start array in 1 and not in 0 475 } 476 //Insert Close icon if exists 477 if (settings.openCloseHelper.closeIcon) { 478 $(headLis[settings.startSlide - 1]).find('i').attr("class", 'icon-' + settings.openCloseHelper.closeIcon); 479 } 480 481 //and if exists a class name for tab set it then 482 if (settings.classTab) { 483 $(headLis[settings.startSlide - 1]).addClass(settings.classTab); 484 } 485 } 486 487 //Give class last to last li 488 $(headLis).last().addClass('last'); 489 490 }, 491 492 // Slide Content 493 slideContent: function (ev) { 494 //prevent on div selector, preventing from clicking or mouseovering div 495 if ($(ev.target).is("div") || $(ev.target).parent().is("div")) { 496 return false; 497 } 498 499 //var selector = $(ev.currentTarget), 500 var selector = $(ev.currentTarget), 501 visibleElements = $(selector).parent().find('div:visible'); 502 503 //Check if is at autoPlay and if it has been clicked by user 504 if (settings.autoPlay && !ev.isTrigger) { 505 //Stop autoPlay 506 methods.stop(); 507 } 508 509 //Open one by one only for vertical accordion 510 if (settings.openOnebyOne && (visibleElements.length > 0) && settings.type === 'vertical') {
511 core.animateSlideUp(visibleElements); 512 } 513 514 //Check if is there any visible div 515 if (settings.type === 'vertical') { 516 if ($(selector).find('div').is(":visible")) { 517 core.animateSlideUp(selector); 518 } else { 519 core.animateSlideDown(selector); 520 } 521 } else { 522 if ($(selector).find('div').is(":hidden")) { 523 //Animate Right LI 524 core.animateSlideRight(selector); 525 //Animate Left visible divs 526 core.animateSlideLeft(visibleElements); 527 } 528 } 529 }, 530 531 // Slide Up 532 animateSlideUp: function (selector) { 533 // BUG HIER !!!! 534 535 //check if is onebyone, target must be <ul> else we remove parent to target <li> 536 if (settings.openOnebyOne) { 537 //if has anykind of class remove it and close tab 538 if ($(selector).parent().hasClass('last')) { 539 $(selector).parent().find('div').slideUp('fast'); 540 } else { 541 $(selector).parent().find('div').slideUp('fast'); 542 } 543 } else { 544 if ($(selector).hasClass('last')) { 545 $(selector).find('div').slideUp('fast'); 546 } else { 547 $(selector).find('div').slideUp('fast'); 548 } 549 } 550 551 //If it has a openIcon set it 552 if (settings.openCloseHelper.openIcon) { 553 $(selector).parent().find('i').attr("class", 'icon-' + settings.openCloseHelper.openIcon); 554 } 555 }, 556 557 // Slide Down 558 animateSlideDown: function (selector) { 559 560 //Check classTab and remove it 561 $(selector).parent().find('.' + settings.classTab).removeAttr('class'); 562 563 //Check if it has a closeIcon 564 if (settings.openCloseHelper.closeIcon) { 565 //When init accordion length is 1 because it targets directly li, but after that we need to add parent for searching inside li 566 if ($(selector).find('i').length > 0) { 567 $(selector).find('i').attr("class", 'icon-' + settings.openCloseHelper.closeIcon); 568 } else { 569 $(selector).parent().find('i').attr("class", 'icon-' + settings.openCloseHelper.closeIcon); 570 } 571 } 572 573 //Add classTab to current selector if needed and slidedown 574 //$(selector).addClass(settings.classTab).find('div').slideDown('fast'); 575 $(selector).addClass(settings.classTab).parent().find('div').slideDown('fast'); 576 577 }, 578 579 // Slide Right 580 animateSlideRight: function (selector) { 581 582 //Check classTab and remove it 583 $(selector).parent().find('.' + settings.classTab).removeClass(settings.classTab); 584 585 //Check if it has a closeIcon 586 if (settings.openCloseHelper.closeIcon) { 587 //When init accordion length is 1 because it targets directly li, but after that we need to add parent for searching inside li 588 if ($(selector).find('i').length > 0) { 589 $(selector).find('i').attr("class", 'icon-' + settings.openCloseHelper.closeIcon); 590 } else { 591 $(selector).parent().find('i').attr("class", 'icon-' + settings.openCloseHelper.closeIcon); 592 } 593 } 594 595 //Add classTab to current selector and animate right 596 $(selector).addClass(settings.classTab).animate({ width: (methods.calcDivWidthHor() + settings.cssAttrsHor.liWidth) + 'px' }, 'fast'); 597 $(selector).find('div').css('display', 'block'); 598 }, 599 600 // Slide Right 601 animateSlideLeft: function (selector) { 602 603 //Define display none at the very beginning 604 $(selector).parent().find('div').animate({ width: '0p
604x' }, 'fast', function () { 605 $(this).css({ 'display': 'none', 'width': methods.calcDivWidthHor() + 'px' }); 606 }); 607 608 //if has anykind of class remove it and close tab 609 if ($(selector).parent().hasClass('last')) { 610 $(selector).parent().removeClass(settings.classTab).animate({ width: settings.cssAttrsHor.liWidth + 'px' }, 'fast'); 611 } else { 612 $(selector).parent().removeAttr('class').animate({ width: settings.cssAttrsHor.liWidth + 'px' }, 'fast'); 613 } 614 615 //If it has a openIcon set it 616 if (settings.openCloseHelper.openIcon) { 617 $(selector).parent().find('i').attr("class", 'icon-' + settings.openCloseHelper.openIcon); 618 } 619 }, 620 621 // Hide all open content ehen initializing 622 resetSlideContent: function () { 623 headLis.find('div').hide(); 624 }, 625 626 //Initialize Core 627 init: function () { 628 629 //Set Class hor or ver to our accordion 630 if (settings.type === 'vertical') { 631 $(elem).addClass('accordion-ver'); 632 } else { 633 $(elem).addClass('accordion-hor'); 634 } 635 // init events 636 core.bindEvents(); 637 } 638 639 }; 640 641 // ### INITIALIZE CORE
642 core.init(); 643 644 // ### RETURN METHODS 645 return methods; 646 647 }; 648 649 // ### CALL JQUERY AWS ACCORDION PLUGIN 650 $.fn.awsAccordion = function (options) { 651 var elem = this; 652 653 return elem.each(function () { 654 var awsAccordion; 655 awsAccordion = new AwsAccordion(elem, options); 656 elem.data('awsAccordion', awsAccordion); 657 }); 658 }; 659 660} (jQuery));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.