PDA

View Full Version : Is multithreaded programming supported in JS?


ConfusedOfLife
11-25-2002, 08:39 AM
Here's the code, I ask my question in the nex post! ( too much characters to write! ) :


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
<title>Untitled</title>
<style>
/* This class is used for the title */
.Title
{
color : white;
background-color : black;
font: 22px Tahoma;
width : 150px;
border : thin groove #3b3b3b;
cursor : hand;
}
/* This is the place that you can change
the shape of your menu items
*/
.Items
{
color : white;
background-color : #828282;
font: 18px Tahoma;
text-decoration : none;
width : 150px;
border-bottom : thin groove #3b3b3b;
border-left : thin groove #3b3b3b;
border-right : thin groove #3b3b3b;
cursor : hand;
}

</style>

</head>

<body>

<script>
GLOBAL_ARRAY = new Array();
function makeMenu( parentId, objId, Title, menuArray, Speed)
{
var mainDiv = document.createElement("div");
mainDiv.setAttribute( "id", objId);
mainDiv.onmouseout = function()
{
hideIt( "inner" + objId, Speed);
}

// Putting the menu inside the id of another tag if it's
// supported
if ( parentId == "" )
document.body.appendChild(mainDiv);
else
document.getElementById( parentId).appendChild( mainDiv);

// Creating the title;
var mainTitle = document.createElement("span");
mainTitle.className = "Title";
mainDiv.appendChild(mainTitle);
mainTitle.innerHTML = "<center>" + Title + "</center>";
// Creating the action when the mouse pointer goes on
// the title!
mainTitle.onmouseover = function()
{
showIt( "inner" + objId, Speed);
}

// Putting a break between the title and the menu items!
var br = document.createElement("br");
mainDiv.appendChild(br);

var innerDiv = document.createElement( "div");
innerDiv.setAttribute("id", "inner" + objId);
innerDiv.style.position = "absolute";
innerDiv.onmouseover = function()
{
showIt( "inner" + objId, Speed);
}

// This is a dummy number that later we be able to get
// the clientHeight of the innerDiv.
innerDiv.style.height = 10;

// Clipping our innerDiv to zero! Invisible somehow!!
innerDiv.style.clip = "rect(0px 150px 0px 0px)";
mainDiv.appendChild( innerDiv);



for (i=0; i<menuArray.length; i++)
{
var item = document.createElement("div");
item.className = "Items";
item.onmouseover = function()
{
this.style.backgroundColor = "#4c4c4c";
};
item.onmouseout = function()
{
this.style.backgroundColor = "#828282";
};
item.onclick = function()
{
// The redirection should occur in here, but
// I didn't write this part yet, I have another
// question regarding to this part that I'll
// ask later!
}

item.innerHTML = "<center>" + menuArray[i][0] + "</center>";
innerDiv.appendChild(item);
}

}
function showIt( childId, Speed)
{
clearTimeout( GLOBAL_ARRAY[childId,"hide"]);
var obj = ( document.getElementById) ? ( document.getElementById( childId)) : ( document.all.childId);
var maxHeight = obj.clientHeight;
var clipHeight = parseInt(obj.style.clip.split("rect(0px 150px ")[1].split("px 0px)")[0]);
if ( clipHeight < maxHeight )
{
obj.style.clip = "rect(0px 150px " + ( clipHeight + 2) + "px 0px)";

// Simulating a kind of f*cking associative array!
// Why doesn't really javascript support associative arrays?!

GLOBAL_ARRAY[childId,"value"] = childId;
GLOBAL_ARRAY[childId,"speed"] = Speed;
GLOBAL_ARRAY[childId,"show"] = setTimeout
("showIt(GLOBAL_ARRAY[" + childId + ",'value'], GLOBAL_ARRAY[" + childId + ",'speed'])", Speed);
}
else
// When the whole menu is opened and mouse pointer is going from an element
// to another element, in the gap between these 2 elements the onmouseover
// triggers and hideIt tries to close the menu, but since the mouse is fast
// and goes to the next item immediately ( doesn't stop on the gap ), the showIt
// gets activated again and prevents the hideIt to function, but we can
// see a flickering in the end of the menu, it's because hideIt() clips
// two pixels and showIt immediately bring those pixels back, to prevent
// this, in the end of showIt ( when the whole menu is on the screen ),
// I add 2 pixels to the end of it that hideIt hides them first and
// then goes to the real menu if mouse is really out of the menu.
obj.style.clip = "rect(0px 150px " + ( clipHeight + 2) + "px 0px)";
}
function hideIt( childId, Speed)
{
clearTimeout( GLOBAL_ARRAY[childId,"show"]);
var obj = ( document.getElementById) ? ( document.getElementById( childId)) : ( document.all.childId);
var maxHeight = obj.clientHeight;
var clipHeight = parseInt(obj.style.clip.split("rect(0px 150px ")[1].split("px 0px)")[0]);
if ( clipHeight > 0 )
{
obj.style.clip = "rect(0px 150px " + ( clipHeight - 2) + "px 0px)";
clearTimeout( GLOBAL_ARRAY[childId,"show"]);
GLOBAL_ARRAY[childId,"hide"] = setTimeout
("hideIt(GLOBAL_ARRAY[" + childId + ",'value'], GLOBAL_ARRAY[" + childId + ",'speed'])", Speed);
}

}
</script>


<table border="0">
<tr>
<td id="parent#1">
&nbsp;
</td>
<td id="parent#2">
&nbsp;
</td>
<td id="parent#3">
&nbsp;
</td>
<td id="parent#4">
&nbsp;
</td>
<td id="parent#5">
&nbsp;
</td>
<td id="parent#6">
&nbsp;
</td>
</tr>
</table>




<script>

menuArr1 =[
[ "First" , "http://www.somewhere.com"],
[ "Second" , "http://www.somewhere.com"],
[ "Third" , "http://www.somewhere.com"],
[ "Fourth" , "http://www.somewhere.com"],
[ "Fifth" , "http://www.somewhere.com"],
[ "Sixth" , "http://www.somewhere.com"]
];
menuArr2 =[
[ " 1 " , "http://www.Oopse.com"],
[ " 2 " , "http://www.Oopse.com"],
[ " 3 " , "http://www.Oopse.com"],
[ " 4 " , "http://www.Oopse.com"],
[ " 5 " , "http://www.Oopse.com"],
[ " 6 " , "http://www.Oopse.com"],
[ " 7 " , "http://www.Oopse.com"],
[ " 8 " , "http://www.Oopse.com"],
[ " 9 " , "http://www.Oopse.com"],
[ " 10 " , "http://www.Oopse.com"],
[ " 11 " , "http://www.Oopse.com"],
[ " 12 " , "http://www.Oopse.com"],
[ " 13 " , "http://www.Oopse.com"],
[ " 14 " , "http://www.Oopse.com"],
[ " 15 " , "http://www.Oopse.com"],
[ " 16 " , "http://www.Oopse.com"]
];

makeMenu("parent#1", "1stMenuId", "Menu #1", menuArr1, 15);
makeMenu("parent#2", "2ndMenuId", "Menu #2", menuArr2, 1);
makeMenu("parent#3", "3rdMenuId", "Menu #3", menuArr1, 7);
makeMenu("parent#4", "4thMenuId", "Menu #4", menuArr2, 10);
makeMenu("parent#5", "5thMenuId", "Menu #5", menuArr1, 5);
makeMenu("parent#6", "6thMenuId", "Menu #6", menuArr2, 2);
</script>


</body>
</html>

ConfusedOfLife
11-25-2002, 08:43 AM
----continue! ---
I have my fancy menu written and it works perfectly, the name of my function is "makeMenu" and
for making a menu in your page, you just have to call this function and supply some arguments,
the arguments are the id of the tag that you wana place your menu in, an id for the menu itself,
the title of the menu ( when you go on it the menu opens),a 2d array that contains the elements
names and also their links ( when the user clicks on each item he be redirected to that link), and
finally the speed that you want your menu to open/close.
You can see the function and a sample of it in the previous post.


You see that I made 6 menus in my page by just calling this function and giving it the id of the
parent tag that I wana place my menu in it and it works, the problem is that when you go on one
menu and it starts to drop down and you just do not wait till it completes and you go to the next
menu, the first one doesn't go back and it seems that it's stalled ( it's actually! ), I almost
know the answer but I just wanted to be sure, as you can see I'm just using 2 functions ( showIt &
hideIt ) for showing and hiding all the menus, but I'm using unique variables for their
setTimeouts, and I make these variables through a kind of associative array ( I just
simulated that ), like GLOBAL_ARRAY[The id of the child div ( that's made by adding "inner" to
the id of menu that the user supported ) + A comma + "show" or "hide" depending on the function
that the setTimeout is located in], I checked this syntax and it just works ( even though it looks
wierd in JS ), so, it means that when the user goes on a menu then the showIt starts and our
unique global array will hold that setTimeout, and when user leaves that menu, our global array
contains the unique value of the hideIt setTimeout.
What I'm asking now is that if multithreading programming was supported in JS, then when the user
went to another menu without waiting for the first menu to get closed, the hide function for the
first menu and the show function for the second menu should have been triggerd simultaniously, and
in a biger scope, if he passed all the menus very fast, then multiple hideIt and showIt functions
should have worked simultaniously to make the effect, but it's not working, does it mean that
it's absolutely no way to fix it? I can have another global array ( call it Buffer or something )
to track all the menus that the user pointed to them while my first menu is closing and when the menu is
properly closed I read the Buffer and just open the last or first menu that the user pointed to. But I
wanted to have a neat function to make my menu object, I don't know what to do now!
Any help on this and also the total structure of the menu is greately appericated

glenngv
11-25-2002, 11:01 AM
why do you set a delay on showing/hiding the menus?
why don't you just show/hide them at once?

IMHO, it's not user-friendly to have menus with different delays on showing/hiding them.

brothercake
11-25-2002, 05:45 PM
My own experience suggests that the easiest way out of this is, as glenngv suggested, a more global approach to menu closing. So that on each menu-trigger mouseover, you run functions which:

- iterate through all menu objects and hide them
- show the menu object you requested


btw - not strictly relevant, but show/hide is more processor intensive, and makes for a larger script, compared with dynamic element creation

ConfusedOfLife
11-25-2002, 07:34 PM
hey, I know what you mean and I did that b4, but just as a question, I wana find out if it's possible and as I said I had the same problem some month ago but I just forgot about it, and now it's back again and I wana see if it's anyway to solve this!

PS: Is multithreaded programming supported in JS? :p

ConfusedOfLife
11-26-2002, 10:54 AM
It's solved dears, and the answer is yes! JS does support multithread programming, I also copy the correct code for documentation!


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
<title>Untitled</title>
<style>
/* This class is used for the title */
.Title
{
color : white;
background-color : black;
font: 22px Tahoma;
width : 150px;
border : thin groove #3b3b3b;
cursor : hand;
}
/* This is the place that you can change
the shape of your menu items
*/
.Items
{
color : white;
background-color : #828282;
font: 18px Tahoma;
text-decoration : none;
width : 150px;
border-bottom : thin groove #3b3b3b;
border-left : thin groove #3b3b3b;
border-right : thin groove #3b3b3b;
cursor : hand;
}

</style>

</head>

<body>

<script>
GLOBAL_ARRAY = new Array();
function makeMenu( parentId, objId, Title, menuArray, Speed)
{
// This is gonna be used for the inner div that contains
// the menu elements!
childId = "inner" + objId;
GLOBAL_ARRAY[ childId] = new Array();


var mainDiv = document.createElement("div");
mainDiv.setAttribute( "id", objId);
mainDiv.onmouseout = function()
{
hideIt( "inner" + objId, Speed);
}

// Putting the menu inside the id of another tag if it's
// supported
if ( parentId == "" )
document.body.appendChild(mainDiv);
else
document.getElementById( parentId).appendChild( mainDiv);

// Creating the title;
var mainTitle = document.createElement("span");
mainTitle.className = "Title";
mainDiv.appendChild(mainTitle);
mainTitle.innerHTML = "<center>" + Title + "</center>";
// Creating the action when the mouse pointer goes on
// the title!
mainTitle.onmouseover = function()
{
showIt( "inner" + objId, Speed);
}

// Putting a break between the title and the menu items!
var br = document.createElement("br");
mainDiv.appendChild(br);

var innerDiv = document.createElement( "div");
innerDiv.setAttribute("id", "inner" + objId);
innerDiv.style.position = "absolute";
innerDiv.onmouseover = function()
{
showIt( "inner" + objId, Speed);
}

// This is a dummy number that later we be able to get
// the clientHeight of the innerDiv.
innerDiv.style.height = 10;

// Clipping our innerDiv to zero! Invisible somehow!!
innerDiv.style.clip = "rect(0px 150px 0px 0px)";
mainDiv.appendChild( innerDiv);



for (i=0; i<menuArray.length; i++)
{
var item = document.createElement("div");
item.className = "Items";
item.onmouseover = function()
{
this.style.backgroundColor = "#4c4c4c";
};
item.onmouseout = function()
{
this.style.backgroundColor = "#828282";
};
item.onclick = function()
{
// The redirection should occur in here, but
// I didn't write this part yet, I have another
// question regarding to this part that I'll
// ask later!
}
//item.setAttribute("href", ( menuArray[i][1] == "") ? ( "javascript:void(0);" ) : ( menuArray[i][1]));

item.innerHTML = "<center>" + menuArray[i][0] + "</center>";
innerDiv.appendChild(item);
}

}
function showIt( childId, Speed)
{
clearTimeout( GLOBAL_ARRAY[childId]["hide"]);
var obj = ( document.getElementById) ? ( document.getElementById( childId)) : ( document.all.childId);
var maxHeight = obj.clientHeight;
var clipHeight = parseInt(obj.style.clip.split("rect(0px 150px ")[1].split("px 0px)")[0]);
if ( clipHeight < maxHeight )
{
obj.style.clip = "rect(0px 150px " + ( clipHeight + 2) + "px 0px)";

// Simulating a kind of f*cking associative array!
// Why doesn't really javascript support associative arrays?!

GLOBAL_ARRAY[childId]["show"] = setTimeout
("showIt( '" + childId + "', " + Speed + ")", Speed);
}
else
// When the whole menu is opened and mouse pointer is going from an element
// to another element, in the gap between these 2 elements the onmouseover
// triggers and hideIt tries to close the menu, but since the mouse is fast
// and goes to the next item immediately ( doesn't stop on the gap ), the showIt
// gets activated again and prevents the hideIt to function, but we can
// see a flickering in the end of the menu, it's because hideIt() clips
// two pixels and showIt immediately bring those pixels back, to prevent
// this, in the end of showIt ( when the whole menu is on the screen ),
// I add 2 pixels to the end of it that hideIt hides them first and
// then goes to the real menu if mouse is really out of the menu.
obj.style.clip = "rect(0px 150px " + ( clipHeight + 2) + "px 0px)";
}
function hideIt( childId, Speed)
{
clearTimeout( GLOBAL_ARRAY[childId]["show"]);
var obj = ( document.getElementById) ? ( document.getElementById( childId)) : ( document.all.childId);
var maxHeight = obj.clientHeight;
var clipHeight = parseInt(obj.style.clip.split("rect(0px 150px ")[1].split("px 0px)")[0]);
if ( clipHeight > 0 )
{
obj.style.clip = "rect(0px 150px " + ( clipHeight - 2) + "px 0px)";
GLOBAL_ARRAY[childId]["hide"] = setTimeout
("hideIt( '" + childId + "', " + Speed + ")", Speed);
}

}
</script>


<table border="0">
<tr>
<td id="parent#1">
&nbsp;
</td>
<td id="parent#2">
&nbsp;
</td>
<td id="parent#3">
&nbsp;
</td>
<td id="parent#4">
&nbsp;
</td>
<td id="parent#5">
&nbsp;
</td>
<td id="parent#6">
&nbsp;
</td>
</tr>
</table>




<script>

menuArr1 =[
[ "First" , "http://www.somewhere.com"],
[ "Second" , "http://www.somewhere.com"],
[ "Third" , "http://www.somewhere.com"],
[ "Fourth" , "http://www.somewhere.com"],
[ "Fifth" , "http://www.somewhere.com"],
[ "Sixth" , "http://www.somewhere.com"]
];
menuArr2 =[
[ " 1 " , "http://www.Oopse.com"],
[ " 2 " , "http://www.Oopse.com"],
[ " 3 " , "http://www.Oopse.com"],
[ " 4 " , "http://www.Oopse.com"],
[ " 5 " , "http://www.Oopse.com"],
[ " 6 " , "http://www.Oopse.com"],
[ " 7 " , "http://www.Oopse.com"],
[ " 8 " , "http://www.Oopse.com"],
[ " 9 " , "http://www.Oopse.com"],
[ " 10 " , "http://www.Oopse.com"],
[ " 11 " , "http://www.Oopse.com"],
[ " 12 " , "http://www.Oopse.com"],
[ " 13 " , "http://www.Oopse.com"],
[ " 14 " , "http://www.Oopse.com"],
[ " 15 " , "http://www.Oopse.com"],
[ " 16 " , "http://www.Oopse.com"]
];

makeMenu("parent#1", "1stMenuId", "Menu #1", menuArr1, 15);
makeMenu("parent#2", "2ndMenuId", "Menu #2", menuArr2, 1);
makeMenu("parent#3", "3rdMenuId", "Menu #3", menuArr1, 7);
makeMenu("parent#4", "4thMenuId", "Menu #4", menuArr2, 10);
makeMenu("parent#5", "5thMenuId", "Menu #5", menuArr1, 5);
makeMenu("parent#6", "6thMenuId", "Menu #6", menuArr2, 2);
</script>





</body>
</html>