Javscript Menu Flickers on Hover

Pdesignz
Pdesignz used Ask the Experts™
on
I have a Jquery/Javascript menu that I pulled from dynamic Drive, seems that if you mouseovwe too quickly seems to have aflickering effect. I extended the animation from the default 200 to 500 and animation is slower, but still get flickering. Currently being used on http://likemike.ususers.com

Attaching js file asfor review thanks

Any help with flickering is much appreciated.

Thanks
/*********************
//* jQuery Drop Line Menu- By Dynamic Drive: http://www.dynamicdrive.com/
//* Last updated: June 27th, 09'
//* Menu avaiable at DD CSS Library: http://www.dynamicdrive.com/style/
*********************/

var droplinemenu={

arrowimage: {classname: 'downarrowclass', src: '/images/down.gif', leftpadding: 5}, //customize down arrow image
animateduration: {over: 500, out: 500}, //duration of slide in/ out animation, in milliseconds

buildmenu:function(menuid){
	jQuery(document).ready(function($){
		var $mainmenu=$("#"+menuid+">ul")
		var $headers=$mainmenu.find("ul").parent()
		$headers.each(function(i){
			var $curobj=$(this)
			var $subul=$(this).find('ul:eq(0)')
			this._dimensions={h:$curobj.find('a:eq(0)').outerHeight()}
			this.istopheader=$curobj.parents("ul").length==1? true : false
			if (!this.istopheader)
				$subul.css({left:0, top:this._dimensions.h})
			var $innerheader=$curobj.children('a').eq(0)
			$innerheader=($innerheader.children().eq(0).is('span'))? $innerheader.children().eq(0) : $innerheader //if header contains inner SPAN, use that
			$innerheader.append(
				'<img src="'+ droplinemenu.arrowimage.src
				+'" class="' + droplinemenu.arrowimage.classname
				+ '" style="border:0; padding-left: '+droplinemenu.arrowimage.leftpadding+'px" />'
			)
			$curobj.hover(
				function(e){
					var $targetul=$(this).children("ul:eq(0)")
					if ($targetul.queue().length<=1) //if 1 or less queued animations
						if (this.istopheader)
							$targetul.css({left: $mainmenu.offset().left, top: $mainmenu.offset().top+this._dimensions.h})
						if (document.all && !window.XMLHttpRequest) //detect IE6 or less, fix issue with overflow
							$mainmenu.find('ul').css({overflow: (this.istopheader)? 'hidden' : 'visible'})
						$targetul.slideDown(droplinemenu.animateduration.over)
				},
				function(e){
					var $targetul=$(this).children("ul:eq(0)")
					$targetul.slideUp(droplinemenu.animateduration.out)
				}
			) //end hover
		}) //end $headers.each()
		$mainmenu.find("ul").css({display:'none', visibility:'visible', width:$mainmenu.width()})
	}) //end document.ready
}
}

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
The problem is your document type.

Personally when building a website I use STRCT XHTML. But I see you have used a half TRANSITIONAL tag. This tag is incorrect. This causes the browser IE to make the page work in "Quirks" mode.

You need to use a full DOCTYPE tag. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

Like that instead of your current <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

Read here for more info about DOCTYPEs > http://www.w3schools.com/tags/tag_DOCTYPE.asp

Now after I added that DOCTYPE on my end. It works perfectly on IE and no more flickering when its sliding up. It also works perfectly on FireFox. There are now new problems however. Your html element alignment is abit off. This is because of errors in the alignment of those elements.

You will need to use CSS to fix the width and height of the main menu which is broken after using this DOCTYPE. I have tested other DOCUMENT types for you too and they all end up with broken results. So your best bet if you want to fix the flickering is to change Doctype and to work on the page layout again to make it work with the DOCTYPE you selected. For your page i recommend you use the doctype I showed you.

I hope this helps you, sorry this is a harder fix than you thought it would be.
I picked up the CSS error.

It was here in your droplinebar.css

Change the first item there, you forgot to give it a width attribute. On most DOCTYPES the parent element does not adjust to child element width.

.droplinebar {
      OVERFLOW: hidden;  WIDTH: 955px;
}
PdesignzPPC Specialist

Author

Commented:
just change the width or also add the new doctype
Success in ‘20 With a Profitable Pricing Strategy

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Add the new DOCTYPE too as well as change the width please. Let me know if it works out.
Also the animation looks better on my end if
animateduration: {over: 300, out: 300}, //duration of slide in/ out animation, in milliseconds

the over and out were 300 instead of 500ms
PdesignzPPC Specialist

Author

Commented:
moved back to 200 and still flickering, let me try 300
PdesignzPPC Specialist

Author

Commented:
Made same changes and still seems to flicker
Weird... Which browser are you using?
I am using IE8, FireFox and Opera to check the website and they all show it fine. Also I am moving my mouse around over the two drop downs as fast as I can and I still notice no flickering animation..

Before I was getting a flickering on IE8 when the menu went up again but now thats fixed after the DOCTYPE change...
PdesignzPPC Specialist

Author

Commented:
using IE8, Firefox and Chrome, If I move mouse down and to the left works fine, but if I try and move diagonal and don't get the submenu in time I get a repeating flickering motion
I see what you mean.... Actually the effect looks quite hilarious.. Okay thanks for making me aware of the issue I am now going through the code to figure out why it keeps doing that weird thing.
Alright figured out the mistake. It was in the JS file. I dont know why it was even like that.

Anyway check out the attached snippet here :

/*********************
//* jQuery Drop Line Menu- By Dynamic Drive: http://www.dynamicdrive.com/
//* Last updated: June 27th, 09'
//* Menu avaiable at DD CSS Library: http://www.dynamicdrive.com/style/
*********************/

var droplinemenu={

arrowimage: {classname: 'downarrowclass', src: 'http://likemike.ususers.com/images/down.gif', leftpadding: 5}, //customize down arrow image
animateduration: {over: 500, out: 500}, //duration of slide in/ out animation, in milliseconds

buildmenu:function(menuid){
	jQuery(document).ready(function($){
		var $mainmenu=$("#"+menuid+">ul")
		var $headers=$mainmenu.find("ul").parent()
		$headers.each(function(i){
			var $curobj=$(this)
			var $subul=$(this).find('ul:eq(0)')
			this._dimensions={h:$curobj.find('a:eq(0)').outerHeight()}
			this.istopheader=$curobj.parents("ul").length==1? true : false
			if (!this.istopheader)
				$subul.css({left:0, top:this._dimensions.h})
			var $innerheader=$curobj.children('a').eq(0)
			$innerheader=($innerheader.children().eq(0).is('span'))? $innerheader.children().eq(0) : $innerheader //if header contains inner SPAN, use that
			$innerheader.append(
				'<img src="'+ droplinemenu.arrowimage.src
				+'" class="' + droplinemenu.arrowimage.classname
				+ '" style="border:0; padding-left: '+droplinemenu.arrowimage.leftpadding+'px" />'
			)
			$curobj.hover(
				function(e){
					var $targetul=$(this).children("ul:eq(0)")
					if ($targetul.queue().length==0) //previously == 1, i changed it to 0 and it works right now
					//i wonder why it was on 1 in the first place.. hmmm... but i cant seem to do that
					//diagonal thing anymore at all. and it still seems to work fine. test it out!
					{
						if (this.istopheader)
							$targetul.css({left: $mainmenu.offset().left, top: $mainmenu.offset().top+this._dimensions.h})
						if (document.all && !window.XMLHttpRequest) //detect IE6 or less, fix issue with overflow
							$mainmenu.find('ul').css({overflow: (this.istopheader)? 'hidden' : 'visible'})
						$targetul.slideDown(droplinemenu.animateduration.over)
					}
				},
				function(e){
					var $targetul=$(this).children("ul:eq(0)")
					$targetul.slideUp(droplinemenu.animateduration.out)
				}
			) //end hover
		}) //end $headers.each()
		$mainmenu.find("ul").css({display:'none', visibility:'visible', width:$mainmenu.width()})
	}) //end document.ready
}
}

Open in new window

I also changed the CSS abit on my side and changed the colors around abit to help the user know that the bottom menu is an extention from the top one when they hover over the items. So they know if they move left or right of that item the bottom menu will close.

In dropdownline.css I changed the background color of 3 of the last 4 items on that CSS file. I will attach it here. Use it if you wish but right now your page looks good the way it is!

.droplinebar UL LI A:hover {
	COLOR: #fff; TEXT-DECORATION: underline; BACKGROUND: #197895;
}
.droplinebar UL LI UL {
	Z-INDEX: 100; POSITION: absolute; WIDTH: 955px; BACKGROUND: #197895; VISIBILITY: hidden; TOP: 0px; LEFT: 0px
}
.droplinebar UL LI UL LI A {
	PADDING-BOTTOM: 6px; MARGIN: 0px; PADDING-LEFT: 6px; PADDING-RIGHT: 8px; FONT: bold 16px Arial; PADDING-TOP: 6px
}
.droplinebar UL LI UL LI A:hover {
	BACKGROUND: #2988A5; COLOR: #fff; TEXT-DECORATION: underline
}

Open in new window

PdesignzPPC Specialist

Author

Commented:
Let me see if this works, :)
PdesignzPPC Specialist

Author

Commented:
seems better, but still not able to get the the two submenu items to stay long enough to hit them, will try extending to 1000 or maybe 1500
Hey I snooped around abit more and figure out, what you want is to delay the onmouseout event right. So I looked for ways to do this. And I came up with a solution. Its to use hoverIntent(), its a plugin for jQuery (if you want to read up on it its here > http://cherne.net/brian/resources/jquery.hoverIntent.html)

I have attached the .js file which we were working on with this comment. Try it out please. I think it might be what you were hoping for. To change the sensitivty settings you can change the contents inside "var config = {   " which is near the bottom of the code. You will see there are 3 options you can set for hoverIntent , sensitivity:, interval:, and timeout:

Goodluck!
droplinemenu.js
You do not have to add in extra code onto your main page or anything like that. I already combined the jQuery plugin in the file I attached in my previous comment. Just use that file and relace your existing one (make a backup of your existing one just as a precaution) and everything should work fine!
You could change those 3 variables to how you see fit to your satisfaction, just make sure you read the documentation about what those variables do on http://cherne.net/brian/resources/jquery.hoverIntent.html before changing them around too much.
PdesignzPPC Specialist

Author

Commented:
Great Job!! Thank You

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial