1;(function ($) { 2 3 var defaults = { 4 hashEvents : 'load hashchange', 5 6 titleSelector : '.accordion-title', 7 containerSelector : '.accordion-container', 8 9 iconStyle : 'fal', 10 iconOpen : 'fa-plus', 11 iconClose : 'fa-minus', 12 13 autoOpenFirst : false, 14 autoClose : false, 15 16 wrapInner : true, 17 activeCls : 'active', 18 useAnimations : false 19 }; 20 21 var Plugin = function(rootNode, options) { 22 var me = this, 23 op = $.extend({}, options || {}); 24 25 //Optionen aus den Data-Attributen zuweisen 26 $.each($(rootNode).data(), function(key, value) { 27 $.map(defaults, function(defValue, defKey) { 28 if (defKey.toLowerCase() == key.toLowerCase()) { 29 op[defKey] = value; 30 } 31 }); 32 }); 33 34 $.extend(me, { 35 rootNode : rootNode, 36 options : $.extend({}, defaults, op) 37 }); 38 39 me.init(); 40 }; 41 42 Plugin.prototype = { 43 44 init: function() { 45 var me = this, 46 op = me.options; 47 48 window.globalIkissAccordionCounter = (window.globalIkissAccordionCounter || 0)+1; 49 50 //Ueberschriften suchen und Elemente entsprechend modifizieren (bei dem neuen Accordion nur direkte Titel sammeln, daher Selektor mit > erweitern) 51 if (me.rootNode == document.body) { 52 me.header = $(op.titleSelector, me.rootNode); 53 } else { 54 me.header = $('> '+op.titleSelector, me.rootNode); 55 if (!me.header.length) me.header = $('> div > '+op.titleSelector, me.rootNode); 56 } 57 58 59 me.header.each(function(idx, node) { 60 var idKey = '-'+window.globalIkissAccordionCounter+'-'+(idx+1), 61 ctSel = op.containerSelector; 62 63 if (op.wrapInner) { 64 $(node) 65 .wrapInner('<button id="acc'+idKey+'" aria-controls="sect'+idKey+'" aria-expanded="false" type="button"><span></span><i class="accordion-toggle-button '+op.iconStyle+' '+op.iconOpen+'" aria-hidden="true"></i></button>'); 66 } else { 67 $(node) 68 .attr({'id': 'acc'+idKey, 'aria-controls': 'sect'+idKey, 'aria-expanded': 'false', 'tabindex': '0'}) 69 .keypress(function(evt) { if (evt.which === 13) { me.onClick.apply(me, arguments); } }); 70 } 71 72 window.photoswipeAccCounter = window.photoswipeAccCounter || 1; 73 74 $(node) 75 .click(function() { me.onClick.apply(me, arguments); }) 76 .next(ctSel) 77 .attr({'id': 'sect'+idKey, 'aria-labelledby': 'acc'+idKey, 'role': 'region'}) 78 .css('display', 'none') 79 .find('.photoswipe-gallery') 80 .filter(function() { return $(this).closest(ctSel).get(0) == $(node).next(ctSel).get(0); }) 81 .attr('data-photoswipe-group', 'acc-'+(window.photoswipeAccCounter++)); 82 }); 83 84 //Beim Fokus mittels TabKey CSS-Klasse setzen 85 me.header.on('focusin', function(e){ 86 var me = this; 87 $(window).one('keyup.tabkey', function (e) { 88 if ((e.keyCode ? e.keyCode : e.which) == 9) { 89 $(me).addClass('accordion-tab-focus'); 90 } 91 }); 92 }).on('focusout', function(e){ 93 $(this).removeClass('accordion-tab-focus'); 94 $(window).off('keyup.tabkey'); 95 }); 96 97 98 //Erstes Element öffnen? 99 if (op.autoOpenFirst && me.header.length) { 100 me.toggle(me.header[0]); 101 } 102 103 //Events bei denen der location.hash geprüft werden soll 104 $(window).on(op.hashEvents, function(){ me.checkHash.apply(me, arguments);}); 105 106 //ab jQuery 3.x wird das load event in docready manchmal nicht mehr ausgeführt, daher manueller Aufruf 107 if (document.readyState === 'complete') { 108 me.checkHash(); 109 } 110 }, 111 112 onClick: function(e) { 113 var me = this, 114 op = me.options; 115 116 var trgHeader = $(e.target).closest(op.titleSelector).get(0); 117 118 if (!trgHeader) 119 return; 120 121 e.preventDefault(); 122 e.stopPropagation(); 123 124 this.toggle(trgHeader); 125 }, 126 127 open: function(header) { 128 this.toggle(header, 'open'); 129 }, 130 131 close: function(header) { 132 this.toggle(header, 'close'); 133 }, 134 135 toggle: function(header, forceMode) { 136 var me = this, 137 op = me.options, 138 io = op.iconOpen, 139 ic = op.iconClose, 140 mode = $(header).hasClass(op.activeCls) ? 'close' : 'open', 141 open = (mode == 'open' || forceMode == 'open'); 142 143 if (open && op.autoClose) { 144 var acHeader = (me.rootNode == document.body)
145 ? $(op.titleSelector+'.'+op.activeCls, ($(header).closest(op.containerSelector).get(0) || document.body)).get(0) 146 : (me.header.filter('.'+op.activeCls)).get(0); 147 148 if (acHeader && acHeader != header) { 149 this.close(acHeader); 150 151 var offTop = parseInt($(header).offset().top, 10), 152 scTop = parseInt($(header).css('scroll-margin-top'), 10); 153 if (scTop) { 154 offTop -= scTop; 155 } 156 157 if (offTop < $(window).scrollTop()) { 158 $('html, body').animate({scrollTop: offTop}, 500); 159 } 160 } 161 } 162 163 $(header).toggleClass(op.activeCls); 164 165 var $container = $(header).next(op.containerSelector); 166 if (op.useAnimations === true) { 167 $container[open ? 'slideDown' : 'slideUp'](); 168 } else { 169 $container.css('display', open ? '' : 'none'); 170 } 171 172 if ($('button', header).length) { 173 $('button', header).attr('aria-expanded', open ? 'true': 'false'); 174 } else { 175 $(header).attr('aria-expanded', open ? 'true': 'false'); 176 } 177 178 $('i'+(op.wrapInner ? '.accordion-toggle-button' : ''), header).removeClass(open ? io : ic).addClass(open ? ic : io); 179 }, 180 181 checkHash: function() { 182 var me = this, 183 op = me.options, 184 hash = decodeURI(window.location.hash || ''), 185 hashID = hash && hash.substr(1), 186 trgEl; 187 188 if (hashID) { 189 var els = me.rootNode.getElementsByTagName("*"); 190 for (var i=0, len = els.length; i < len; i++) { 191 if (els[i].getAttribute('id') == hashID || els[i].getAttribute('data-anchor') == hashID) { 192 trgEl = els[i]; 193 break; 194 } 195 } 196 } 197 198 if (!trgEl || $(trgEl).hasClass(op.activeCls)) 199 return; 200 201 var ctSelector = op.containerSelector, 202 tiSelector = op.titleSelector, 203 openHit = 0; 204 205 if (me.rootNode == document.body) { 206 $(trgEl).parentsUntil(me.rootNode, ctSelector).each(function(idx, ct) { 207 me.open($(ct).prev(tiSelector).get(0)); 208 openHit = 1; 209 }); 210 } else { 211 var ct = $(trgEl).parentsUntil(me.rootNode, ctSelector).last(), 212 hd = ct.length ? 0 : $(trgEl).closest(tiSelector).get(0); 213 214 openHit = 1; 215 216 me.open(hd ? hd : $(ct).prev(tiSelector).get(0)); 217 } 218 219 if (openHit) { 220 var topPos = parseInt($(trgEl).offset().top, 10), 221 scTop = parseInt($(trgEl).css('scroll-margin-top'), 10) || parseInt($('> button', trgEl).css('scroll-margin-top'), 10); 222 223 if (topPos < 10 || window.globalIkissAccordionIsScrolling === true) 224 return; 225 226 if (scTop) { 227 topPos -= scTop; 228 } 229 230 window.globalIkissAccordionIsScrolling = true; 231 232 $('html, body').animate({scrollTop: topPos}, 500); 233 234 } 235 } 236 237 }; 238 239 $.fn.ikissAccordion = function (options) { 240 var pKey = (options && options.pluginKey) || 'ikissAccordion'; 241 return this.each(function() { 242 if (!$.data(this, pKey)) { 243 $.data(this, pKey, new Plugin(this, options)); 244 } 245 }); 246 }; 247 248 //Kompatibilität zur alten Accordion Syntax 249 window.ikissAccordion = function(config) { 250 251 var cf = $.extend({ 252 titleSelector : '.toggler-title', 253 containerSelector : '.toggler-container', 254 openFirstOnLoad : false, 255 wrapInner : false 256 }, config || {}); 257 258 $.extend(cf, { 259 pluginKey : (cf.titleSelector+'-'+cf.containerSelector).replace(/\./g, ''), 260 autoOpenFirst : (cf.openFirstOnLoad || cf.autoOpenFirst) 261 }); 262 delete cf.openFirstOnLoad; 263 264 $(document.body).ikissAccordion(cf); 265 }; 266 267})(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.