oPg Gaming Forum
May 25, 2012, 10:35:13 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
Make payments with PayPal - it's fast, free and secure!
News: Stay tuned to opggaming.com for new features, modifications, and improvements.
 
   Home   opggaming Help Arcade Search Calendar stats SourceBans Login Register  


hd-gaming
Pages: [1]   Go Down
  Print  
Author Topic: JavaScript setTimeout  (Read 697 times)
0 Members and 1 Guest are viewing this topic.
Jedakiah
Hero Member
*****
Posts: 4632



WWW
« on: August 09, 2007, 12:07:42 PM »

Hey folks.  I'm trying to write a very simple script for my css menu.  I want the menu to delay a second or two onmouseout before running hidemenu(parameterRequired);. 

Here is a simple script I have that I just love:
Code:
<script type="text/javascript">
function showmenu(elmnt)
{
document.getElementById(elmnt).style.display="block"
}
function hidemenu(elmnt)
{
document.getElementById(elmnt).style.display="none"
}
</script>

Here is my HTML in a nutshell:
Code:
<ul id="primaryNav">
  <li onmouseover="showmenu('dropDown');" onmouseout="hidemenu('dropDown');">Text
      <div id="dropDown">Drop down text</div>
  </li>
</ul>

How would I go about delaying the onmouseout function?  I have used setTimeout, but because I know next to nothing about JS I cannot get it to work. 
Logged

mikehale
Guest
« Reply #1 on: August 10, 2007, 01:17:00 AM »

setTimeout(hidemenu('dropDown'), 500);

setTimeout([function],[delay in milliseconds]);

and if you want to do multiple commands, do something like this

setTimeout(function(){/* list of commands here */}, 500);

also, if might not be working because you don't have semi colons at the end of your lines in your hide and show scripts. should be this

Code:
<script type="text/javascript">
function showmenu(elmnt)
{
document.getElementById(elmnt).style.display="block";
}
function hidemenu(elmnt)
{
document.getElementById(elmnt).style.display="none";
}
</script>

Logged
Jedakiah
Hero Member
*****
Posts: 4632



WWW
« Reply #2 on: August 10, 2007, 10:11:57 AM »

Thank you Crackie.  I usually end a line of a code, but since it was a simple one line per function I didn't need to.  I did anyways just in case. 

This new code works:
Code:
<head>
<script type="text/javascript">
var to
function showmenu(elmnt)
{
clearTimeout(to);
document.getElementById(elmnt).style.display="block";
}
function testy()
{
to=setTimeout('hidemenu("dropDown")',1000);
}
function hidemenu(elmnt)
{
document.getElementById(elmnt).style.display="none";
}
</script>
</head>
<body>
<ul id="primaryNav">
  <li onmouseover="showmenu('dropDown');" onmouseout="testy();">
<a href="#">Menu 1</a>
<div id="dropDown"><a href="index.html">item 1</a><a href="#">item 2</a></div>
  </li>
</ul>
</body>

I had to rewrite the code and define the setTimeout call as a defined object sorta thingy, so that I could clear it if a person put their mouse back over the dropdown.  Especially because the DOM considered mousing over the text a separate object at times and it would tell the menu to clear in one second.  Also I found out that the element:
Quote
setTimeout('hidemenu("dropDown")',1000)
has to be encased in quotes not 'dropDown'.  Because it requires quotes I cannot call it from inside the onmouseover attribute of html. 

And now for the final touch.  I don't want to define a function for each menu.  Especially since the site I'm working on will have 9 menus.  Instead I would like to pass parameters on. 

Here is a rough draft of what I would like to happen in invalid JS:

Code:
<li onmouseover="showmenu('dropDown');" onmouseout="hidemenudelay('parameter1');">

<script type="text/javascript">
function hidemenudelay(parameter1)
{
to=setTimeout('hidemenu("parameter1")',1000);
}
function hidemenu(elmnt)
{
document.getElementById(elmnt).style.display="none";
}
</script>

Could someone help me get that to work?  I kind of understand why the above code doesn't work, but I have no idea how to fix it.  If you see anyway I can optimize my code or something I would also like to hear that.  I am a complete noob at JS. 
« Last Edit: August 10, 2007, 10:13:48 AM by Jedakiah » Logged

mikehale
Guest
« Reply #3 on: August 10, 2007, 01:13:04 PM »

Code:
<script type="text/javascript">
function hidemenudelay(parameter1)
{
to=setTimeout('hidemenu(' + parameter1 + ')',1000);
}
function hidemenu(elmnt)
{
document.getElementById(elmnt).style.display="none";
}
</script>

that will work. or you could do this.

Code:
<script type="text/javascript">
function hidemenudelay(parameter1)
{
to=setTimeout(function(){hidemenu(parameter1)},1000);
}
function hidemenu(elmnt)
{
document.getElementById(elmnt).style.display="none";
}
</script>
Logged
Jedakiah
Hero Member
*****
Posts: 4632



WWW
« Reply #4 on: August 10, 2007, 02:54:34 PM »

Thank you Crackie so VERRRY much.  The first thing didn't work, I think that ' + parameter + ' is for printing variables in JS.  I'm probably wrong though. 

Here is the final script for anyone who cares.  I was trying to create a simple show hide script that I could easily define it's exact position with css.  I'm used to pure css menus, but I finally decided to add a little JS in for old broswer compatibility.  Here is what I did with Crackie's help:
Code: (html)
<head>
<link href="menu.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="menu.js"></script>
<title>Menu test</title>
</head>
<body>
<ul id="primaryNav">
<li onmouseover="showItem('dropDown');" onmouseout="hideItem('dropDown');">
<a href="#">Menu 1</a>
<div id="dropDown"><a href="#">item 1</a><a href="#">item 2</a></div>
</li>
</ul>
</body>
</html>
Code: (CSS)
ul#primaryNav li {
position: relative;
}
/* DROP DOWN */
ul#primaryNav div.dropDown {
display: none;
position: absolute;
top: 14px;
left: 0px;
}
Code: (JavaScript)
var toDelay
function showItem(elmnt)
{
clearTimeout(toDelay);
document.getElementById(elmnt).style.display="block";
}
function hideItem(elmnt)
{
toDelay=setTimeout(function(){document.getElementById(elmnt).style.display="none";},1000);
}
Logged

Jedakiah
Hero Member
*****
Posts: 4632



WWW
« Reply #5 on: August 10, 2007, 02:58:45 PM »

See it in action
Logged

mikehale
Guest
« Reply #6 on: August 10, 2007, 05:49:03 PM »

not sure why the + param + thing didn't work. as far as i remember that's how it's done if you do it that way, but yeah, for that very reason probably is why i choose the anonymous function approach
Logged
b.ho
Guest
« Reply #7 on: August 10, 2007, 08:02:42 PM »

nerds....are tasty!

Logged
The Grandfather
Hi Halloweenie!!!!!!
Premier Admin
Hero Member
*****
Posts: 3766


Man who scratch ass should not bite fingernails.


WWW
« Reply #8 on: August 11, 2007, 01:11:45 AM »



Thats gay.
Logged


[The OPG World]
Man who run in front of car get tired. 
Quote from: Labyrinthine link=topic=3818.msg46378#msg46378
Oh f*** you.
ppstain :  man logical how could you NOT kill me!
Jedakiah
Hero Member
*****
Posts: 4632



WWW
« Reply #9 on: August 13, 2007, 02:43:12 PM »

I found a bug I need to fix.  When I run multiple menus on this script it will occasionally display two menus at the same time until the mouse out event is called.  Here is why. 

I have the elements set up like this:
Quote
<li onmouseover="showItem('menu1');" onmouseout="hideItem('menu1');">
      <a href="#">Menu 1[/url]
      <div id="dropDown"><a href="#">item 1[/url]<a href="#">item 2[/url]</div>
   </li>
        <li onmouseover="showItem('menu2');" onmouseout="hideItem('menu2');">
      <a href="#">Menu 2[/url]
      <div id="dropDown"><a href="#">item 1[/url]<a href="#">item 2[/url]</div>
   </li>
When a users mouses out of Menu 1 it runs this function
Quote
function hideItem(elmnt)
{
   toDelay=setTimeout(function(){document.getElementById(elmnt).style.display="none";},500);
}
If a user quickly mouses over Menu 2 it runs this function:
Quote
function showItem(elmnt)
{
   clearTimeout(toDelay);
   document.getElementById(elmnt).style.display="block";
}
This will stop the hide function that we called earlier, so the menu will stay open until you call the mouse out function again. 

As a simple fix I could put this in my html: onmouseover="showItem('menu1'); hideItem('menu2');"

But what I would like to do is fix the script.  Could I make the variable "toDelay" named after the parameter?  For instance:
Quote
function showHide(elmnt)
{
    var to+ elmnt +;

    clearTimeout(to+ elmnt +);

    document.getElementById(elmnt).style.display="block";

    elmnt.mouseout= function () {
        to+ elmnt +=setTimeout(function(){document.getElementById(elmnt).style.display="none";},500);
    };
}
« Last Edit: August 13, 2007, 02:44:59 PM by Jedakiah » Logged

mikehale
Guest
« Reply #10 on: August 13, 2007, 08:48:30 PM »

it's easy when you understand scope in javascript (which isn't that easy, lol). this will work. you could also easily modify this script to make a recursive menu system. right now this makes the assumption that the sub menu that you want to show is the first div tag in the list item.

Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
ul#primaryNav li {
position: relative;
}
ul#primaryNav li a {
background-color: #EEEEEE;
height: 26px;
width: auto;
padding: 1px 5px 1px 5px;
border: 1px solid #D6D6D6;
display: block;
line-height: 26px;
text-decoration: none;
}
ul#primaryNav li a:hover {
background-color: White;
}
/* DROP DOWN */
ul#primaryNav li div#dropDown {
width: 300px;
display: none;
position: absolute;
top: 29px;
left: 0px;
}
div#dropDown a:link, div#dropDown a:visited {
width: 100%;
display: block;
}
</style>
<script type="text/javascript">
function showItem(parent) {
// get a reference to the submenu
var submenu = parent.getElementsByTagName('div')[0];
var timeout;

if (submenu != null) {
// show the submenu
submenu.style.display = 'block';
}

parent.onmouseout = function() {
timeout = setTimeout(function(){
submenu.style.display = 'none';
}, 500);
}

parent.onmouseover= function() {
// prevent menu from hiding
clearTimeout(timeout);
showItem(parent);
}
}
</script>
</head>
<body>
<ul id="primaryNav">
  <li onmouseover="showItem(this);"> <a href="#">Menu 1</a>
    <div id="menu1" style="display:none;"><a href="#">item 1</a><a href="#">item 2</a></div>
  </li>
  <li onmouseover="showItem(this);"> <a href="#">Menu 2</a>
    <div id="menu2" style="display:none;"><a href="#">item 1</a><a href="#">item 2</a></div>
  </li>
</ul>
</body>
</html>
Logged
Jedakiah
Hero Member
*****
Posts: 4632



WWW
« Reply #11 on: August 14, 2007, 09:02:15 AM »

Crackie, your awesome. Maybe even more awesome than Deka. 

Quick question, what does this part of the script do?  I assume it will not execute the script if there is no div, saving an error message? 
Quote
if (submenu != null) {
      // show the submenu
      submenu.style.display = 'block';
   }

Also the script calls itself again, I don't fully get that
Code:
parent.onmouseover= function() {
// prevent menu from hiding
clearTimeout(timeout);
showItem(parent);
}

Since the script needs to be called onmouseover anyway, couldn't I just do delete the onmouseover function once I move the clearTimeout up:
Code:
function showItem(parent) {
// get a reference to the submenu
var submenu = parent.getElementsByTagName('div')[0];
var timeout;

clearTimeout(timeout);

if (submenu != null) {
// show the submenu
submenu.style.display = 'block';
}

parent.onmouseout = function() {
timeout = setTimeout(function(){
submenu.style.display = 'none';
}, 500);
}
}
Logged

mikehale
Guest
« Reply #12 on: August 14, 2007, 09:32:18 AM »

the first part makes sure that a sub menu was found.

the second part doesn't call itself again, it changes the onmouseover event of the li tag (think of replacing the onmouseover="showItem(this);" with onmouseover="clearTimeout(timeout);showItem(this);".

as for the third part, yes that will work.

Logged
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.12 | SMF © 2006-2009, Simple Machines LLC | Sitemap Valid XHTML 1.0! Valid CSS!


Google visited last this page May 22, 2012, 09:18:55 AM