1// doc: 120718 2 3 4// Namespacing. Das et-Objekt und ggf. Unterobjekte nur einmal am Anfang initialisieren! 5var et = et || {}, 6 jQ = jQuery; 7 8/* 9================================================== 10Helper-Funktionen 110623 (Wolfgang) 11================================================== 12ein paar kleine allgemeine Hilfsfunktionen 13*/ 14 15// Allgemeine Methode zum Erstellen von Events 16et.addEvent = function (el, type, fn){ 17 el.addEventListener(type, fn, false); 18}; 19 20// ersetzt addLoadEvent 21et.onLoad = function(fn) 22{ 23 this.addEvent(window,'load',function(){fn();}); 24}; 25 26// einfache Methode zum "Kopieren" von Objekten 27// Argumente können direkt an eine configure-Funktion übergeben werden 28et.clone = function (original, args) 29{ 30 var F = function () {}, obj; 31 F.prototype = original; 32 obj = new F(); 33 if (obj.configure && args) 34 { 35 obj.configure(args); 36 } 37 return obj; 38}; 39 40 41// Methode zum Kombinieren von Objekten 42// (Werte von updateObj überschreiben die von defaultObj) 43et.combine = function(defaultObj, updateObj) 44{ 45 var name, 46 returnObj = this.clone(defaultObj); 47 for (name in updateObj) 48 { 49 if (updateObj.hasOwnProperty(name)) 50 { 51 returnObj[name] = updateObj[name]; 52 } 53 } 54 return returnObj; 55}; 56 57 58// Verwandelt das bei Typo3 standardmäÃig ersetzte @ zurück (bei pageLoad) 59et.convertAt = function() { 60 var dels = document.getElementsByTagName("del"), 61 i; 62 for (i=0; i<dels.length; i++) { 63 if (dels[i].className && dels[i].className === "schutz") { 64 dels[i].firstChild.data = "@"; 65 } 66 } 67 }; 68et.onLoad(et.convertAt); 69 70 71 72/* 73================================================== 74Auf Window-Resize reagieren 130530 (Wolfgang) 75================================================== 76Jetzt auch für mehrfache Anwendung auf einer Seite 77Der Zeitabstand lässt sich leider nur noch einmalig beim ersten Aufruf einstellen 78*/ 79et.afterBrowserResize = function(func,lapse,andNow) 80{ 81 var l = Number(lapse) | 100; 82 83 et.afterBrowserResize.funcsArr.push(func); 84 if (!et.afterBrowserResize.timeOut) 85 { 86 $(window).resize(function() { 87 clearTimeout(et.afterBrowserResize.timeOut); 88 et.afterBrowserResize.timeOut = setTimeout(et.afterBrowserResize.runFuncs, l); 89 }); 90 } 91 if (andNow) 92 { 93 func(); 94 } 95}; 96 97et.afterBrowserResize.timeOut = false;
98et.afterBrowserResize.funcsArr = []; 99et.afterBrowserResize.runFuncs = function(e) 100{ 101 for (i=0; i < et.afterBrowserResize.funcsArr.length; i++ ) 102 { 103 et.afterBrowserResize.funcsArr[i](); 104 } 105}; 106 107 108/* 109================================================== 110GröÃen vergleichen 130630 (Wolfgang) 111================================================== 112Gibt ein Objekt zurück, das die gröÃte/kleinste Höhe/Breite etc. der mitgegebenen Elemente enthält 113*/ 114et.getDimensions = function(elems) 115{ 116 var d = 117 { 118 wMax : 0, 119 wMin : 999999, 120 hMax : 0, 121 hMin : 999999, 122 /*wMaxElems, 123 wMinElems, 124 hMaxElems, 125 hMinElems,*/ 126 outerWCombined : 0, 127 outerHCombined : 0 128 }; 129 $(elems).each(function() 130 { 131 var outerW = $(this).outerWidth(true), 132 outerH = $(this).outerHeight(true); 133 d.wMax = outerW > d.wMax ? outerW : d.wMax; 134 d.wMin = outerW < d.wMin ? outerW : d.wMin; 135 d.hMax = outerH > d.hMax ? outerH : d.hMax; 136 d.hMin = outerH < d.hMin ? outerH : d.hMin; 137 d.outerWCombined += outerW; 138 d.outerHCombined += outerH; 139 }); 140 return d ; 141}; 142 143 144/* 145================================================== 146Touchwipe für Slider 147================================================== 148*/ 149 150/** 151 * jQuery Plugin to obtain touch gestures from iPhone, iPod Touch and iPad, should also work with Android mobile phones (not tested yet!) 152 * Common usage: wipe images (left and right to show the previous or next image) 153 * 154 * @author Andreas Waltl, netCU Internetagentur (http://www.netcu.de) 155 * @version 1.1.1 (9th December 2010) - fix bug (older IE's had problems) 156 * @version 1.1 (1st September 2010) - support wipe up and wipe down 157 * @version 1.0 (15th July 2010) 158 */ 159(function($){$.fn.touchwipe=function(settings){var config={min_move_x:20,min_move_y:20,wipeLeft:function(){},wipeRight:function(){},wipeUp:function(){},wipeDown:function(){},preventDefaultEvents:true};if(settings)$.extend(config,settings);this.each(function(){var startX;var startY;var isMoving=false;function cancelTouch(){this.removeEventListener('touchmove',onTouchMove);startX=null;isMoving=false}function onTouchMove(e){if(config.preventDefaultEvents){e.preventDefault();}if(isMoving){var x=e.touches[0].pageX;var y=e.touches[0].pageY;var dx=startX-x;var dy=startY-y;if(Math.abs(dx)>=config.min_move_x){cancelTouch();if(dx>0){config.wipeLeft()}else{config.wipeRight()}}else if(Math.abs(dy)>=config.min_move_y){cancelTouch();if(dy>0){config.wipeDown()}else{config.wipeUp()}}}}function onTouchStart(e){if(e.touches.length==1){startX=e.touches[0].pageX;startY=e.touches[0].pageY;isMoving=true;this.addEventListener('touchmove',onTouchMove,false)}}if('ontouchstart'in document.documentElement){this.addEventListener('touchstart',onTouchStart,false)}});return this}})(jQuery); 160 161 162/* 163================================================== 164Slider einrichten 110620 (Wolfgang) [jQuery] 165================================================== 166Erstellt aus allen statischen "div.container-slider" dynamische Switchboxen, 167deren Inhalte einzeln durchgeschaltet werden können. 168 169benötigt jQuery, et.clone, et.combine 170*/ 171//var jQ = jQuery.noConflict(); 172 173// Namespacing-Objekt 174et.slider = {}; 175 176// Clone-Vorlage für die tatsächlichen slider (quasi die Klasse) 177et.slider.obj = 178{ 179 jQ_obj : "jQ", 180 jQ_targets : "jQ", 181 jQ_container: "jQ", 182 opt : {}, 183 curNum : 0, 184 maxNum : 0, 185 interval : 0, 186 reactivateTimeout : 0, 187 layerWidth : 0, 188 fullWidth : 0, 189 anim : function() {}, 190 switchTo : function() {}, 191 extendSwitchTo : function(correctedNr) {}, 192 createHtml : function() {}, 193 configure : function() {} 194}; 195et.slider.objectsArray = []; 196 197// Option: Sliding-Animation (anim:"slideH") 198et.slider.obj.slideH = function(nr, correctedNr, corrected, dirForward, dontAnimate) 199{ 200 var nr = nr, 201 containerAnim = -this.layerWidth*nr; 202 // Auf Min/Maxnummer korrigieren, wenn nicht loopend 203 if (!this.opt.loop) 204 { 205 // aktive Box soll mittig stehen - Berechnung, welches Element ganz links steht 206 if (this.opt.centerAct) 207 { 208 nr = nr - Math.floor((this.range-1)/2); 209 } 210 nr = nr + this.range > this.maxNum + 1 ? (this.maxNum + 1 - this.range) : nr; 211 nr = nr < 0 ? 0 : nr; 212 containerAnim = -this.layerWidth*nr; 213 } 214 // Berechungen nur bei loopendem Container notwendig 215 else //if (!dontAnimate) 216 { 217 //tritt eine Lücke auf, wenn es vorwärts oder rückwärts geht? 218 //im ersten Fall bei backwardGap besteht bereits eine Lücke! 219 var forwardGap = this.curNum + this.range > this.maxNum, 220 backwardGap = this.curNum + this.range - 1 > this.maxNum || this.curNum === 0, 221 containerSet = -this.layerWidth*this.curNum; 222 //Reset der einzelnen Elemente 223 this.jQ_targets.css({left:0}); 224 //Berechnung der Position und Animationsziel des Containers 225 //und Position der Elemente (wegen Anschluss vor dem ersten/Nach dem Letzten Element) 226 //alert(nr+' '+correctedNr+' '+corrected+' '+dirForward+' '+dontAnimate+' '+forwardGap); 227 if(forwardGap && dirForward) 228 { 229 this.jQ_targets.slice(this.curNum).css({left:-this.fullWidth}); 230 containerSet = this.layerWidth*(this.maxNum - this.curNum + 1); 231 containerAnim = this.layerWidth*(this.maxNum - nr + 1); 232 } 233 else if (backwardGap && !dirForward) 234 { 235 this.jQ_targets.slice(nr).css({left:-this.fullWidth}); 236 containerSet = this.curNum===0 ? 0 : this.layerWidth*(this.maxNum - this.curNum + 1); 237 containerAnim = this.layerWidth*(this.maxNum - correctedNr + 1); 238 } 239 this.jQ_container.stop(true).css({marginLeft:containerSet}); 240 } 241 //Animieren des Containers 242 if(!dontAnimate) 243 { 244 this.jQ_container.stop(true).animate({marginLeft:containerAnim},this.opt.speed, this.opt.easing); 245 } 246 else 247 { 248 this.jQ_container.stop(true).css({marginLeft:containerAnim}); 249 } 250}; 251 252// Option: Fading-Animation (anim:"fade") 253et.slider.obj.fade = function(nr, correctedNr, corrected, dirForward) 254{ 255 this.jQ_targets.eq(correctedNr).hide().addClass("new").fadeIn(this.opt.speed, function() 256 { 257 jQ(this).siblings(".act").removeClass("act").hide(); 258 jQ(this).addClass("act").removeClass("new"); 259 }); 260} 261 262 263// Wechselfunktion zwischen den Elementen, anstoÃen der Animation 264et.slider.obj.switchTo = function(nr) 265{ 266 if ((this.jQ_container.is(':animated') && this.opt.loop) || this.jQ_targets.is(':animated') || this.dontSlide) 267 { 268 return; 269 } 270 if (this.opt.switchFullRange && nr < 0) 271 { 272 nr = 0; 273 } 274 var dirForward = nr > this.curNum; 275 var correctedNr = nr > this.maxNum ? 0 : nr; 276 correctedNr = correctedNr < 0 ? this.maxNum : correctedNr; 277 var corrected = correctedNr!==nr; 278 if ((!corrected || this.opt.loop) && nr !== this.curNum) 279 { 280 this.anim(nr, correctedNr, corrected, dirForward); 281 this.extendSwitchTo(correctedNr); 282 this.curNum = correctedNr; 283 } 284 this.updateState(); 285}; 286 287// Funktion, die von den Buttons ausgelöst wird 288et.slider.obj.uiSwitchTo = function(e, obj, btn, nr) 289{ 290 e.preventDefault(); 291 if(!jQ(btn).is('.inact')) 292 { 293 obj.switchTo(nr); 294 obj.stopSlideshow(); 295 } 296} 297 298 299// Erstellt die wraps und css-Grundeistellungen 300et.slider.obj.createWraps = function() 301{ 302 var outer = this.jQ_obj; 303 304 // zuerst das äuÃerste Sliderobjekt finden, ggf. erstellen 305 if (outer.is('.layer-container, .slider-mask')) 306 { 307 outer = outer.parent().is('.slider-mask') ? outer.parent() : outer; 308 if (!outer.parent().is('.slider-outer')) 309 { 310 outer.wrap('<div class="slider-outer"></div>'); 311 } 312 outer = outer.parent(); 313 } 314 // dann von auÃen nach innen die Wraps aufbauen 315 if(!outer.children().is('.slider-mask')) 316 { 317 outer.wrapInner('<div class="slider-mask"></div>'); 318 } 319 if(!outer.children().children().is('.layer-container')) 320 { 321 outer.children().wrapInner('<div class="layer-container"></div>'); 322 } 323 324 this.jQ_obj = outer; 325 this.jQ_mask = outer.children(); 326 this.jQ_container = outer.children().children(); 327}; 328 329// Erstellt die Navigations-Buttons etc. 330et.slider.obj.createControls = function() 331{ 332 var that = this,
333 controls = jQ('<div class="slider-controls"></div>'); 334 if (this.opt.controls) 335 { 336 jQ('<a class="btn-back '+this.opt.btnClasses+'" href="#zurueck" title="ein Bild zurück"><b><</b></a>').appendTo(controls).click(function(e){ 337 that.uiSwitchTo(e, that, this, that.curNum-that.switchRange); 338 }); 339 var menu = jQ('<ol class="menu"></ol>'); 340 for (var i=0; i < that.maxNum+1; i++) 341 { 342 var li = jQ('<li>'); 343 li.appendTo(menu).click(function(e) 344 { 345 var nr = jQ(this).index(); 346 that.uiSwitchTo(e, that, this, nr); 347 }); 348 } 349 menu.appendTo(controls); 350 351 jQ('<a class="btn-forward '+this.opt.btnClasses+'" href="#vor" title="nächstes Bild anzeigen"><b>></b></a>').appendTo(controls).click(function(e){ 352 that.uiSwitchTo(e, that, this, that.curNum+that.switchRange); 353 }); 354 this.jQ_controls = controls; 355 this.jQ_layerCounter = jQ('<div class="info layer-counter"></div>'); 356 this.jQ_obj.append(this.jQ_layerCounter); 357 this.jQ_obj.append(controls); 358 } 359 // Einfache Touch-Bedienung (Swipe löst Wechsel aus, leider kein stufenloses Ziehen) 360 this.jQ_mask.touchwipe( 361 { 362 wipeLeft: function() 363 { 364 that.switchTo(that.curNum+that.switchRange); 365 that.stopSlideshow(); 366 }, 367 wipeRight: function() 368 { 369 that.switchTo(that.curNum-that.switchRange); 370 that.stopSlideshow(); 371 }, 372 min_move_x: 20, 373 min_move_y: 20, 374 preventDefaultEvents: false 375 }); 376} 377 378et.slider.obj.prepareAnimType = function() 379{ 380 switch (this.opt.anim) 381 { 382 case "fade": 383 this.anim = this.fade; 384 //this.jQ_targets.css({position:'absolute'}); 385 break; 386 default: 387 this.anim = this.slideH; 388 } 389} 390 391// aktuellen Stand des Sliders abbilden 392et.slider.obj.updateState = function() 393{ 394 var firstSlide = this.curNum === 0, 395 lastSlide = this.curNum === this.maxNum || (this.opt.switchFullRange && (this.curNum > this.maxNum - this.range)), 396 maxTxt = this.maxNum+1, 397 curTxt = this.curNum+1, 398 counterText = curTxt+'/'+maxTxt;; 399 400 this.dontSlide = false; 401 this.jQ_obj.removeClass('dont-slide'); 402 if (this.jQ_targets.length < this.range+1){ 403 this.dontSlide = true; 404 this.jQ_obj.addClass('dont-slide'); 405 } 406 407 if (!this.opt.loop) 408 { 409 this.jQ_controls.find('a').removeClass('inact'); 410 if (lastSlide) 411 { 412 this.jQ_controls.find('.btn-forward').addClass('inact'); 413 } 414 else if (firstSlide) 415 { 416 this.jQ_controls.find('.btn-back').addClass('inact'); 417 } 418 } 419 420 this.jQ_layerCounter.text(counterText); 421 this.jQ_controls.find('.menu li').eq(this.curNum).add(this.jQ_targets.eq(this.curNum)).addClass('act').siblings().removeClass('act'); 422} 423 424// Konfiguriert die sliderbox anhand des ausgesuchten jQuery-Objekts 425et.slider.obj.configure = function(confArray) 426{ 427 this.opt = confArray[1]; 428 this.jQ_obj = confArray[0]; 429 this.jQ_targets = this.jQ_obj.find(this.opt.layers).first().siblings().addBack(); 430 this.maxNum = this.jQ_targets.length-1; 431 432 this.createWraps(); 433 this.createControls(); 434 this.prepareAnimType(); 435 436 this.setDimensions(this); 437 //this.updateState(); // jetzt auch am Ende von setDimensions() 438 this.startSlideshow(); 439}; 440 441// Startet das automatische Weiterblättern 442et.slider.obj.startSlideshow = function() 443{ 444 var that = this; 445 clearInterval(this.interval); 446 clearTimeout(this.reactivateTimeout); 447 if (this.opt.autoslideInterval > 0) 448 { 449 this.interval = window.setInterval(function() 450 { 451 that.switchTo(that.curNum+that.switchRange); 452 }, that.opt.autoslideInterval); 453 } 454}; 455 456// Stoppt das automatische Weiterblättern 457et.slider.obj.stopSlideshow = function() 458{ 459 var that = this; 460 clearInterval(this.interval); 461 if (this.opt.autoslideInterval > 0 && this.opt.autoslideReactivateAfter > 0) 462 { 463 clearTimeout(this.reactivateTimeout); 464 this.reactivateTimeout = window.setTimeout(function() 465 { 466 that.startSlideshow(); 467 }, that.opt.autoslideReactivateAfter); 468 } 469}; 470 471// Slider für Responsive anpassen 472et.slider.obj.setDimensions = function(obj) 473{ 474 var obj = obj || this, 475 maxH; 476 obj.range = obj.opt.range; 477 if (obj.opt.responsive && obj.opt.range > 1 && obj.opt.layerMinWidth > 0 ) 478 { 479 obj.range = Math.min(obj.opt.range, Math.floor(obj.jQ_obj.width()/obj.opt.layerMinWidth)); 480 } 481 482 obj.switchRange = obj.opt.switchFullRange ? obj.range : 1; 483 // responsive funktioniert nur, wenn layers keinen Extra-Margin haben 484 // auÃerdem +1 Hack wegen Blitzern im FF 485 obj.layerWidth = obj.opt.responsive ? Math.round((obj.jQ_obj.width()/obj.range)) : obj.jQ_targets.outerWidth(true); 486 obj.fullWidth = obj.layerWidth*(obj.maxNum+1); 487 if (obj.opt.responsive) 488 { 489 // width() addiert fälschlich die Paddings dazu 490 obj.jQ_targets.css('width',obj.layerWidth); 491 } 492 obj.anim(obj.curNum, obj.curNum, false, true, true); 493 maxH = et.getDimensions(obj.jQ_targets).hMax; 494 switch (obj.opt.anim) 495 { 496 case "fade": 497 //obj.jQ_container.height(maxH); 498 break; 499 default: 500 obj.jQ_container.width(obj.fullWidth); 501 } 502 obj.maxH = maxH; 503 obj.jQ_controls.find('.menu').width(et.getDimensions(obj.jQ_controls.find('li')).outerWCombined); 504 obj.updateState(); 505 obj.extendSwitchTo(obj.curNum); 506} 507 508et.slider.obj.extendSwitchTo = function(correctedNr) 509{ 510} 511 512// Standard-Erstellungs-Optionen. Können durch init-Argument angepasst werden. 513et.slider.def = 514{ 515 containers:".slider-outer", 516 layers:".layer", 517 responsive: true, 518 range: 1, 519 layerMinWidth: 0, 520 speed: 500,
521 autoslideInterval: 0, 522 autoslideReactivateAfter: 12000, 523 easing:"swing", 524 loop: false, // nicht mit switchFullRange! 525 anim:"slideH", 526 controls: true, 527 btnClasses: '', 528 centerAct: false, // nicht mit loop, switchFullRange! 529 switchFullRange: false, 530 noInitIfLayerCount: 1 // -1,0,1,2,3 ... 'range' 531}; 532 533// Gibt das Slider-Objekt zu einem $('.slider-outer') zurück 534et.slider.getObj = function(jQ_obj) 535{ 536 var id = $(jQ_obj).data('switchId'), 537 obj = this.objectsArray[id]; 538 return obj 539} 540 541// Sucht die slider im Html und erstellt entsprechend die Objekte 542et.slider.init = function(optObj) 543{ 544 var opt = et.combine(this.def,optObj), 545 switchdivs = jQ(opt.containers), 546 len = switchdivs.length, 547 noInitIfLayerCount, 548 layerCount, 549 i; 550 for (i=0; i < len; i++) 551 { 552 // children() funktioniert nicht, wenn mehr als ein wrap bereits vorhanden ist 553 layerCount = switchdivs.eq(i).find(opt.layers).length; 554 noInitIfLayerCount = opt.noInitIfLayerCount === 'range' ? opt.range : Number(opt.noInitIfLayerCount); 555 if (isNaN(noInitIfLayerCount) || layerCount > noInitIfLayerCount) 556 { 557 (function(that, i) 558 { 559 var id = that.objectsArray.length, 560 obj = that["obj_"+id] = et.clone(that.obj, [switchdivs.eq(i), opt]); 561 obj.switchId = id; 562 obj.jQ_obj.data({'switchId':id}).addClass('slider-id-'+id); 563 that.objectsArray.push(obj); 564 if (opt.responsive) 565 { 566 et.afterBrowserResize(function() 567 { 568 obj.setDimensions(obj); 569 }); 570 } 571 })(et.slider, i); 572 } 573 else 574 { 575 switchdivs.eq(i).addClass('not-initialized'); 576 } 577 } 578}; 579 580 581 582// Ruft verschiedene slider mit den angepassten Optionen auf 583// Möglichst nur dieses anpassen 584var startSliders = function() 585{ 586 // nicht sliden, wenn feediting aktiv ist! 587 if ($('.typo3-feedit-element, .content-link').length) 588 { 589 return; 590 } 591 592 et.slider.init({ 593 containers:".top-slider", 594 autoslideInterval: 6000, 595 loop: true 596 }); 597 et.slider.init({ 598 containers:".teaser-slider", 599 loop: true 600 }); 601 et.slider.init({ 602 containers:".textpic-slider", 603 autoslideInterval: 6000, 604 loop: true 605 }); 606 et.slider.init({ 607 containers:".gallery-slider", 608 loop: true 609 }); 610 et.slider.init({ 611 containers:".slider-6", 612 layerMinWidth: 125, 613 range: 6, 614 switchFullRange: true, 615 }); 616 et.slider.init({ 617 containers:".logo-slider > div", 618 layers:".wrap-img", 619 layerMinWidth: 150, 620 range: 6, 621 loop: true 622 }); 623 624 // Thumbnail-Slider steuert groÃen Slider 625 $('.slider-with-thumbslider .slider-6 .layer').click(function() 626 { 627 var index = $(this).index(); 628 $(this).parents('.slider-with-thumbslider').first().find('.slider-outer .menu li').eq(index).click(); 629 }); 630}; 631 632 633et.onLoad(function() 634{ 635 startSliders(); 636 et.setMaxImgHeight('.slider-outer'); 637}); 638 639/* 640================================================== 641Bildhöhe angleichen 130710 (Wolfgang) [jQuery] 642================================================== 643Kein Slider-Bild soll gröÃer sein als das erste 644 645benötigt jQuery 646*/ 647et.setMaxImgHeight = function(container, index) 648{ 649 //var index = index || 0; 650 651 $(container).each(function() 652 { 653 var //refImg = $(this).find('img').eq(index), 654 //refH = refImg.height(), 655 sliderObj = et.slider.getObj(this), 656 dimensions = et.getDimensions($(this).find('img')), 657 wMax = dimensions.wMax, 658 hMin = Math.max(dimensions.hMin, wMax*9/16), 659 vpH = $(window).height(), 660 vpMax = Math.max(vpH*3/4, vpH-150, 320); 661 refH = Math.min(hMin,vpMax); 662 $(this).find('img').each(function() 663 { 664 var factor = 100 * refH / $(this).height(); 665 if ( factor < 100 ) 666 { 667 $(this).parents('.inner-wrap').css('width',factor+'%'); 668 } 669 }); 670 if(sliderObj) 671 { 672 sliderObj.setDimensions(sliderObj); 673 } 674 }); 675 676}; 677 678 679/* 680================================================== 681Variable Responsive-Menüs 130710 (Wolfgang) [jQuery] 682================================================== 683Responsive-Menüs werden erst hinter dem Button versteckt, 684wenn sie auch tatsächlich zu breit werden 685 686benötigt jQuery 687*/ 688et.responsiveMenu = {} 689et.responsiveMenu.objsArr = [] 690 691et.responsiveMenu.update = function() 692{ 693 var len = et.responsiveMenu.objsArr.length, 694 winW = $(window).width(), 695 responsiveClass = 'responsive-on', 696 obj, 697 i; 698 for (i=0; i<len; i++) 699 { 700 obj = et.responsiveMenu.objsArr[i] 701 obj.container.removeClass(responsiveClass); 702 $('body').removeClass('responsive-menu-0'); 703 if (obj.breakFullW > winW && obj.maxW >= winW) 704 { 705 obj.container.addClass(responsiveClass); 706 $('body').addClass('responsive-menu-0'); 707 } 708 } 709} 710 711et.responsiveMenu.init = function() 712{ 713 var menu0 = 714 {
715 container : $('.area-menu-0'), 716 breakFullW : et.getDimensions($('.menu-0 > li')).outerWCombined+30, 717 maxW : 1100 718 }; 719 if ($('body').is('.layout-jugend')) 720 { 721 menu0.breakFullW = et.getDimensions($('.menu-0 > li, #header #logo, #header .search-header .show-search')).outerWCombined+35; 722 menu0.maxW = 1199; 723 } 724 if ($('body').is('.layout-dom')) 725 { 726 menu0.breakFullW = et.getDimensions($('.menu-0 > li, #header #logo, #header .search-header, .menu-lang li')).outerWCombined+100; 727 menu0.maxW = 1600; 728 } 729 // Buttons zum Menü-Ãffnen 730 $('.menu-0 li').has('ul').each(function(){ 731 var btn = $('<div href="#" class="btn icon"></div>'); 732 $(this).append(btn); 733 btn.click(function(e){ 734 $(this).parent().toggleClass('opened').siblings().removeClass('opened'); 735 }); 736 }); 737 $('.menu-0 .act').has('ul').addClass('opened'); 738 if (!$('body.mode-mobile').length) { 739 et.responsiveMenu.objsArr = [menu0]; 740 et.afterBrowserResize(et.responsiveMenu.update, false, true); 741 } 742 $('.responsive-menu-btn').click(function(e) 743 { 744 $('.area-menu-0').toggleClass('opened'); 745 $('body').toggleClass('mobile-mainmenu-open'); 746 }); 747 748} 749 750 751 752/* 753================================================== 754Popup-Search [jQuery] 755================================================== 756Such-Box im Header klappt aus (Jugend und Dom Template) 757*/ 758var headerSearch = function () { 759 var wrap = $('.search-header.popup-search'), 760 btn = wrap.find('.show-search'), 761 form = wrap.find('form'), 762 input = wrap.find('.input-text'); 763 764 btn.click(function (e) { 765 if (!wrap.is('.is-open')) { 766 form.css('display', 'block'); 767 btn.attr('aria-expanded', true); 768 setTimeout(function () { 769 wrap.addClass('is-open'); 770 input.trigger("focus"); 771 }, 30); 772 773 form.on('focusout.closesearch', function (e2) { 774 setTimeout(function () { 775 if (form.has($(document.activeElement)).length === 0) { 776 wrap.removeClass('is-open'); 777 btn.attr('aria-expanded', false); 778 form.off('.closesearch'); 779 setTimeout(function () { 780 if (!wrap.is('is-open')) { 781 form.css('display', 'none'); 782 } 783 }, 500); 784 } 785 }); 786 }); 787 } 788 }); 789}; 790$(document).ready(function () { 791 headerSearch(); 792}); 793 794 795 796/* 797================================================== 798Accordion [jQuery] 799================================================== 800*/ 801et.initAccordions = function() 802{ 803 $('.accordion-label').click(function(e) 804 { 805 var a = $(this).parents('.accordion').first(); 806 a.toggleClass('act').children('.accordion-content').stop().slideToggle(300); 807 a.siblings().removeClass('act').children('.accordion-content').stop().slideUp(300); 808 }); 809 $('.menu-archive .accordion:has(.act)').addClass('act'); 810 $('.accordion:not(.act) .accordion-content').hide(); 811} 812 813/* 814================================================== 815Footer-Social-Buttons ausrichten 816================================================== 817*/ 818et.SocialFooterBtns = function() 819{ 820 $('body:not(.layout-dom) #footer').find('a[href*="facebook."], a[href*="instagram."], a[href*="twitter."], a[href*="youtube."], a[href*="google."], a[href*="whatsapp."]').each(function() 821 { 822 $(this).attr('title',$(this).text()).parent().addClass('wrap-social-btn'); 823 }); 824} 825 826 827/* 828================================================== 829Pdf-Links in Subsites korrigieren 830================================================== 831Funktionieren sonst wegen Base-URL + Absrefprefix = / nicht korrekt 832*/ 833et.fixPdfLinks = function() 834{ 835 $('a[href*=".pdf"], a[href*=".PDF"], a[href*=".Pdf"]').each(function() 836 { 837 if ($(this).is('a[href^="/"]')) 838 { 839 var href = $(this).attr('href'); 840 href = href.substr(1, href.length-1); 841 $(this).attr('href',href); 842 } 843 }); 844}; 845 846/* 847================================================== 848Slider-Box komplett verlinken 849================================================== 850*/ 851et.linkFullSliderBox = function() 852{ 853 $('.top-slider .layer').each(function() 854 { 855 var textContainer = $(this).find('.overlay, .col-4'), 856 overLinks = textContainer.find('a'), 857 overHref = overLinks.attr('href'), 858 overTarget = overLinks.attr('target') || '_self', 859 differingOverHrefs = overLinks.length != overLinks.filter('a[href="'+overHref+'"]').length, 860 imgLink = $(this).find('.csc-textpic-imagewrap a, .wrap-img a'), 861 imgHref = imgLink.attr('href'), 862 imgTarget = imgLink.attr('target'), 863 imgLinkLightbox = imgLink.is('[rel^="lightbox"]'), 864 href = overHref || imgHref, 865 target = imgTarget || overTarget; 866 867 if ( !differingOverHrefs && !imgLinkLightbox && href && (overHref == imgHref || !overHref || !imgHref) ) 868 { 869 $(this).addClass('box-full-link').click(function(e) 870 { 871 e.preventDefault(); 872 window.open(href, target); 873 }); 874 } 875 else if (!differingOverHrefs && overHref) 876 { 877 textContainer.addClass('box-full-link').click(function(e) 878 { 879 e.preventDefault(); 880 window.open(href, target); 881 }); 882 } 883 884 }); 885} 886 887 888/* 889================================================== 890Fancybox (Lightbox) starten [Fancybox, jQuery] 891================================================== 892*/ 893et.initFancybox = function() 894{ 895 $('.top-slider').each(function() 896 { 897 var rel= 'lightbox['+$(this).parent().attr('id')+']'; 898 $(this).find('.lightbox').attr('rel',rel); 899 }); 900 $(".lightbox").fancybox({ 901 title:function() 902 { 903 var caption = $(this).find('.caption').html() || $(this).siblings('.caption').html() || '', 904 copyright = $(this).find('.copyright').html() || $(this).siblings('.copyright').html() || '';
905 copyright = copyright.length ? ' <span class="inline-copyright">'+copyright+'</span>' : ''; 906 return caption+copyright 907 }, 908 type : 'image', 909 helpers: { 910 title : { 911 type : 'inside' 912 } 913 } 914 }); 915} 916 917 918/* 919================================================== 920"Anchors" für Powermail-Formular-Actions 921================================================== 922*/ 923et.setPowermailAnchors = function() 924{ 925 var id = "#powermail-form"; 926 $('.tx-powermail form').each(function(){ 927 var f = $(this); 928 f.attr('action', f.attr('action')+id); 929 }) 930} 931 932 933/* 934================================================== 935Menu-0: 1. touch -> hover 936================================================== 937*/ 938et.initTouchHover = function() 939{ 940 // Nur relevant, wenn das Gerät überhaupt Touch unterstützt 941 if (!$('.touch-support').length) 942 { 943 return; 944 } 945 // touchstart hat Scrollen unterbunden, daher click; 946 // touchend hinzugefügt, da 'hover' auch bei nur leichter Berührung oder Scrollen funktionieren darf 947 $('.menu-0 > li > a, .box-cube a').on('click, touchend', function(e){ 948 // Nur weiter, wenn auch tatsächlich (bereits) getoucht wurde (wegen 'click') 949 if (!et.has.touchConfirmed) 950 { 951 return true 952 } 953 954 var elem = $(this), 955 cl = 'touch-hover'; 956 // Unterscheidung .menu-0/.box-cube 957 if (elem.parents('.menu-0').length) 958 { 959 // Wenn Responsive-Menü aktiv ist, gibt es kein hover 960 if ($('.area-menu-0.responsive-on').length) 961 { 962 return true; 963 } 964 elem = elem.parent(); 965 } 966 // Link ausführen, wenn das Elem nach erstem touch/klick nochmal geklickt wird 967 if (elem.hasClass(cl)) 968 { 969 return true; 970 } 971 // sonst stoppen, Klasse setzen und body-Listener setzen 972 else 973 { 974 e.preventDefault(); 975 $('.'+cl).removeClass(cl); 976 elem.addClass(cl); 977 // Nur das erste mal, wenn nach 'touch-hover' der body woanders getoucht/geklickt wird 978 // soll die Klasse auf dem Elem wieder entfernt werden 979 $('body').off('.touchhover').on('touchend.touchhover click.touchhover', function(e){ 980 var t = $(e.target); 981 if (!t.hasClass(cl) && !t.parents('.'+cl).length) 982 { 983 $('.'+cl).removeClass(cl); 984 $(this).off('.touchhover'); 985 } 986 }); 987 988 return false; 989 } 990 }); 991}; 992 993 994/* 995================================================== 996Fullsize-Img neben 600px-Teaser 997================================================== 998*/ 999et.alignFullSizeImg = function() 1000{ 1001 $('.full-size').each(function() 1002 { 1003 1004 var otherCol = $(this).parents('.csc-textpic').first().parent('.col-6').siblings('.col-6'); 1005 if(otherCol.find('.box-bigcube, .box-bigimgteaser').length) 1006 { 1007 $(this).addClass('h-600'); 1008 } 1009 }); 1010} 1011/* 1012================================================== 1013Support Youtube-iFrame mit "embed-container" 1014================================================== 1015*/ 1016et.supportYoutubeHtml = function() 1017{ 1018 $('*:not(.ece-media-element) > .embed-container:not(.no-helper)').wrap('<div class="col iframe-helper"></div>'); 1019} 1020 1021/* 1022================================================== 1023Fix Audio statt Video in News 1024================================================== 1025*/ 1026et.fixNewsAudio = function() 1027{ 1028 $('audio').each(function() 1029 { 1030 $(this).parents('.video-responsive-wrapper').addClass('wrap-audio wrap-media').removeClass('video-responsive-wrapper'); 1031 }); 1032} 1033 1034 1035/* 1036================================================== 1037Externe News kenntlich machen 1038================================================== 1039*/ 1040et.externalNews = function() 1041{ 1042 var curDomain = window.location.hostname; 1043 1044 $('.news-list-view a').each(function() 1045 { 1046 var a = $(this), 1047 href = a.attr('href'), 1048 hasDomain = href.indexOf('http') === 0 || href.indexOf('//') === 0, 1049 linkDomain = hasDomain ? href.split('//')[1].split('/')[0] : false; 1050 if (hasDomain && linkDomain !== curDomain) 1051 { 1052 a.addClass('external-news').attr('target','_blank').parent('.list-teaser').find('.wrap-txt p').after('<p class="source-news">Meldung von '+linkDomain+'</p>'); 1053 } 1054 }); 1055} 1056 1057 1058/* 1059================================================== 1060Captions über 2 Zeilen unter das Bild schieben 1061================================================== 1062*/ 1063et.fixCaptions = function() 1064{ 1065 if ($('.caption').length > 0) 1066 {
1067 et.afterBrowserResize(et.fixCaptions.update,false,true); 1068 } 1069} 1070et.fixCaptions.update = function() 1071{ 1072 setTimeout(function() 1073 { 1074 $('.caption').each(function() 1075 { 1076 var elem = $(this) 1077 h = elem.height(); 1078 // Zeilenhöhe ca. 18-21px 1079 if (h > 50) 1080 { 1081 elem.addClass('caption-below-img'); 1082 } 1083 else 1084 { 1085 elem.removeClass('caption-below-img'); 1086 } 1087 }); 1088 }, 800); 1089} 1090 1091$(document).ready(function() 1092{ 1093 et.responsiveMenu.init(); 1094 et.initAccordions(); 1095 et.initFancybox(); 1096 et.SocialFooterBtns(); 1097 et.linkFullSliderBox(); 1098 et.alignFullSizeImg(); 1099 et.supportYoutubeHtml(); 1100 et.setPowermailAnchors(); 1101 et.initTouchHover(); 1102 et.externalNews(); 1103 et.fixCaptions(); 1104 et.fixNewsAudio(); 1105 et.fixPdfLinks(); 1106}); 1107 1108 1109 function initOpenStreetMaps() { 1110 if (!$('div.openstreetmap').length) { 1111 return; 1112 } 1113 $("script.openstreetmap").each(function () { 1114 let script = $('<script></script>'); 1115 script.attr('src', $(this).attr('src')); 1116 $(this).before(script).remove(); 1117 }); 1118 } 1119 1120 jQ(document).ready(function() 1121 { 1122 placeHolderInDevMode(false); 1123 }); 1124 1125 1126 function placeHolderInDevMode(forceDev) 1127 { 1128 var isDev = window.location.href.indexOf("dev.") > -1 && window.location.href.indexOf("die-etagen") > -1; 1129 var isDev = (isDev) ? isDev : window.location.href.indexOf("vagrant") > -1; 1130 isDev = false; 1131 if(forceDev || isDev) 1132 { 1133 jQ('img').each(function() 1134 { 1135 var el = jQ(this), w = el.attr('width'), h = el.attr('height'); 1136 if(w && h) el.attr('src', 'https://www.placehold.it/' + w + 'x' + h); 1137 }); 1138 } 1139 } 1140 1141/** 1142 * Youtube API 1143 * 16-03-08 1144 * Andy 1145 * https://developers.google.com/youtube/v3/code_samples/javascript#authorizing_requests 1146 */ 1147 et.youTube = { 1148 init: function() 1149 { 1150 var listContainer = $('.youtube-list'); 1151 if (!listContainer.length) 1152 { 1153 return; 1154 } 1155 this.key = 'AIzaSyA5IVWtS2xBg8To6piDKKE2-TRiQoy78wQ'; 1156 this.channel = 'UCivfjXyf_3bPgwgIQaY2kRQ'; 1157 this.perPage = 20; 1158 this.listTarget = listContainer; 1159 1160 this.currentPage = 1; // gets ++ or -- according to the usage of the pagination since the api does not provide a page state 1161 1162 this.videos = {}; 1163 this.url = 'https://www.googleapis.com/youtube/v3/search?key=' + this.key + '&channelId=' + this.channel + '&part=snippet,id&order=date&maxResults=' + this.perPage + '&type=video'; 1164 this.iframe = false; 1165 1166 this.iframeTarget = jQ('<div/>', 1167 { 1168 class: 'embed-container', 1169 html: '' 1170 }).prependTo(listContainer); 1171 this.iframeTarget.wrap('<div class="yt-iframe-player col ece-media-element ece-media-type-youtube"></div>'); 1172 this.iframeTarget.parent().wrap('<div class="yt-iframe-player-wrap row bg-nonwhite row-over bg-maincolor"></div>'); 1173 1174 this.fetch(); 1175 this.listener(); 1176 1177 // et.afterBrowserResize.funcsArr.push(et.youTube.resize()); 1178 }, 1179 fetch: function(pageToken) 1180 { 1181 var url = this.url; 1182 if(typeof pageToken != 'undefined') 1183 { 1184 url += '&pageToken=' + pageToken; 1185 } 1186 jQ.ajax(url, { 1187 success: function(data) 1188 { 1189 et.youTube.videos = data; 1190 et.youTube.renderList(); 1191 }, 1192 error: function() 1193 { 1194 et.youTube.errorHandler(); 1195 } 1196 }); 1197 }, 1198 errorHandler: function() 1199 { 1200 console.log('-'); 1201 }, 1202 renderList: function() 1203 { 1204 if(!this.list) 1205 { 1206 this.list = jQ('<div/>', 1207 { 1208 class: 'news-list-view row flex-grid', 1209 html: '' 1210 }); 1211 this.list.appendTo(this.listTarget); 1212 } 1213 this.renderItems(et.youTube.videos.items); 1214 this.renderPagination(); 1215 }, 1216 renderItems: function(videos) 1217 { 1218 et.youTube.list.html(''); 1219 jQ.each(videos, function(i, v) 1220 { 1221 var img = '<div class="wrap-img"><img src="' + v.snippet.thumbnails.medium.url + '" /></div>', 1222 //text = '<h3 class="h4">' + v.snippet.title + '</h3><div><div><p>' + v.snippet.description + '</p></div></div>', 1223 text = '<h3 class="h4">' + v.snippet.title + '</h3><div><div></div></div>', 1224 btn = '<div class="btn btn-pseudo arrow right">Ansehen</div>'; 1225 1226 var content = img + '<div class="wrap-txt">' + text + btn + '</div>'; 1227 1228 var teaser = jQ('<a/>', 1229 { 1230 class: 'row no-border', 1231 href: '#', 1232 html: content, 1233 }).attr('data-yt-id', v.id.videoId); 1234 1235 var item = jQ('<div/>', { 1236 id: 'yt-video-' + v.id.videoId, 1237 class: 'box box-link box-teaser col-3', 1238 html: teaser, 1239 }).appendTo(et.youTube.list); 1240 }); 1241 1242 this.resize(); 1243 }, 1244 renderPagination: function() 1245 { 1246 var total = et.youTube.videos.pageInfo.totalResults; 1247 if(total > this.perPage) 1248 { 1249 var pages = Math.floor(total / this.perPage); 1250 } 1251 if(this.paginationWrap) { 1252 this.paginationWrap.remove(); 1253 } 1254 1255 this.paginationWrap = jQ('<div/>', 1256 { 1257 class: 'page-navigation col yt-pagination', 1258 html: '' 1259 }).appendTo(this.listTarget); 1260 1261 var pagination = jQ('<ul/>', 1262 { 1263 class: 'f3-widget-paginator menu menu-pagination', 1264 html: '' 1265 }).appendTo(this.paginationWrap); 1266 1267 if(this.videos.prevPageToken) { 1268 jQ('<li/>', 1269 { 1270 class: 'prev', 1271 html: '<a href="#" class="neg-arrow arrow left">vorherige</a>' 1272 }).on('click', 'a', function(e) { 1273 et.youTube.currentPage--; 1274 et.youTube.rerender(e, et.youTube.videos.prevPageToken); 1275 }).appendTo(pagination); 1276 } 1277 1278 jQ('<li/>', 1279 { 1280 class: 'pages', 1281 html: '<ul><li>Seite ' + et.youTube.currentPage + ' von ' + pages + '</li></ul>' 1282 }).appendTo(pagination); 1283 1284 if(this.videos.nextPageToken && this.currentPage < pages) { 1285 jQ('<li/>', 1286 { 1287 class: 'next', 1288 html: '<a href="#" class="neg-arrow arrow right">nächste</a>' 1289 }).on('click', 'a', function(e) { 1290 et.youTube.currentPage++; 1291 et.youTube.rerender(e, et.youTube.videos.nextPageToken); 1292 }).appendTo(pagination); 1293 } 1294 1295 }, 1296 rerender: function(e, token) { 1297 e.preventDefault(); 1298 this.list.addClass('loading'); 1299 this.fetch(token); 1300 this.list.scrollToTarget({offsetTop: 15}); 1301 setTimeout(function() { 1302 et.youTube.list.removeClass('loading'); 1303 }, 500); 1304 }, 1305 listener: function() 1306 { 1307 this.listTarget.on('click', 'a[data-yt-id]', function(e) 1308 { 1309 e.preventDefault(); 1310 var id = $(this).data('yt-id'); 1311 1312 if(et.youTube.iframe) 1313 { 1314 et.youTube.iframe.remove(); 1315 } 1316 et.youTube.iframe = jQ('<iframe id="ytplayer" type="text/html" width="1280" height="720" allowfullscreen src="https://www.youtube-nocookie.com/embed/' + id + '?autoplay=1&rel=0" frameborder="0"/>');
1317 jQ('.yt-iframe-player-wrap').show(); 1318 et.youTube.iframe.appendTo(et.youTube.iframeTarget).scrollToTarget({offsetTop: 15}); 1319 }); 1320 }, 1321 resize: function() 1322 { 1323 setTimeout(function() 1324 { 1325 if(et.youTube.list) { 1326 et.youTube.list.find('.box-teaser').removeAttr('style').css('height', et.getDimensions(et.youTube.list.find('.box-teaser')).hMax); 1327 } 1328 }, 500); 1329 }, 1330 }; 1331 1332 $.fn.scrollToTarget = function(conf) { 1333 var def = {duration: 500, offsetTop: 0, position: false, checkVisibility: false, callback: false}; 1334 var c = $.extend({}, def, conf); 1335 $.extend({}, conf, c); 1336 c.checkVisibility = (c.checkVisibility && jQuery().visible); 1337 c.offsetTop = parseInt(c.offsetTop) || 0; 1338 1339 var offset = this.offset(); 1340 var target = parseInt(c.position) || (offset.top - c.offsetTop); 1341 1342 if(!c.checkVisibility || (c.checkVisibility && !this.visible()) || (target <= (jQuery(window).scrollTop() + c.offsetTop))) 1343 { 1344 jQuery('body, html').animate({ scrollTop: target }, c.duration, function() {if(c.callback && typeof c.callback == "function") {c.callback();}}); 1345 } 1346 return this; 1347 }; 1348 1349 jQ(document).ready(function() 1350 { 1351 // fix links to bet _blank inside "Bistumszeilen" on Subsites 1352 jQ('.layout-subsite .mainpage-subsite-addition a').each(function() 1353 { 1354 if(jQ(this).attr('target') != '_blank') 1355 { 1356 jQ(this).attr('target', '_blank'); 1357 } 1358 }); 1359 1360 jQ('.box.box-link.list-teaser p').each(function() { 1361 var p = jQ(this); 1362 if(p.html().replace(/\s| /g, '').length == 0) 1363 { 1364 p.remove(); 1365 } 1366 p.html(p.html().replace(/ /g, '')); 1367 }); 1368 }); 1369 1370 jQ(window).resize(function() 1371 { 1372 if(jQ(window).width() > 900) 1373 et.youTube.resize(); 1374 }); 1375 1376 1377 1378 1379 1380/* 1381================================================== 1382Fix: Youtube-Videos ohne Related Videos (rel=0) 1383================================================== 1384Aktuell kann man rel=0 im Gegensatz zu anderen Parametern nicht per Fluid-Template setzen. 1385Entfernen, sobald nicht mehr benötigt. 1386*/ 1387et.ytRemoveRelated = function() 1388{ 1389 $('iframe[src*=youtube]').each(function() 1390 { 1391 var vid = $(this), 1392 separator = vid.attr('src').indexOf('?') !== -1 ? '&' : '?', 1393 vidSrc = vid.attr('src'), 1394 vidSrcArray = vidSrc.split('?'); 1395 if (vidSrcArray.length > 2) 1396 { 1397 vidSrc = vidSrcArray[0]+'?'+vidSrcArray[1]; 1398 for(i=2; i < vidSrcArray.length; i++ ) 1399 { 1400 vidSrc += "&"+ vidSrcArray[i]; 1401 } 1402 } 1403 vid.attr('src', vidSrc + separator + 'rel=0'); 1404 }); 1405} 1406 1407et.etagenCookie = function() 1408{ 1409 // HTML-Youtube-Videos automatisch anpassen: 1410 $('iframe[src*="youtube-nocookie"], iframe[data-src*="youtube-nocookie"], iframe[data-src*="youtube.com"]').addClass('et-cookie-set-blocker bg-maincolor cookiePermission media youtube'); 1411 1412 let etCookieOptions = { 1413 mainText: "Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten und die Zugriffe auf unsere Website analysieren zu können. Informationen können für soziale Medien, Werbung und Analysen an Dritte weitergegeben werden. Diese Dritten führen die Informationen möglicherweise mit Daten aus anderen Quellen zusammen." + 1414 "<br><br>" + 1415 "Hierbei können auch Dienstleister aus Drittländern, d.h. insbesondere aus Ländern auÃerhalb der EU ohne angemessenes Datenschutzniveau, eingesetzt werden. Das birgt folgende Risiken: Zugriff durch Behörden ohne Benachrichtigung, keine Betroffenenrechte oder Rechtsmittel, Verlust der Kontrolle über die Datenverarbeitung. Mit Ihrer Einstellung willigen Sie in die beschriebenen Vorgänge ein. Sie können Ihre Einwilligung mit Wirkung für die Zukunft widerrufen. Mehr Informationen finden Sie in unserer <a href='/datenschutz'>Datenschutzerklärung</a>.", 1416 kinds: [ 1417 { 1418 kind: "necessary", 1419 title: "Notwendig", 1420 disabled: true, 1421 checked: true, 1422 details: "Diese Cookies sind notwendig, um den Betrieb unserer Seite für Sie reibungslos möglich zu machen." 1423 }, 1424 { 1425 kind: "analytics", 1426 title: "Statistik", 1427 details: "Mit unserer Statistikeinstellung bestätigen Sie die Nutzung von Cookies zur Verbesserung unserer Angebote. Wir nutzen Google Analytics. Hierbei können wir zum Beispiel einsehen, wer sich auf unserer Seite wo bewegt, um Inhalte noch einfacher für Sie darstellen zu können." 1428 }, 1429 { 1430 kind: "media", 1431 title: "Externe Medien", 1432 details: "Inhalte von Video- und Audioplattformen sowie von Karten- und Grafikdesigndiensten werden blockiert. Wenn Cookies von externen Medien akzeptiert werden, bedarf der Zugriff auf diese Inhalte keiner manuellen Einwilligung mehr." 1433 } 1434 ], 1435 deleteCookies: ['cookieconsent_status'], 1436 contentBlockers: [ 1437 {
1438 selector: "iframe[src*='youtube-nocookie.com'].et-cookie-set-blocker, iframe[data-src*='youtube-nocookie.com'].et-cookie-set-blocker", 1439 kind: "media", 1440 text: "<p>Wenn Sie hier klicken, wird ein Video geladen. <br>Ihre IP-Adresse wird hierbei an YouTube übermittelt.</p>", 1441 showBlockerWithoutHover: true 1442 }, 1443 { 1444 selector: "iframe[data-src*='soundcloud.com']", 1445 kind: "media", 1446 text: "<p>Wenn Sie hier klicken, wird ein Audioplayer geladen. <br>Ihre IP-Adresse wird hierbei an Soundcloud übermittelt.</p>", 1447 showBlockerWithoutHover: true 1448 }, 1449 { 1450 selector: ".map-canvas, .googlemap.et-cookie-set-blocker", 1451 kind: "media", 1452 text: "<p>Wenn Sie hier klicken, wird eine Karte geladen. <br>Ihre IP-Adresse wird hierbei an Google übermittelt.</p>", 1453 showBlockerWithoutHover: true 1454 }, 1455 { 1456 selector: ".openstreetmap.et-cookie-set-blocker", 1457 kind: "media", 1458 text: "<p>Wenn Sie hier klicken, wird eine Karte geladen. <br>Ihre IP-Adresse wird hierbei an OpenStreetMap übermittelt.</p>", 1459 showBlockerWithoutHover: true 1460 }, 1461 { 1462 selector: ".kizfeed", 1463 kind: "standalone-blocker", 1464 text: "<p>Wenn Sie hier klicken, wird ein Feed der KirchenZeitung im Bistum Hildesheim geladen. Dabei werden Ihre IP und externe Cookies, darunter auch statistische, übermittelt.</p>", 1465 showBlockerWithoutHover: true 1466 }, 1467 { 1468 selector: ".youtube-list", 1469 kind: "media", 1470 text: "<p>Wenn Sie hier klicken, werden einige Video-Teaser geladen. <br>Ihre IP-Adresse wird hierbei an YouTube übermittelt.</p>", 1471 showBlockerWithoutHover: true 1472 }, 1473 { 1474 selector: ".pikto-canvas-wrap.et-cookie-set-blocker", 1475 kind: "media", 1476 text: "<p>Wenn Sie hier klicken, wird eine Grafik mit statistischen Zahlen zum Bistum Hildesheim geladen.<br> Dabei werden Cookies auf dem Rechner gespeichert.</p>", 1477 showBlockerWithoutHover: true 1478 }, 1479 { 1480 selector: ".crArchive.et-cookie-set-blocker", 1481 kind: "media", 1482 text: "<p>Wenn Sie hier klicken, wird eine Liste der versendeten Newsletter geladen.<br> Es erfolgt ein Datentransfer an CleverReach.</p>", 1483 showBlockerWithoutHover: true 1484 } 1485 ], 1486 } 1487 1488 $(document).one('etCookiesAllowed-analytics', function () { 1489 console.log('Tracking jetzt einmalig ausführen!'); 1490 if (typeof triggerAnalytics !== 'undefined') 1491 { 1492 triggerAnalytics(); 1493 } 1494 }); 1495 $(document).one('etCookiesAllowed-media', function () { 1496 et.youTube.init(); 1497 initPiktoChart(); 1498 }); 1499 1500 $('body').etagenCookie(etCookieOptions); 1501 1502 $('.openstreetmap + .et-cookie-blocker .et-cookie-blocker--show-content').click(function(){ 1503 initOpenStreetMaps(); 1504 }); 1505 $('.wrap-youtube-list .et-cookie-blocker--show-content').click(function(){ 1506 et.youTube.init(); 1507 }); 1508 $('.piktowrapper-embed .et-cookie-blocker--show-content').click(function(){ 1509 initPiktoChart(); 1510 }); 1511 $('.crArchive + .et-cookie-blocker .et-cookie-blocker--show-content').click(function(){ 1512 const scr = $(this).parent().parent().parent().find('script.cookiePermission'); 1513 let script = $('<script></script>'); 1514 script.attr('src', scr.attr('src')); 1515 scr.before(script).remove(); 1516 }); 1517} 1518 1519// PiktoChart auf Seite https://www.bistum-hildesheim.de/bistum/bistum-in-zahlen/ (id=280) 1520initPiktoChart = function() { 1521 if ($('.piktowrapper-embed').length) { 1522 (function (d) { 1523 var js, id = "pikto-embed-js", ref = d.getElementsByTagName("script")[0]; 1524 if (d.getElementById(id)) { 1525 return; 1526 } 1527 js = d.createElement("script"); 1528 js.id = id; 1529 js.async = true; 1530 js.src = "https://create.piktochart.com/assets/embedding/embed.js"; 1531 ref.parentNode.insertBefore(js, ref); 1532 }(document)); 1533 } 1534} 1535 1536$(document).ready(function() 1537{ 1538 et.ytRemoveRelated(); 1539 et.etagenCookie(); 1540 1541 // Google OptOut aufrufen (setzt einen lokalen Disable-Cookie) 1542 $('a[href*="#ga-opt-out"]').click(function(e){ 1543 e.preventDefault(); 1544 try { 1545 gaOptout(); 1546 } 1547 catch(err) { 1548 console.log(err); 1549 } 1550 }); 1551 1552}); 1553 1554// Google Analytics: PDFs usw. tracken 1555// http://www.blastam.com/blog/how-to-track-downloads-in-google-analytics-v2 1556// angepasst auf ga: 1557// https://developers.google.com/analytics/devguides/collection/analyticsjs/events 1558if (typeof jQuery != 'undefined') { 1559 1560 jQuery(document).ready(function($) { 1561 var filetypes = /\.(zip|exe|dmg|pdf|doc.*|xls.*|ppt.*|mp3|txt|rar|wma|mov|avi|wmv|flv|wav)$/i; 1562 var baseHref = ''; 1563 if (jQuery('base').attr('href') != undefined) baseHref = jQuery('base').attr('href'); 1564 1565 jQuery('a').on('click', function(event) { 1566 var el = jQuery(this); 1567 var track = true; 1568 var href = (typeof(el.attr('href')) != 'undefined' ) ? el.attr('href') :""; 1569 var isThisDomain = href.match(document.domain.split('.').reverse()[1] + '.' + document.domain.split('.').reverse()[0]); 1570 if (!href.match(/^javascript:/i)) { 1571 var elEv = []; elEv.value=0, elEv.non_i=false; 1572 if (href.match(/^mailto\:/i)) { 1573 elEv.category = "email"; 1574 elEv.action = "click"; 1575 elEv.label = href.replace(/^mailto\:/i, ''); 1576 elEv.loc = href; 1577 } 1578 else if (href.match(filetypes)) { 1579 var extension = (/[.]/.exec(href)) ? /[^.]+$/.exec(href) : undefined; 1580 elEv.category = "download"; 1581 elEv.action = "click-" + extension[0]; 1582 elEv.label = href.replace(/ /g,"-"); 1583 elEv.loc = baseHref + href; 1584 } 1585 else if (href.match(/^https?\:/i) && !isThisDomain) { 1586 elEv.category = "external"; 1587 elEv.action = "click"; 1588 elEv.label = href.replace(/^https?\:\/\//i, ''); 1589 elEv.non_i = true; 1590 elEv.loc = href; 1591 } 1592 else if (href.match(/^tel\:/i)) { 1593 elEv.category = "telephone"; 1594 elEv.action = "click"; 1595 elEv.label = href.replace(/^tel\:/i, ''); 1596 elEv.loc = href; 1597 } 1598 else track = false;
1599 if (track && typeof ga != 'undefined') { 1600 ga('send','event',elEv.category.toLowerCase(), elEv.action.toLowerCase(), elEv.label.toLowerCase(), elEv.value, {nonInteraction: elEv.non_i}); 1601 if ( el.attr('target') == undefined || el.attr('target').toLowerCase() != '_blank') { 1602 setTimeout(function() { location.href = elEv.loc; }, 400); 1603 return false; 1604 } 1605 } 1606 } 1607 }); 1608 }); 1609} 1610 1611function resizeGridItem(item){ 1612 var grid = document.getElementsByClassName("grid-masonry")[0]; 1613 var rowHeight = parseInt(window.getComputedStyle(grid).getPropertyValue('grid-auto-rows')); 1614 var rowGap = parseInt(window.getComputedStyle(grid).getPropertyValue('grid-row-gap')); 1615 var rowSpan = Math.ceil((item.querySelector('.wrap-content').getBoundingClientRect().height+rowGap+30)/(rowHeight+rowGap)); 1616 item.style.gridRowEnd = "span "+rowSpan; 1617} 1618function resizeAllGridItems(){ 1619 var allItems = document.getElementsByClassName("prayer"); 1620 for(x=0;x<allItems.length;x++){ 1621 resizeGridItem(allItems[x]); 1622 } 1623} 1624window.onload = resizeAllGridItems(); 1625window.addEventListener("resize", resizeAllGridItems); 1626 1627// In HTML-Elementen gesetzte Cleverreach-Formulare werden per TS umgeschrieben (action -> data-action) 1628// und per JS wieder lauffähig gemacht. 1629// Honeypot ".et_name" sollte nicht befüllt sein, sonst wird nicht versendet. 1630function spamPreventHtmlForms() { 1631 $('form.et-protected').each(function(){ 1632 const f = $(this); 1633 if (!f.attr('action')) { 1634 f.attr('action',f.data('action')); 1635 } 1636 f.submit(function(e){ 1637 const hp = f.find('.et_name'); 1638 if (hp.val()) { 1639 e.preventDefault(); 1640 alert('Spam detected.'); 1641 } 1642 }); 1643 }); 1644} 1645// In diesen Cleverreach-Formularen fehlen zudem (meist) die passenden Pflichtfeld-Attribute 1646function addValidationHtmlForms() { 1647 $('.cr_form .musthave input:not([required])').attr('required','1'); 1648 $('.cr_form .musthave[rel="email"] input[type="text"]').attr('type','email'); 1649} 1650$(document).ready(function(){ 1651 spamPreventHtmlForms(); 1652 addValidationHtmlForms(); 1653}); 1654 1655 1656 1657/* 1658================================================== 1659Select-Link [jQuery] 1660================================================== 1661select.change-reload-value options haben als value eine URL 1662Diese wird geladen, wenn sich der select-value ändert 1663Va. für Solr-Facetten genutzt 1664*/ 1665et.selectChangeUrl = function() { 1666 $('.change-reload-value').each(function () { 1667 var select = $(this); 1668 select.change(function () { 1669 var value = select.find('option:selected').val(); 1670 if (value.charAt(0) !== "/" && !value.startsWith("http:") && !value.startsWith("https:")) { 1671 window.location = "/" + value; 1672 } else { 1673 window.location = value; 1674 } 1675 }); 1676 }); 1677} 1678 1679$(document).ready(function(){ 1680 et.selectChangeUrl(); 1681}); 1682 1683 1684 1685/* 1686================================================== 1687Test webp und ggf. auf Fallback umstellen 1688================================================== 1689srcset wird von Browsern bevorzugt. 1690Da liegen aber nur webp Bilder drin. 1691Wird webp nicht unterstützt, entfernt dieses JS alle srcset-Attribute, 1692damit der Browser das Fallback-jpg/png im src anzeigt. 1693--> Irgendwann nebst jpg-Fallbacks einfach entfernen! 1694https://caniuse.com/webp 1695*/ 1696et.checkWebp = function(callback) { 1697 var img = new Image(); 1698 img.onload = function () { 1699 var result = (img.width > 0) && (img.height > 0); 1700 callback(result); 1701 }; 1702 img.onerror = function () { 1703 callback(false); 1704 }; 1705 img.src = "data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA"; 1706} 1707$(document).ready(function() 1708{ 1709 if ('supports-webp' in localStorage) { 1710 if (localStorage.getItem('supports-webp') !== 'true') { 1711 $('img[src]').removeAttr('srcset'); 1712 } 1713 } else { 1714 et.checkWebp(function(result){ 1715 if (!result) { 1716 $('img[src]').removeAttr('srcset'); 1717 } 1718 localStorage.setItem('supports-webp', JSON.stringify(result)); 1719 }); 1720 } 1721}); 1722 1723 1724/* 1725================================================== 1726Fix Powermail: Bessere Duplikat-Warnung 1727================================================== 1728https://github.com/in2code-de/powermail/blob/master/Documentation/ForAdministrators/BestPractice/PreventDuplicates.md 1729 1730TODO: Anpassung anders lösen (TS-replacement klappte aber nicht) 1731*/ 1732$(document).ready(function() 1733{ 1734 $('.powermail_message_error li').each(function(){ 1735 let li = $(this), 1736 text = li.text() || '', 1737 msg = "Sie haben diese Mail bereits versendet."; 1738 if (text.indexOf('timestamppreventduplicates') !== -1) { 1739 li.text(msg); 1740 } 1741 }); 1742});
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.