1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 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 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
|
/* ---------------------------------------------
Nested Accordion v.1.4.7.3
Script to create 'accordion' functionality on a hierarchically structured content.
http://www.adipalaz.com/experiments/jquery/nested_accordion.html
Requires: jQuery v1.4.2+
Copyright (c) 2009 Adriana Palazova
Dual licensed under the MIT (http://www.adipalaz.com/docs/mit-license.txt) and GPL (http://www.adipalaz.com/docs/gpl-license.txt) licenses.
------------------------------------------------ */
(function($) {
//$.fn.orphans - http://www.mail-archive.com/jquery-en@googlegroups.com/msg43851.html
$.fn.orphans = function(){
var txt = [];
this.each(function(){$.each(this.childNodes, function() {
if (this.nodeType == 3 && $.trim(this.nodeValue)) txt.push(this)})}); return $(txt);};
$.fn.accordion = function(options) {
var o = $.extend({}, $.fn.accordion.defaults, options);
return this.each(function() {
var containerID = o.container ? '#' + this.id : '', objID = o.objID ? o.objID : o.obj + o.objClass,
Obj = o.container ? containerID + ' ' + objID : '#' + this.id,
El = Obj + ' ' + o.el,
hTimeout = null;
// build
if (o.head) $(Obj).find(o.head).addClass('h');
if (o.head) {
if ($(El).next('div:not(.outer)').length) {$(El).next('div:not(.outer)').wrap('<div class="outer" />');}
$(Obj + ' .h').each(function(){
var $this = $(this);
if (o.wrapper == 'div' && !$this.parent('div.new').length) {$this.add( $this.next('div.outer') ).wrapAll('<div class="new"></div>');}
});
}
$(El).each(function(){
var $node = $(this);
if ($node.find(o.next).length || $node.next(o.next).length) {
if ($node.find('> a').length) {
$node.find('> a').addClass("trigger").css('display', "block");
} else {
var anchor = '<a class="trigger" style="display:block" href="#" />'
if (o.elToWrap) {
var $t = $node.orphans(), $s = $node.find(o.elToWrap);
$t.add($s).wrapAll(anchor);
} else {
$node.orphans().wrap(anchor);
}
}
} else {
$node.addClass('last-child');
if (o.lastChild && $node.find('> a').length) {$node.find('> a').addClass("trigger").css('display', "block");}
}
});
// init state
$(El + ' a.trigger').closest(o.wrapper).find('> ' + o.next).not('.shown').hide().closest(o.wrapper).find('a.open').removeClass('open').data('state', 0);
if (o.activeLink) {
var loc,
fullURL = window.location.href,
path = window.location.pathname.split( '/' ),
page = path[path.length-1];
(o.uri == 'full') ? loc = fullURL : loc = page;
$(Obj + ' a:not([href $= "#"])[href$="' + loc + '"]').addClass('active').parent().attr('id', 'current').closest(o.obj).addClass('current');
if (o.shift && $(Obj + ' a.active').closest(o.wrapper).prev(o.wrapper).length) {
var $currentWrap = $(Obj + ' a.active').closest(o.wrapper),
$curentStack = $currentWrap.nextAll().andSelf(),
$siblings = $currentWrap.siblings(o.wrapper),
$first = $siblings.filter(":first");
if (o.shift == 'clicked' || (o.shift == 'all' && $siblings.length)) {
$currentWrap.insertBefore($first).addClass('shown').siblings(o.wrapper).removeClass('shown');
}
if (o.shift == 'all' && $siblings.length > 1) {$curentStack.insertBefore($first);}
}
}
if (o.initShow) {
$(Obj).find(o.initShow).show().addClass('shown')
.parents(Obj + ' ' + o.next).show().addClass('shown').end()
.parents(o.wrapper).find('> a.trigger, > ' + o.el + ' a.trigger').addClass('open').data('state', 1);
if (o.expandSub) {$(Obj + ' ' + o.initShow).children(o.next).show().end().find('> a').addClass('open').data('state', 1 );}
}
// event
if (o.event == 'click') {
var ev = 'click';
} else {
if (o.focus) {var f = ' focus';} else {var f = '';}
var ev = 'mouseenter' + f;
}
var scrollElem;
(typeof scrollableElement == 'function') ? (scrollElem = scrollableElement('html', 'body')) : (scrollElem = 'html, body');
// The event handler is bound to the "accordion" element
// The event is filtered to only fire when an <a class="trigger"> was clicked on.
$(Obj).delegate('a.trigger', ev, function(ev) {
var $thislink = $(this),
$thisWrapper = $thislink.closest(o.wrapper),
$nextEl = $thisWrapper.find('> ' + o.next),
$siblings = $thisWrapper.siblings(o.wrapper),
$trigger = $(El + ' a.trigger'),
$shownEl = $thisWrapper.siblings(o.wrapper).find('>' + o.next + ':visible'),
shownElOffset;
$shownEl.length ? shownElOffset = $shownEl.offset().top : shownElOffset = false;
function action(obj) {
if (($nextEl).length && $thislink.data('state') && (o.collapsible)) {
$thislink.removeClass('open');
$nextEl.filter(':visible')[o.hideMethod](o.hideSpeed, function() {$thislink.data('state', 0);});
}
if (($nextEl.length && !$thislink.data('state')) || (!($nextEl).length && $thislink.closest(o.wrapper).not('.shown'))) {
if (!o.standardExpansible) {
$siblings.find('> a.open, >'+ o.el + ' a.open').removeClass('open').data('state', 0).end()
.find('> ' + o.next + ':visible')[o.hideMethod](o.hideSpeed);
if (shownElOffset && shownElOffset < $(window).scrollTop()) {$(scrollElem).animate({scrollTop: shownElOffset}, o.scrollSpeed);}
}
$thislink.addClass('open');
$nextEl.filter(':hidden')[o.showMethod](o.showSpeed, function() {$thislink.data('state', 1);});
}
if (o.shift && $thisWrapper.prev(o.wrapper).length) {
var $thisStack = $thisWrapper.nextAll().andSelf(),
$first = $siblings.filter(":first");
if (o.shift == 'clicked' || (o.shift == 'all' && $siblings.length)) {
$thisWrapper.insertBefore($first).addClass('shown').siblings(o.wrapper).removeClass('shown');
}
if (o.shift == 'all' && $siblings.length > 1) {$thisStack.insertBefore($first);}
}
}
if (o.event == 'click') {
action($trigger);
if ($thislink.is('[href $= "#"]')) {
return false;
} else {
if ($.isFunction(o.retFunc)) {
return o.retFunc($thislink)
} else {
return true;
}
}
}
if (o.event != 'click') {
hTimeout = window.setTimeout(function() {
action($trigger);
}, o.interval);
$thislink.click(function() {
$thislink.blur();
if ($thislink.attr('href')== '#') {
$thislink.blur();
return false;
}
});
}
});
if (o.event != 'click') {$(Obj).delegate('a.trigger', 'mouseleave', function() {window.clearTimeout(hTimeout); });}
/* -----------------------------------------------
// http://www.learningjquery.com/2007/10/improved-animated-scrolling-script-for-same-page-links:
-------------------------------------------------- */
function scrollableElement(els) {
for (var i = 0, argLength = arguments.length; i < argLength; i++) {
var el = arguments[i],
$scrollElement = $(el);
if ($scrollElement.scrollTop() > 0) {
return el;
} else {
$scrollElement.scrollTop(1);
var isScrollable = $scrollElement.scrollTop() > 0;
$scrollElement.scrollTop(0);
if (isScrollable) {
return el;
}
}
};
return [];
};
/* ----------------------------------------------- */
});};
$.fn.accordion.defaults = {
container : true, // {true} if the plugin is called on the closest named container, {false} if the pligin is called on the accordion element
obj : 'ul', // the element which contains the accordion - 'ul', 'ol', 'div'
objClass : '.accordion', // the class name of the accordion - required if you call the accordion on the container
objID : '', // the ID of the accordion (optional)
wrapper :'li', // the common parent of 'a.trigger' and 'o.next' - 'li', 'div'
el : 'li', // the parent of 'a.trigger' - 'li', '.h'
head : '', // the headings that are parents of 'a.trigger' (if any)
next : 'ul', // the collapsible element - 'ul', 'ol', 'div'
initShow : '', // the initially expanded section (optional)
expandSub : true, // {true} forces the sub-content under the 'current' item to be expanded on page load
showMethod : 'slideDown', // 'slideDown', 'show', 'fadeIn', or custom
hideMethod : 'slideUp', // 'slideUp', 'hide', 'fadeOut', or custom
showSpeed : 400,
hideSpeed : 800,
scrollSpeed : 600, //speed of repositioning the newly opened section when it is pushed off screen.
activeLink : true, //{true} if the accordion is used for site navigation
event : 'click', //'click', 'hover'
focus : true, // it is needed for keyboard accessibility when we use {event:'hover'}
interval : 400, // time-interval for delayed actions used to prevent the accidental activation of animations when we use {event:hover} (in milliseconds)
collapsible : true, // {true} - makes the accordion fully collapsible, {false} - forces one section to be open at any time
standardExpansible : false, //if {true}, the functonality will be standard Expand/Collapse without 'accordion' effect
lastChild : true, //if {true}, the items without sub-elements will also trigger the 'accordion' animation
shift: false, // false, 'clicked', 'all'. If 'clicked', the clicked item will be moved to the first position inside its level,
// If 'all', the clicked item and all following siblings will be moved to the top
elToWrap: null, // null, or the element, besides the text node, to be wrapped by the trigger, e.g. 'span:first'
uri : 'full', //
retFunc: null //
};
/* ---------------------------------------------
Feel free to remove the following code if you don't need these custom animations.
------------------------------------------------ */
//credit: http://jquery.malsup.com/fadetest.html
$.fn.slideFadeDown = function(speed, callback) {
return this.animate({opacity: 'show', height: 'show'}, speed, function() {
if (jQuery.browser.msie) { this.style.removeAttribute('filter'); }
if (jQuery.isFunction(callback)) { callback(); }
});
};
$.fn.slideFadeUp = function(speed, callback) {
return this.animate({opacity: 'hide', height: 'hide'}, speed, function() {
if (jQuery.browser.msie) { this.style.removeAttribute('filter'); }
if (jQuery.isFunction(callback)) { callback(); }
});
};
/* --- end of the optional code --- */
})(jQuery);
///////////////////////////
// The plugin can be called on the ID of the accordion element or on the ID of its closest named container.
// If the plugin is called on a named container, we can initialize all the accordions residing in a given section with just one call.
// EXAMPLES:
/* ---
$(function() {
// If the closest named container = #container1 or the accordion element is <ul id="subnavigation">:
/// Standard nested lists:
$('#container1').accordion(); // we are calling the plugin on the closest named container
$('#subnavigation').accordion({container:false}); // we are calling the plugin on the accordion element
// this will expand the sub-list with "id=current", when the accordion is initialized:
$('#subnavigation').accordion({container:false, initShow : "#current"});
// this will expand/collapse the sub-list when the mouse hovers over the trigger element:
$('#container1').accordion({event : "hover", initShow : "#current"});
// If the closest named container = #container2
/// Nested Lists + Headings + DIVs:
$('#container2').accordion({el: '.h', head: 'h4, h5', next: 'div'});
$('#container2').accordion({el: '.h', head: 'h4, h5', next: 'div', initShow : 'div.outer:eq(0)'});
/// Nested DIVs + Headings:
$('#container2').accordion({obj: 'div', wrapper: 'div', el: '.h', head: 'h4, h5', next: 'div.outer'});
$('#container2').accordion({objID: '#acc2', obj: 'div', wrapper: 'div', el: '.h', head: 'h4, h5', next: 'div.outer', initShow : '.shown', shift: 'all'});
});
/// We can globally replace the defaults, for example:
$.fn.accordion.defaults.initShow = "#current";
--- */
/// Example options for Hover Accordion:
/* ---
$.fn.accordion.defaults.container=false;
$.fn.accordion.defaults.event="hover";
$.fn.accordion.defaults.focus=false; // Optional. If it is possible, use {focus: true}, since {focus: false} will break the keyboard accessibility
$.fn.accordion.defaults.initShow="#current";
$.fn.accordion.defaults.lastChild=false;
--- */ |
Partager