b0y-101 Mini Shell


Current Path : E:/www/risk/modules/mod_djmegamenu/assets/js/
File Upload :
Current File : E:/www/risk/modules/mod_djmegamenu/assets/js/jquery.djmobilemenu.js

/**
 * @package DJ-MegaMenu
 * @copyright Copyright (C) 2022 DJ-Extensions.com, All rights reserved.
 * @license DJ-Extensions.com Proprietary Use License
 * @author url: https://dj-extensions.com
 * @author email contact@dj-extensions.com
 * @developer Szymon Woronowski, Artur Kaczmarek
 */

 var DJMegaMobile;

(function($) {
	DJMegaMobile = function () {
		this.mega = [];
		this.timer = null;

		this.init();
	};

	DJMegaMobile.prototype.init = function () {

		var self = this;

		// init mobile menu
		$('.dj-megamenu:not(.dj-megamenu-sticky)').each(function() {
			
			var menu = $(this);
			var mobile = $('#'+menu.prop('id')+'mobile');
			var offcanvas = $('#'+menu.prop('id')+'offcanvas');
			
			var idx = self.mega.length;
			self.mega[idx] = {};
			self.mega[idx].id = menu.prop('id');
			self.mega[idx].trigger = menu.data('trigger');
			self.mega[idx].menu = menu;
			self.mega[idx].menuHandler = $('<div />');
			self.mega[idx].mobile = mobile.length ? mobile : null;
			self.mega[idx].mobileHandler = $('<div />');
			self.mega[idx].offcanvas = offcanvas.length ? offcanvas : null;
			self.mega[idx].offcanvasHandler = $('<div />');
			
			var wrapper = $('#'+menu.prop('id')+'mobileWrap');
			if(wrapper.length) {
				wrapper.empty().append(self.mega[idx].mobile);
			}
			
			if(self.mega[idx].mobile) {
				// remove hidden menu items from the DOM
				self.mega[idx].mobile.find('.dj-hideitem').remove();
				
				if(self.mega[idx].mobile.hasClass('dj-megamenu-offcanvas')) {
					self.createOffcanvas(self.mega[idx].mobile);
				} else if(self.mega[idx].mobile.hasClass('dj-megamenu-accordion')) {
					self.createAccordion(self.mega[idx].mobile);
				}
				
				// fix double collapse Joomla!3 Protostar 
				self.mega[idx].mobile.parents('.nav-collapse').addClass('collapse in').css('height', 'auto').prev('.navbar').remove();
				
				// fix double collapse Joomla!4 Cassiopeia
				self.mega[idx].mobile.parents('.navbar-collapse').addClass('show').prev('.navbar-toggler').remove();
			}

		});

		$(window).resize(self.switchMenu.bind(self));
		self.switchMenu();

		$(document).on('click', '.dj-offcanvas-open', function(e) {
			if( $(e.target).parents('.dj-offcanvas').length || $(e.target).hasClass('dj-offcanvas')) return;
			//if clicked outside offcanvas close it
			$('.dj-offcanvas-opened').find('.dj-offcanvas-close-btn').click();
		});

		$(document).on('djmegamobile:pageload', function() {
			for(var idx = 0; idx < self.mega.length; idx++) {
				if(self.mega[idx].mobile) {
					if(self.mega[idx].mobile.hasClass('dj-megamenu-select')) {
						self.createSelectMenu(self.mega[idx].menu, self.mega[idx].mobile);
					}
				}
			}
		});
	};

	DJMegaMobile.prototype.createSelectMenu = function(menu, mobile) {
		
		// Create the dropdown base
		var id = menu.attr('id');
		var name = mobile.attr('data-label') || 'menu';

		var btn_open = mobile.find('.dj-mobile-open-btn');

		var select = $('<select id="'+ id +'select" class="inputbox dj-select" />');

		select.on('click blur', function() {
			btn_open.toggleClass('active');
		});

		select.on('change', function() {
			btn_open.removeClass('active');
			if($(this).val) window.location = $(this).val();
		});

		var label = $('<label class="hidden" aria-hidden="true" for="'+ id +'select">' + name + '</label>')

		var list = menu.find('li.dj-up');
		this.addOptionsFromDJMegaMenu(list, select, 0);
		
		label.appendTo(mobile);
		select.appendTo(mobile);
		
		btn_open.on('click', function(e){

			e.stopPropagation();
			e.preventDefault();

			var element = select[0];
			if (document.createEvent) { // all browsers
				var ev = document.createEvent("MouseEvents");
				ev.initMouseEvent("mousedown", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
				element.dispatchEvent(ev);
			} else if (element.fireEvent) { // ie
				element.fireEvent("onmousedown");
			}
		});
	};
	
	DJMegaMobile.prototype.addOptionsFromDJMegaMenu = function(items, select, level) {
		var self = this;

		var sep = '',
		active = false;
		for(var i=0;i<level;i++) {
			sep += '- ';
		}
		//console.log(items);
		items.each(function(){
			
			var item = $(this);

			var link = item.find('> a').first();
			var kids = item.find('> .dj-subwrap > .dj-subwrap-in > .dj-subcol > .dj-submenu > li, > .dj-subtree > li');
			
			if(link.length) {
				var text = '';
				var img = link.find('img').first();
				if(img.length) {
					text = sep + img.attr('alt');
				} else {
					text = link.html().replace(/(<small[^<]+<\/small>)/ig,"");
					text = sep + text.replace(/(<([^>]+)>)/ig,"");
				}
				//console.log(text);
				var option = $('<option value="'+link.prop('href')+'">'+ text +'</option>').appendTo(select);
				if(!link.prop('href')) { option.prop('disabled',true); }
				if(item.hasClass('active')) {
					select.val(option.val());
					active = true;
				}
			}
			if(kids) self.addOptionsFromDJMegaMenu(kids, select, level+1);
		});
		
		if(!level && !active) {
			//$('<option value="">Menu</option>').prependTo(select);
			select.val('');
		}
	};
	
	DJMegaMobile.prototype.initAccordion = function(mobile) {
		//console.log('initAccordion');
		var focusTimer = null;

		var btn_close = mobile.find('.dj-offcanvas-close-btn');

		mobile.find('ul.dj-mobile-nav > li, ul.dj-mobile-nav-child > li').each(function(){
			
			var menu = $(this);
			var anchor = menu.find('> a').first();

			if(anchor.length) {

				var subs = menu.find('> ul.dj-mobile-nav-child > li:not(:empty)');

				if( !subs.length ) {
					menu.removeClass('parent');
					menu.find('ul.dj-mobile-nav-child').remove();
				}

				if( menu.hasClass('parent') ) {
					
					if( menu.hasClass('active') ) {
						anchor.attr('aria-expanded', true);
						menu.find('> ul').slideDown(400);
					} else {
						anchor.attr('aria-expanded', false);
					}
					
					anchor.append('<span class="toggler"></span>');
				}
				
				anchor.on('click',function(e) {

					var $this = $(this);
					var is_toggler = $(e.target).hasClass('toggler');
					var _href = $this.attr('href');
					var _hash = ( _href != undefined && _href.length > 1 && _href.indexOf('#') !== -1 ) ? true : false;

					clearTimeout(focusTimer);

					//detect hash, close off-canvas
					if ( _hash && ! is_toggler && e.which ) { //e.which detects if a real click
						$(document.body).addClass('dj-offcanvas-no-effects');
						btn_close.click();
					} else if( menu.hasClass('parent') && !menu.hasClass('active') ) {
						e.preventDefault(); //first click - open submenu
					} else if( is_toggler ) { //second click in toggler - close submenu
						e.preventDefault();
						e.stopPropagation();
						
						menu.removeClass('active').find('> ul').slideUp(400);
						$this.attr('aria-expanded', false);
					}

				});

				anchor.on('focus',function() {

					var $this = $(this);

					mobile.find('[aria-expanded]').attr('aria-expanded', false);
					$this.parents('.active').find('> [aria-expanded]').attr('aria-expanded', true);
					$this.attr('aria-expanded', true);

					focusTimer = setTimeout(function(){
						menu.click();
					}, 250);
				});
			}
			
			menu.on('click', function( e ) {
				menu.siblings().removeClass('active').find('> ul').slideUp(400);
				menu.addClass('active').find('> ul').slideDown(400);
			});
		});
	};
	
	DJMegaMobile.prototype.createOffcanvas = function(mobile) {
		
		var isJoomla4 = mobile.parents('[data-joomla4]').length ? true : false;
		var template = mobile.parents('[data-tmpl]').attr('data-tmpl');

		var FXnotSupported = ( 'cassiopeia' === template ) ? true : false;

		var content 	= null;
		var wrapper 	= $('.dj-offcanvas-wrapper').first();
		var pusher 		= $('.dj-offcanvas-pusher').first();
		var pusherIn 	= $('.dj-offcanvas-pusher-in').first();
		
		if( ! wrapper.length ) {
			content		= $(document.body).children();
			wrapper		= $('<div class="dj-offcanvas-wrapper" />');
			pusher		= $('<div class="dj-offcanvas-pusher" />');
			pusherIn	= $('<div class="dj-offcanvas-pusher-in" />');
		}
		
		var allOffcanvas = $('.dj-offcanvas');
		var offcanvas = mobile.find('.dj-offcanvas').first();


		var fx = ( FXnotSupported || ! wrapper.length || allOffcanvas.length > 1 ) ? '1' : offcanvas.data('effect');
		var simple_fx = ( fx == 1 ) ? true : false; //effect slide in on top
		
		$(document.body).addClass('dj-megamenu-offcanvas dj-offcanvas-effect-' + fx);

		//if simple effect, no need to add pushers
		if( !simple_fx ) {
			if(content) $(document.body).prepend(wrapper);
			if(fx == 3 || fx == 6 || fx == 7 || fx == 8 || fx == 14) {
				pusher.append(offcanvas);
			} else {
				wrapper.append(offcanvas);
			}
			if(content) {
				wrapper.append(pusher);
				pusher.append(pusherIn);
				pusherIn.append(content);
			}
		} else {
			$(document.body).append(offcanvas); //move offcanvas to the end
		}

		allOffcanvas.hide();

		var timer = null;

		var btn_open = mobile.find('.dj-mobile-open-btn');
		var btn_close = offcanvas.find('.dj-offcanvas-close-btn');
		var last_item = offcanvas.find('button, a, input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])').last();

		btn_open.on('click', function(e){
			e.stopPropagation();
			e.preventDefault();
			if( $(document.body).hasClass('dj-offcanvas-open') ) {
				btn_open.removeClass('active');
				btn_close.click();
			} else {

				btn_open.addClass('active');

				clearTimeout(timer);
				offcanvas.data('scroll', $(window).scrollTop());
				$(document.body).addClass('dj-offcanvas-anim').removeClass('dj-offcanvas-no-effects');
				setTimeout(function(){
					$(document.body).addClass('dj-offcanvas-open');
				}, 50 );

				if( ! simple_fx ) {
					pusherIn.css('top', -offcanvas.data('scroll'));
				}

				allOffcanvas.hide();
				offcanvas.show();
				offcanvas.removeAttr('aria-hidden');
				offcanvas.attr('role', 'dialog');
				offcanvas.attr('aria-modal', 'true');
				offcanvas.addClass('dj-offcanvas-opened');

				if( ! $('.dj-megamenu-offcanvas-overlay').length ) {
					offcanvas.parent().append('<div class="dj-megamenu-offcanvas-overlay" />');
				}

				//move focus to offcanvas
				setTimeout(function(){
					btn_close.focus();
				}, 250 );
			}
		});

		btn_close.on('click', function(e) {
			e.stopPropagation();
			e.preventDefault();

			if($(document.body).hasClass('dj-offcanvas-open')) {

				btn_open.removeClass('active');

				$(document.body).removeClass('dj-offcanvas-open');
				
				if( $(document.body).hasClass('dj-offcanvas-no-effects') ) {

					if( !simple_fx ) pusherIn.css('top', 0);

					$(document.body).removeClass('dj-offcanvas-anim dj-offcanvas-no-effects');
					offcanvas.hide();
					btn_open.focus();
				} else {
					timer = setTimeout(function(){

						if( !simple_fx ) pusherIn.css('top', 0);

						$(document.body).removeClass('dj-offcanvas-anim');
						$(window).scrollTop($(window).scrollTop() + offcanvas.data('scroll'));
						offcanvas.hide();
						btn_open.focus();
					}, 250 );
				}
				
				offcanvas.attr('aria-hidden', 'true');
				offcanvas.removeAttr('role');
				offcanvas.removeAttr('aria-modal');
				offcanvas.removeClass('dj-offcanvas-opened');

				$(document.body).find('.dj-megamenu-offcanvas-overlay').remove();

			}
		});

		btn_close.on('keydown', function(event){
			if(event.key == 'Tab' && event.shiftKey) {
				event.preventDefault();
				last_item.focus();
			}
		});

		last_item.on('keydown', function(event){
			if(event.key == 'Tab' && !event.shiftKey) {
				event.preventDefault();
				btn_close.focus();
			}
		});

		offcanvas.on('keydown', function(e) {
			if (e.key === "Escape") {
				btn_close.click();
			}
		});

		this.initAccordion(offcanvas);
	};

	DJMegaMobile.prototype.createAccordion = function(mobile) {
		
		var btn_open = mobile.find('.dj-mobile-open-btn');

		btn_open.on('click', function(e){
			e.stopPropagation();
			e.preventDefault();
			$(this).toggleClass('active');
			mobile.find('.dj-accordion-in').slideToggle('fast');
		});
		
		$(document).on('click', function(e){
			if(!$(e.target).closest('.dj-accordion-in').length) {
				btn_open.removeClass('active');
				if(mobile.find('.dj-accordion-in').is(':visible')) mobile.find('.dj-accordion-in').slideUp('fast');
			}
		});

		this.initAccordion(mobile);
		
	};

	DJMegaMobile.prototype.switchMenu = function() {
		
		var self = this;

		window.clearTimeout(self.timer);
		self.timer = window.setTimeout(function(){
			
			for(var idx = 0; idx < self.mega.length; idx++) {
				
				if(self.mega[idx].mobile) {
					
					if(window.matchMedia("(max-width: "+self.mega[idx].trigger+"px)").matches) {
						
							$(document.body).addClass('dj-megamenu-mobile');
							$(document.body).addClass(self.mega[idx].id+'-mobile');
							// we need only one menu in DOM
							if($.contains(document, self.mega[idx].menu[0])) {
								self.mega[idx].menu.after(self.mega[idx].menuHandler);
								self.mega[idx].menu.detach();
							}
							if($.contains(document, self.mega[idx].mobileHandler[0])) {
								self.mega[idx].mobileHandler.replaceWith(self.mega[idx].mobile);
							}
							if($.contains(document, self.mega[idx].offcanvasHandler[0])) {
								self.mega[idx].offcanvasHandler.replaceWith(self.mega[idx].offcanvas);
							}
							
					} else {
						
							$(document.body).removeClass('dj-megamenu-mobile dj-offcanvas-open dj-offcanvas-anim');
							$(document.body).removeClass(self.mega[idx].id+'-mobile');
							// we need only one menu in DOM
							if($.contains(document, self.mega[idx].mobile[0])) {
								self.mega[idx].mobile.after(self.mega[idx].mobileHandler);
								self.mega[idx].mobile.detach();
							}
							if(self.mega[idx].offcanvas && $.contains(document, self.mega[idx].offcanvas[0])) {
								self.mega[idx].offcanvas.after(self.mega[idx].offcanvasHandler);
								self.mega[idx].offcanvas.detach();
							}
							if($.contains(document, self.mega[idx].menuHandler[0])) {
								self.mega[idx].menuHandler.replaceWith(self.mega[idx].menu);
							}
					}
				}
			}
			
		}, 100);
	};
})(jQuery);

var initMobile = function() {
	if (typeof jQuery == 'undefined') {
		console.log('DJ-Megamenu: jQuery missing');
	} else {
		new DJMegaMobile;
	}
}

if (document.readyState !== 'loading') {
  initMobile();
} else {
  document.addEventListener('DOMContentLoaded', function() {
    initMobile();
  });
}

window.addEventListener('load', function() {
	if (typeof jQuery == 'undefined') {
		console.log('DJ-Megamenu: jQuery missing');
	} else {
		jQuery(document).trigger('djmegamobile:pageload');
	}
});

Copyright © 2019 by b0y-101