I need a little help about css and top/sidebar menu

Hello friends
I hope you are all well.
I need a little help from you if you are familiar with css or javascript. :roll_eyes:
I needed a grid display component for my site, and after searching I found a suitable one and installed it. Now the problem is that after activating the module related to this component on any page, the menu at the top of my site stops working. It means that there is an interference between the grid component and the menu. If I disable the grid module, the menu works again without any problem.
Please see for yourself in the link below.

Currently, the grid module is active under articles,so nothing happens if you click on the search button or the corresponding button on the sidebar menu. This issue occurs only in mobile and tablet display mode. So reduce the browser size to see what I mean.
The question is, what should I do to solve the problem? I don’t think it should be a very complicated problem?
Also, when the grid module is active, the following error can be seen on the Google Inspect page.

mootools-core.js?d25b1e28c6a2a29d5e390c182349c46d:136 Uncaught TypeError: Cannot read properties of undefined (reading 'x') at getWidth (mootools-core.js?d25b1e28c6a2a29d5e390c182349c46d:136:134) at Object.check (script.js:137:23) at Object.initialize (script.js:58:14) at HTMLDocument.<anonymous> (script.js:442:14) at n (jquery-1.7.1.min.js:2:14784) at Object.fireWith (jquery-1.7.1.min.js:2:15553) at Function.ready (jquery-1.7.1.min.js:2:9773) at HTMLDocument.B (jquery-1.7.1.min.js:2:14348)

I would appreciate it if you could help me.

1 Like

Looking at the site, I’m not able to see the problem with the menu or search.
But I may suggest that with today’s CSS there should be no need for javascript modules to get a grid layout.
Using pure CSS would be less likely to interfere with the parts of your page that have to rely on scripts.

2 Likes

Hello
Thank you for your reply. To see the problem, you should reduce the width of your browser or view the page on a mobile or tablet. When you click on the search button or the menu, they do not open.
Unfortunately, I am not familiar with programming and it is much easier and faster for me to use ready-made modules.

I’ll move this to the JS forum as this is not a CSS issue. It looks like a conflict with your scripts (or you aren’t loading the script as I can’t find it).

It might help if you can point to where the js for the toggle menu is kept to save one of our JS gurus looking for it.

It’s too complicated for me :wink:

2 Likes

That’s a problem, and in fact has made it far from easier.

You have reams of JS to trawl through, some pretty dated code, some compressed etc. — needle in a haystack comes to mind.

Checking the official blog, mootools hasn’t been updated in 7 years. Furthermore from what I can see it creates it’s own custom methods on Javascript’s built in types. This is prone to conflicts.

Doing a bit of searching, I have found quite a few old threads reporting conflicts between Jquery and Mootools. The solution being to use Jquery.noConflict() e.g.

Maybe that is relevant.

I’m sorry to say I am with SamA74. You are in need of some modernisation of your code and would probably benefit from trimming down what you have considerably.

2 Likes

Hi,
Thank you so much for your reply and advices. I am not a programmer and these things are pretty difficult for me.
So I found out that currently the problem with my site’s script is the conflict between mootools and jQuery. And I have to use jQuery.noConflict .
But my question is, where should I put jQuery.noConflict(); exactly? In which file and what part of it?

  • in media/system/js/ folder I have two files “mootools-core.js” and “mootools-more.js”
  • also in templates/ja_wall/js/ folder i have some files including “jquery.noconflict.js” , “jquery.jbk.js”, “script.js” , “wall.js” …
  • and in templates/ja_wall/plugins/ i have “jquery-1.7.1.min.js”

here is the content of my current “jquery.noconflict.js” file:

window.$wall = jQuery.noConflict();
if(window.jbkQuery){
	window.jQuery = window.jbkQuery;
}

should I add following code at begin and end of file

jQuery.noConflict();
(function($) { 


})(jQuery);

like the example page you sent me?
or I only put jQuery.noConflict() At beging of file?

Using no conflict frees up the ‘$’ sign for other frameworks.

// This will free up $ for any other framework that might use it.
// In other words it is no longer tied to jQuery
jQuery.noConflict();

// This IIFE will wrap code providing a new $ alias for Jquery
(function($) { 
  // Inside here we have a new $ alias to jQuery
  // Here is where you want your jQuery code
  $('.myDiv')....

})(jQuery); // ← jQuery is passed in and will become a $

// Code that may use a $ sign is safe to use here

An IIFE (immediately invoked function expression) is used to create a safe container for the jQuery code.

Just to give another simple IIFE example

const a = 5

// IIFE
(function(b) { // value of 'a' is given to 'b'
  // b is contained in here and is not accessible outside of the IIFE
  console.log(b) // 5

})(a) // ← 'a' is passed in to 'b' here

console.log(a) // 5
console.log(b) // undefined

It is not something I have used, but in theory you should only need to use jQuery.noConflict() once and it should be placed in the next script to the one that loads jQuery. e.g. from the docs

<script src="other_lib.js"></script>
<script src="jquery.js"></script>
<script>
$.noConflict();
// Code that uses other library's $ can follow here.
</script>
2 Likes

Hi,
Thanks again for your help. But I feel so stupid when I can’t understand the code.
Can you fix this issue for me if I send you admin password?
This site is based on Joomla CMS actually.

Actually I disabled MooTools for now and will remove sidebar buttons.

But I still see two errors with google inspect:
script.js:361 Uncaught TypeError: window.addEvent is not a function at script.js:361:8
and when i click on error it mention to the following code:

window.addEvent('load', function(){
	if(window.menuIScroll){
		window.menuIScroll.refresh();
	}
	
	if(window.sidebarIScroll){
		window.sidebarIScroll.refresh();
	}
});

and second error:
Uncaught ReferenceError: Class is not defined at caption.js:15:16
and when i click on error it mention to the following code:

var JCaption = new Class({
	initialize: function(selector)
	{
		this.selector = selector;

		var images = $$(selector);
		images.each(function(image){ this.createCaption(image); }, this);
	},

I’ll be thankful if you have any ideas for fixing this two errors (Especially the first error)?
you can see it in site now

window.addEvent I believe is a mootools function. Which script is this in?

The reason in the past we needed functions like this was because Internet Explorer had a function called attachEvent and other browsers like firefox had addEventListener. Mootools’ addEvent function would handle the browser differences for you.

The window.addEvent code would probably be along the lines of this

function addEvent (element, type, handler){
 if (element.addEventListener){ // Mozilla
   element.addEventListener(type, handler, false);
 } else if (element.attachEvent){ // IE
   element.attachEvent('on' + type, handler);
 } else { // all else fails
   element['on' + type] = handler;
 }
}

You don’t need this sort of legacy code now, addEventListener will do, so in theory you could replace that code block with native JS.

window.addEventListener('load', function(event) {
  if(window.menuIScroll){
    window.menuIScroll.refresh();
  }
	
  if(window.sidebarIScroll){
    window.sidebarIScroll.refresh();
  }
})

Edit:

I see that line of code is from JA Wall template. So JA Wall template is dependent on Mootools. I think it would be ill advised to try and re-write JA Wall.

I also see at the top of JA wall that the copyright is 2004-2011. So the code is 12 years old?

You should not be using this program to do grid layouts for you, if that is what it does. You can use the built in grids in CSS, these weren’t available in 2011. Or alternatively you could use a popular framework like bootstrap

Edit2:

Sorry if that is a bit harsh @sashaiel, I can see you have put a lot of work in to your site.

3 Likes

It’s in script.js file (I’ll attach the content of this file at the end of my message. I think this file is the source of all my problems! )

You don’t need this sort of legacy code now, addEventListener will do, so in theory you could replace that code block with native JS.

OK . I changed the code, so it seems it fixed this part of problem. (but I also deleted following code from end of file because browser mentioned that as error again!)

//fix validate.js error
if(Browser.ie && Browser.version <= 8){
	Browser.Features.inputemail = false;
}

but the older Error came back which I think if we can fix this, evrything will be Ok in my site.
script.js:137 Uncaught TypeError: window.getWidth is not a function
and when I click on error it mention to these following codes:

	check: function(){
		var wwidth = window.getWidth();
		if(wwidth == JawallMenu.oldWidth){
			return;
		}

var JawallMenu = {
	initialize: function(){
		JawallMenu.isAndroidTable =  navigator.userAgent.toLowerCase().indexOf('android') > -1 &&  navigator.userAgent.toLowerCase().indexOf('mobile') == -1;
		JawallMenu.isTouch = 'ontouchstart' in window && !(/hp-tablet/gi).test(navigator.appVersion);
		JawallMenu.isTablet = JawallMenu.isTouch && (window.innerWidth >= 720);
		JawallMenu.enableTouch();
		JawallMenu.check();
		window.addEvent('resize', JawallMenu.check);
	},
(window.$wall || window.jQuery)(document).ready(function ($) {
	// enable menu responsive check
	if(!($.browser.msie && parseFloat($.browser.version) < 9)){
		JawallMenu.initialize();
	}

Although You can see full details in Google inspect.

following is the content of script.js

/**
 * ------------------------------------------------------------------------
 * JA Wall Template for J25 & J3x
 * ------------------------------------------------------------------------
 * Copyright (C) 2004-2011 J.O.O.M Solutions Co., Ltd. All Rights Reserved.
 * @license - Copyrighted Commercial Software
 * Author: J.O.O.M Solutions Co., Ltd
 * Websites:  http://www.joomlart.com -  http://www.joomlancers.com
 * This file may not be redistributed in whole or significant part.
 * ------------------------------------------------------------------------
 */
 
/**
 * General script for JA Wall template
 */

var TouchMask = {
	handlers: [],
	isbind: 0,
	ontouch: function(){
		var result = 1;
		TouchMask.handlers.each(function(fn){
			result = fn() && result;
		});
		
		if(result){
			document.removeEvent('touchstart', TouchMask.ontouch);
			TouchMask.isbind = 0;
		}
	},
	
	show: function(){
		if(this.isbind){
			return false;	
		}
		
		document.addEvent('touchstart', TouchMask.ontouch);
		
		this.isbind = 1;
	},
	register: function(handler){
		if(typeOf (handler) == 'function' && this.handlers.indexOf(handler) == -1){
			this.handlers.push(handler);
		}
	},
	unregister: function(handler){
		this.handlers.erase(handler);
	}
};


var JawallMenu = {
	initialize: function(){
		JawallMenu.isAndroidTable =  navigator.userAgent.toLowerCase().indexOf('android') > -1 &&  navigator.userAgent.toLowerCase().indexOf('mobile') == -1;
		JawallMenu.isTouch = 'ontouchstart' in window && !(/hp-tablet/gi).test(navigator.appVersion);
		JawallMenu.isTablet = JawallMenu.isTouch && (window.innerWidth >= 720);
		JawallMenu.enableTouch();
		JawallMenu.check();
		window.addEvent('resize', JawallMenu.check);
	},
	
	enableTouch: function(){
		if (JawallMenu.isTouch){
			var jmainnav = $('mainnav');
			
			if(!jmainnav){
				return false;
			}
			
			var	jmenu = jmainnav.getElement('.menu');

			if(!jmenu){
				return false;
			}

			var	jitems = jmenu.getElements('li.deeper'),
				onTouch = function(e){
					var i, len, noclick = !this.retrieve('noclick');
 
 					e.stopPropagation();

					// reset all
					for (i = 0, len = jitems.length; i < len; ++i) {
						jitems[i].store('noclick', 0);
					}

					if(noclick){
						var jshow = this.addClass('hover').getParents('li.parent').addClass('hover');
						jshow = jshow.append([this]);
						jitems.each(function (jitem) {
							if(!jshow.contains(jitem)){
								jitem.removeClass('hover');
							}
						});
					}
			 
					this.store('noclick', noclick);
					this.focus();
				},
				onClick = function(e){
					e.stopPropagation();

					if(this.retrieve('noclick')){
						e.preventDefault();

						jitems.removeClass('hover');
						this.addClass('hover').getParents('li.parent').addClass('hover');

						TouchMask.hidetoggle();
						TouchMask.show();
					} else {
						var href = this.getElement('a').get('href');
						if(href){
							window.location.href = href;
						}
					}
				};
			
			jitems.each(function(jitem){
				jitem.addEvent('touchstart', onTouch)
					.addEvent('click', onClick)
					.store('noclick', 0);
			});

			JawallMenu.resetmenu = function(){
				jitems.store('noclick', 0).removeClass('hover');
				return true;
			};

			TouchMask.register(JawallMenu.resetmenu);
		}
	},
	
	oldWidth: 0,
	
	check: function(){
		var wwidth = window.getWidth();
		if(wwidth == JawallMenu.oldWidth){
			return;
		}
		
		JawallMenu.oldWidth = wwidth;
		
		var jmainnav = $('mainnav');
		
		if(!jmainnav){
			return;
		}
		
		var	jmenuinner = jmainnav.getElement('.menu-inner'),
			jmenu = jmainnav.getElement('.menu');
			
		if(!jmenuinner || !jmenu){
			return;
		}
		
		//check if we have to implement scroll
		if (jmenu.offsetWidth > jmenuinner.offsetWidth) {
			jmenu.setStyle('float', 'left');
			
			if(!window.menuIScroll){
				var jprev = jmainnav.getChildren('.navprev')[0] ||  new Element('a', {
						'href': 'javascript:;',
						'class': 'navprev'
					}).inject(jmainnav).addEvent('click', function(){
						if(window.menuIScroll){
							window.menuIScroll.scrollToPage('prev');
						}
						
						if(JawallMenu.jcitem){
							JawallMenu.jcitem.fireEvent('shide');
							JawallMenu.jcitem = null;
						}
					}),
					jnext = jmainnav.getChildren('.navnext')[0] ||  new Element('a', {
						'href': 'javascript:;',
						'class': 'navnext'
					}).inject(jmainnav).addEvent('click', function(){
						if(window.menuIScroll){
							window.menuIScroll.scrollToPage('next');
						}
						
						if(JawallMenu.jcitem){
							JawallMenu.jcitem.fireEvent('shide');
							JawallMenu.jcitem = null;
						}
					}),
					checkNav = function (){
						if(window.menuIScroll){
							jprev.setStyle('display', window.menuIScroll.x >= 0 ? 'none' : 'block');
							jnext.setStyle('display', (window.menuIScroll.x <= window.menuIScroll.maxScrollX) ? 'none' : 'block');
						}
					};
				
				window.menuIScroll = new iScroll(jmenuinner, {
					snap: '.menu > li',
					hScrollbar: false,
					vScrollbar: false,
					onRefresh: checkNav,
					onScrollEnd: checkNav,
					useTransform: false,
					onScrollStart: function(){
						if(JawallMenu.jcitem){
							JawallMenu.jcitem.fireEvent('shide');
							JawallMenu.jcitem = null;
						}
					},
					overflow: ''
				});
				
				checkNav();
				
				var jactive = jmenu.getChildren('.active')[0];
				if(jactive){
					window.menuIScroll.scrollToElement(jactive);
				}
			}
			
			if (window.menuIScroll) {
				window.menuIScroll.refresh();
			}
		} else {
			if (window.menuIScroll) {
				window.menuIScroll.scrollTo(0, 0, 0);
			}
			
			jmenu.setStyle('float', '');
		}
		
		//check if the mobile layout, we change html structure
		if(wwidth < 720){
			if(JawallMenu.jcitem){
				JawallMenu.jcitem.fireEvent('shide');
				JawallMenu.jcitem = null;
			}
			
			jmenuinner.setStyle('overflow', 'hidden');
			
			jmenu.getChildren('.deeper > ul').each(function(jsub){
				var jitem = jsub.getParent(),
					sid = null;
					
				jsub.store('parent', jitem).addClass('jsub').inject(jmainnav).setStyle('position', 'absolute');
				
				if(!JawallMenu.isTouch){
					//add mouse event to show/hide sub on desktop
					jitem.addEvent('mouseenter', function(e){
						clearTimeout(sid);
						
						if(jsub.getStyle('display') != 'none'){
							return false;
						} else {
						
							if(JawallMenu.jcitem && JawallMenu.jcitem != jitem){
								JawallMenu.jcitem.fireEvent('shide');
							}
						
							jsub.setStyles({
								display: 'block',
								top: jmenuinner.getHeight()
							});
							
							jitem.addClass('over');
							
							JawallMenu.jcitem = jitem;
						}
					}).addEvent('mouseleave', function(){
						clearTimeout(sid);
						sid = setTimeout(function(){
							jitem.fireEvent('shide');
						}, 100);
					});
					
					jsub.addEvent('mouseenter', function(){
						clearTimeout(sid);
					}).addEvent('mouseleave', function(){
						clearTimeout(sid);
						sid = setTimeout(function(){
							jitem.fireEvent('shide');
						}, 100);
					});
				} else {
					//add touch event for touch device
					jitem.addEvent('touchstart', function(e){
						if(jsub.getStyle('display') == 'none'){
							e.stop();
							
							if(JawallMenu.jcitem && JawallMenu.jcitem != jitem){
								JawallMenu.jcitem.fireEvent('shide');
							}
							
							jsub.setStyles({
								display: 'block',
								top: jmenuinner.getHeight()
							});
							
							jitem.addClass('over');
							
							JawallMenu.jcitem = jitem;
							
							TouchMask.hidetoggle();
							TouchMask.show();
						}
					});
				}
				
				jitem.addEvent('shide', function(){
					clearTimeout(sid);
					jsub.setStyle('display', 'none');
					jitem.removeClass('over');
					JawallMenu.jcitem = null;
				}).fireEvent('shide');
				
			});
			
			//only init once
			if(!JawallMenu.initTouch && JawallMenu.isTouch){
				
				jmainnav.addEvent('touchstart', function(){
					if(JawallMenu.jcitem){
						this.store('touchInside', 1);
					}
				});
				
				TouchMask.hidesub = function(){
					if(jmainnav.retrieve('touchInside')){
						jmainnav.store('touchInside', 0);
						return false;
					} else {
						if(JawallMenu.jcitem){
							JawallMenu.jcitem.fireEvent('shide');
							return false;
						}
					}
					
					return true;
				};
				
				TouchMask.register(TouchMask.hidesub);
				TouchMask.hidesub();
				
				JawallMenu.initTouch = 1;
			}
			
		} else {
			
			JawallMenu.jcitem = null;
			
			jmainnav.getChildren('.jsub').each(function(jsub){
				var jitem = jsub.retrieve('parent');
				
				jitem.removeEvents('mouseenter').removeEvents('mouseleave').removeEvents('touchstart').removeEvents('shide');
				jsub.removeProperty('style').removeEvents('mouseenter').removeEvents('mouseleave').removeClass('jsub').inject(jitem);
			});
			
			jmenuinner.setStyle('overflow', '');
		}
	}
};

window.addEvent('load', function(){
	if(window.menuIScroll){
		window.menuIScroll.refresh();
	}
	
	if(window.sidebarIScroll){
		window.sidebarIScroll.refresh();
	}
});


(function($){
	var groups = {
	},
	
	handler = function (group, value) {
		// ignore user setting for page with fixed option
		if ($(document.body).hasClass ('fixed-' + group)){
			return;
		}
		
		if (value) {
			if (groups[group]['type'] == 'toggle') {
				var cvalue = $.cookie ('ja-'+group);
				if (new RegExp ('(^|\\s)' + value+'(?:\\s|$)').test(cvalue)) {
					$(document.body).removeClass (group + '-' + value);
					cvalue = cvalue.replace (new RegExp ('(^|\\s)' + value+'(?:\\s|$)', 'g'), '$1');
				} else {
					$(document.body).addClass (group + '-' + value);
					cvalue += ' ' + value;
				}
				groups[group]['val'] = cvalue;
				// update cookie
				$.cookie ('ja-'+group, cvalue, {duration: 365, path: '/'});
			} else {
				// update value & cookie
				groups[group]['val'] = value;
				$.cookie ('ja-'+group, value, {duration: 365, path: '/'});
				// remove current
				document.body.className = document.body.className.replace (new RegExp ('(^|\\s)' + group+'-[^\\s]*', 'g'), '$1');
				$(document.body).addClass (group + '-' + value);
			}
		}
		
		// Make the UI reload by trigger resize event for window
		$(window).trigger('resize');
	};
	
	$.fn.toolbar = function(options){
		var defaults = {
			group: 'basegrid',
			type: 'single',
			val: 'm'
		},
		
		opt = $.extend(defaults, options);
		
		groups[opt.group] = groups[opt.group] || {};
		$.extend(groups[opt.group], {type: opt.type, val: opt.val});
		
		if (!$(document.body).hasClass ('fixed-' + opt.group)){
			var value = $.cookie('ja-'+opt.group);
			if (value) {
				groups[opt.group]['val'] = value; // setting exists, replace the default
				// add active class
				$(document.body).addClass (groups[opt.group]['val'].replace (/(^|\s)([^\s]+)/g, '$1' + opt.group + '-$2'));
			} else if(opt.val) {
				handler (opt.group, opt.val);
			}
		}

		// bind event for toolbar
		return this.bind('click', function () { handler (opt.group, this.id.replace ('toolbar-' + opt.group + '-', '')); return false; });
	};
	
})(window.$wall || window.jQuery);


(window.$wall || window.jQuery)(document).ready(function ($) {
	// enable menu responsive check
	if(!($.browser.msie && parseFloat($.browser.version) < 9)){
		JawallMenu.initialize();
	}
	
	var bindevent = 'ontouchstart' in window && !(/hp-tablet/gi).test(navigator.appVersion) ? 'touchstart' : 'click',
		jtoggles = $('.btn-toggle'),
		jsidebar = $('#sidebar'),
		jtoggleactive = null;
		
	// toggle handle
	jtoggles.bind(bindevent, function (event) {	
		var jactive = $(this),
			jparent = jactive.parent();
			
		if (jparent.hasClass('active')) {
			jparent.removeClass ('active');
			// remove btn-toggle-active
			jtoggleactive = null
		} else {
			// remove other active
			jtoggles.parent().removeClass ('active');
			// add active for this toggle
			jparent.addClass ('active');
			// store
			jtoggleactive = jactive;		
		}
		
		if(typeOf (TouchMask.hidesub) == 'function'){
			TouchMask.hidesub();
		}
		TouchMask.show();
		
		return false;
	});
	
	
	jtoggles.parent().bind(bindevent, function(){
		if(jtoggleactive){
			$('body').data('touchInside', 1);
		}
	});

	TouchMask.hidetoggle = function(){
		if (jtoggleactive) {
			if($('body').data('touchInside')){
				$('body').data('touchInside', 0);
				return false;
			} else {
				// remove active
				jtoggleactive.parent().removeClass ('active');
				jtoggleactive = null;				
				return false;
			}
		}		
		return true;
	};
	TouchMask.register(TouchMask.hidetoggle);
	
	var rfpage = $('#josForm').hasClass('wform') && $('#k2Container').hasClass('k2AccountPage'),
		wmobile = false, //normal by default
		wmeditor = function(){
			if(!wmobile){
				var jmce = $('.mceLayout:first');
				if(jmce.width() > jmce.closest('.wcontrols').width()){
					wmobile = true;
					$('table.mceToolbar').each(function(){
						$(this).find('> tbody > tr').css('white-space', 'normal').find('td').css({
							position: '',
							float: 'left',
							display: 'inline-block'
						});
					});

					$('.toggle-editor a').trigger('click').delay(300).trigger('click');
				}
			}
		},
		sidrfp = setTimeout(wmeditor, 350);

	// tracking status of btn-toggle
	$(window).resize (function() {
		JawallMenu.isTablet = JawallMenu.isTouch && (window.innerWidth >= 720);

		if (jtoggleactive) {
			if (jtoggleactive.css('display') == 'none') {
				// remove active
				jtoggleactive.parent().removeClass ('active');
				jtoggleactive = null;
			}
		}
		
		if (jsidebar.length) {
			if(JawallMenu.isTablet){
				jsidebar.css({
					position: 'fixed',
					top: ''
				});
			}

			jsidebar
			.add(jsidebar.find('.sidebar-inner'))
			.css('height', Math.max(80,  
				(window.innerHeight || $(window).height())
				- parseInt(jsidebar.css('top'))
				- parseInt(jsidebar.css('margin-bottom'))
				- parseInt(jsidebar.css('padding-bottom'))));
				
			if(window.sidebarIScroll){
				window.sidebarIScroll.refresh();
			}
		}

		if(rfpage){
			clearTimeout(sidrfp);
			sidrfp = setTimeout(wmeditor, 350);
		}
	});
	
	// scrollbar for sidebar if exist
	if (jsidebar.length) {
		jsidebar
			.add(jsidebar.find('.sidebar-inner'))
			.css('height', Math.max(80,  
				(window.innerHeight || $(window).height())
				- parseInt(jsidebar.css('top'))
				- parseInt(jsidebar.css('margin-bottom'))
				- parseInt(jsidebar.css('padding-bottom'))));
		
		window.sidebarIScroll = new iScroll(jsidebar.find('.sidebar-inner')[0], {vScrollbar: true, scrollbarClass: 'sidebarTracker', useTransform: false});

		if(JawallMenu.isTouch){
			var jsbtoggle = jsidebar.find('.btn-toggle:first');

			$('<div id="dummy-toggle"></div>').css({
				position: 'absolute',
				top: 0,
				left: 0,
				width: jsbtoggle.width(),
				height: jsbtoggle.height(),
			}).appendTo(document.body).bind(bindevent, function(e){
				e.preventDefault();
				e.stopPropagation();
				jsbtoggle.trigger(bindevent);
			});

			var lastScroll = 0,
				scrollid = null;

			$(window).scroll(function(){
				lastScroll = $(window).scrollTop();
				$('#dummy-toggle').css('top', lastScroll);

				if(JawallMenu.isTablet){
					clearTimeout(scrollid);
					scrollid = setTimeout(function(){
						lastScroll = $(window).scrollTop();
						scrollid = setTimeout(function(){
							if(lastScroll == $(window).scrollTop()){
								jsidebar
									.css('top', lastScroll + parseFloat(jsidebar.css('top', '').css('top')))
									.css('position', 'absolute');

								$(document).one('touchmove', function(){
									jsidebar.css({position: 'fixed', top: ''});
								});
							}
						}, 100);
					}, 100);
				}
			});
		}

		if(JawallMenu.isTablet && !JawallMenu.isBindTablet){
			$(document).on('touchmove', function(){
				jsidebar.css({position: 'fixed', top: ''});
			});

			JawallMenu.isBindTablet = 1;
		}
	}
	
	// check and load typography assert files if nessesary
	window.jtypo = jQuery('.item-pagetypography .item-content');
	
	if(!window.jtypo.length){
		window.jtypo = jQuery('.typography .itemBody');
	}
	
	if(window.jtypo.length){
		var css = document.createElement('link');
		css.type = 'text/css';
		css.rel= 'stylesheet';
		css.href= JADef.tplurl + 'css/jtypo.css';
		document.getElementsByTagName('head')[0].appendChild(css);
		
		$.getScript(JADef.tplurl + 'js/jtypo.js');
	}
});

//fix validate.js error
if(Browser.ie && Browser.version <= 8){
	Browser.Features.inputemail = false;
}

I also see at the top of JA wall that the copyright is 2004-2011. So the code is 12 years old?

Yes. unfortunately it’s a very old template however they had some updates in 2019 but the worst part is I worked a lot on this template/site and I really want to use it. :confused:

You can use the built in grids in CSS, these weren’t available in 2011. Or alternatively you could use a popular framework like bootstrap

Using build in grids css or bootstrap needs programming knowledge which I don’t have, And unfortunately, due to my bad economic situation, it is not possible for me to hire a programmer at the moment…
But If I can solve this last issue with my template, I’m still Ok with using it (Although I know this may not be the right thing to do)

Sorry if that is a bit harsh @sashaiel, I can see you have put a lot of work in to your site.

It’s Ok. and I am really grateful for your helps

The unfortunate fact is, updating old scripts that were made for the browsers of 10 or more years ago requires even more programming knowledge.
Bootstrap (though personally I’m not a fan of it, being confident in my own CSS) is a very poular framework and you may find some more modern templates using that which could be utilised without getting too deep into CSS yourself.

you may find some more modern templates using that which could be utilised without getting too deep into CSS yourself.

Honestly, starting a new site from scratch is much more difficult for me than continuing the current site. Because the new site must be optimized for rtl languages and add dozens of plugins I need.
Currently, my only option is to use this template, and that’s why I was hoping to find a skilled coder who can help me with the current error. This forum is for programmers, so surely this problem can be solved with your helps

Anyway, I actually managed to solve that problem by myself!!! But I still have one more question that maybe you can help me with.
When I touch on any of the menu buttons at the top of my site, the menu page opens. (in mobile and tablet view) Now, if I touch on the surrounding environment, the menu page closes, but if I click on the button itself, the menu page does not close.
How to solve this issue?
I want to open the menu when I touch on the menu button, and close when I touch again.
At first, I thought this was a css problem, but when I asked in the css forum, they told me that it it’s a JavaScript issue and they said I need to write my own script for this (onclick event).

The difficulty is trying to track down between your theme.css and navigation.css where the rules are that trigger the dropdown to be shown.

After unminifying your navigation.css I did find this line. However editing that has no effect what so ever.

#mainnav .menu > li.deeper li.parent:hover > ul {
    display: block;
}

In theory if you swapped the :hover for a classname e.g. .show

#mainnav .menu > li.deeper li.parent.show > ul {
    display: block;
}

You could then use javascript to toggle that the .show classname on and off on a click event.

Here is an example I put together this morning. Not the best bit of code, but should give you an idea.

It’s trying to find the relevant lines of code in your css. I am also wondering, given how dated the code is, whether this is currently being handled by some javascript code — potential conflicts there.

Another point of note, is that you would want to remove the anchor links from those top menu items. Currently they are setup that if you hover they show the drop down, if you click they take you to a link

1 Like

Yes that is the rule that activates the hover effect and removing it does stop the hover on desktop and mobile.

Removing the hover and using a click menu for both desktop and mobile would be the sensible approach.

If you wanted hover for desktop and touch for mobile then you would need to isolate the code for each. Firstly hover rules should only apply to hover devices (either by the hover media queries or by detecting for touch support and adding a class to the body etc). Then secondly the click event should only be applied to touch devices (again either by detecting touch or some other method).

The main point is that hover and touch rules cannot be in force at the same time as they conflict with each other. :slight_smile:

1 Like

That’s funny @PaulOB . I tried removing that rule in chrome and the hover still worked for me.

Also if you look through post#12 script.js, JA Wall seems to be setup to handle menus e.g.

var JawallMenu = {
	initialize: function(){
...

var	jitems = jmenu.getElements('li.deeper'),
				onTouch = function(e){
...

if(noclick){
	var jshow = this.addClass('hover').getParents('li.parent').addClass('hover');
	jshow = jshow.append([this]);
	jitems.each(function (jitem) {
		if(!jshow.contains(jitem)){
			jitem.removeClass('hover');
		}
	});
}

So potentially that is something else to unpick.

Edit: Just a bit more digging, but if inspect one of the unorder-list dropdowns, you can see it has a negative margin set.

#mainnav .menu > li.deeper ul {
  ...
  left: -999em;
  ...
}

In the navigate.css it appears to be this rule doing the work, rather than display block.

#mainnav .menu > li.deeper.hover > ul,
#mainnav .menu > li.deeper:hover > ul {
    left: auto; ←
    margin-top: 45px;
    position: absolute;
}

So theoretically removing the : hover and toggling .hover should do the trick. The issue I see is dealing with JA Wall script.

1 Like

In layout mobile.css at line 335 there is this rule.

#mainnav .menu > li.deeper.hover ul, 
#mainnav .menu > li.deeper:hover ul {
    right: 0;
    left: 0;
    top: auto;
}

That looks like the .hover class may or may not be added dynamically and is probably an old ie6 fix as hover wasn’t supported on anything but anchors in the olden days).

However if I delete that rule in the Safari mobile web inspector (which looks at my actual iphone) then the menu does not work. Therefore it is safe to say that even if that .hover class is added by js on click or touch (not mouseover/out as that would be the same as hover) then the menu still won’t hide because the hover rule (a first touch) will still be active. The hover rule must not be seen by touch devices if a click menu is in action. Because when you click to add the class you are also hovering and when you click to remove the class you are hovering again so it won’t go away even if you removed the class :slight_smile:

This is an old demo to show one way of doing it.

However I would do that differently these days because the hover media query doesn’t distinguish between devices that have both touch and hover. Instead I would just detect touch with JS and then assume everything else is hover (and a touch class to html and then say:not(.touch)). If a device has touch and hover then it just gets the touch styles and js etc.

Edit: I can see that hover class is added on the mobile version but not the desktop version. Unfortunately the styles run through three different stylesheets (navigation,layout-mobile and theme).

2 Likes

I hadn’t even considered mobile.css, didn’t spot that one.

So replacing the above rule with something like this ?

#mainnav .menu > li.deeper.show > ul {
    left: auto;
    margin-top: 55px;
    position: absolute;
}

Then JS to toggle the .show class.

You would still need to remove the links from those buttons, or use an event.preventDefault()

Yes in the past, I would kind of do the reverse to that and add a .desktop class to my body tag.

Unfortunately I am not going to have time to look at this anymore today. Maybe tomorrow morning.

Edit: Let’s be honest it’s all a bit of a mess. JA Wall, which is dependent on Moo tools, only to try and override it all. Oh and CSS still using floats etc.

2 Likes

Yes that’s the idea but all the similar hover rules in the other stylesheets would need that class as well and get rid of all the hover rules.

The problem with :hover is that you can’t unset it once its been activated. You can only change the styles it uses but you can’t make it have no effect. Reversing the rule doesn’t help because then you are still enforcing something else even if you can’t see it.

That’s the reason that I prefer click only menus as they are more reliable across devices and more easily keyboard accessible.:slight_smile:

2 Likes