473,725 Members | 2,281 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

passing values in a setTimeout function


can anyone tell me why I cannot pass values in a setTimeout function
whenever I use this function it says "menu is undefined" after th
alert.

function imgOff(menu, num) {
if (document.image s) {
document.images["mt" +menu].src = eval("mt" +menu+ ".src")
}
alert("imgOff_h idemenu");
hideMenu=setTim eout('Hide(menu ,num)',500);
}

if there is no way to use setTimeout this way is there any othe
alternitive to setTimeout

----
domece

Jul 20 '05 #1
3 14942
On Thu, 19 Feb 2004 12:33:49 -0600, domeceo
<do************ @mail.forum4des igners.com> wrote:
can anyone tell me why I cannot pass values in a setTimeout function.
whenever I use this function it says "menu is undefined" after the
alert.
[snip]

That's because when the timer expires, the variable menu is out of scope,
so indeed, menu *is* undefined.

I recently ran into this problem, and the solution is non-trivial.
However, you might be in luck.

Someone else in this group, Richard Cornford, created a nice little script
that calls a function at certain intervals, but I don't know how
applicable it will be to your problem (I don't know if it supports
arguments to that function). The solution I was working on was never
finished, and would probably need a complete re-write any way. He would
probably be in the best position to help you.

I'll get to work on it anyway (it's a useful function), in case he cannot
help you. Just don't hold your breath: non-trivial = long time.
if there is no way to use setTimeout this way is there any other
alternitive to setTimeout?


No, I'm afraid not.

Mike

--
Michael Winter
M.******@blueyo nder.co.invalid (replace ".invalid" with ".uk" to reply)
Jul 20 '05 #2
"Michael Winter" <M.******@bluey onder.co.invali d> wrote in message
news:op******** ******@news-text.blueyonder .co.uk...
<snip>
Someone else in this group, Richard Cornford, created a nice
little script that calls a function at certain intervals,
but I don't know how applicable it will be to your problem
(I don't know if it supports arguments to that function).
It probably would not be appropriate as it is designed for animation (or
shedding over a short period), which is not that task here. It was not
designed to execute functions that need arguments but the functions it
executes can be inner functions (forming closures).
The solution I was working on was never finished, and would
probably need a complete re-write any way. He would probably
be in the best position to help you.

<snip>

There is nothing like encouraging me to write a long post on a
relatively complex subject when I am supposed to be working on the FAQ
;-) I will but in return I will pass back to you the responsibility for
jumping on the OP's - eval - abuse and explaining the value of block
indentation in source code (and especially posted code).

Given the OP's starting point of:-

|function imgOff(menu, num){
| if(document.ima ges){
| document.images["mt"+menu].src = eval("mt" +menu+ ".src");
| }
| alert("imgOff_h idemenu");
| hideMenu=setTim eout('Hide(menu ,num)',500);
|}

- the possible solution might be fairly simple depending on the type
of - num -. If it is a number (or a string representation of a number)
then it might just be a matter of building the string argument to
setTimeout to include the values of - num - as a number literal and -
menu - as a (quoted) string literal:-

hideMenu=setTim eout('Hide((\"' +menu+'\", '+num+');'),500 );

String concatenation is not necessarily implemented to be that fast and
the more such operations, and the more often they are performed the less
efficient the result. An alternative approach is to put the parts of the
string that is to be built into an Array in a suitable containing scope
(often, but not necessarily, global), assigning the variable parts of
the string to be constructed to "placeholde r" elements in the Array and
then calling the Array.prototype .join method (with an empty string
argument) to output the constructed string:-

var hideParts = [ //define Array in a containing (global?) scope.
'Hide(\"',
'', // index 1, string literal
'\", ',
'', // index 3, number
');'
];

- then in the function:-

hideParts[1] = menu;
hideParts[3] = num;

hideMenu=setTim eout((hideParts .join('')),500) ;

But in the case of this operation it would probably not worth the effort
unless the - imgOff - function was expected to be executed excessively.
It is a technique that is more suited to more complex string
construction.

Another simple approach to passing variables to setTimeout (that can
work with any type of value) is to assign the required values to global
variables and place the names of those variables in the setTimeout
string argument:-

var globalMenu;
var globalNum;

function imgOff(menu, num){
if(document.ima ges){
document.images["mt"+menu].src = this["mt"+menu].src;
}
globalMenu = menu;
globalNum = num;
hideMenu=setTim eout('Hide(glob alMenu, globalNum)',500 );
}

Obviously that approach has to be handled with extreme caution because
there is only one set of global variables so there will be concurrency
issues if more than one setTimeout is initiated with the same string
argument within their timeout period.

In addition to accepting strings as its first argument, setTimeout will
accept a function reference as its first argument (at least on the more
modern browsers). Some of those setTimeout implementations will
additionally accept extra arguments (beyond the milliseconds value in
the second argument) when the first argument is a function reference.
Those additional arguments can be used to pass parameters in the call to
setTimeout:-

hideMenu=setTim eout(Hide, 500, menu, num);

Unfortunately this is the worst supported version of setTimeout. So much
so that it is just unsuitable for anything but Intranet use.

However, the version of setTimeout that accepts function references as
its first argument (but without the 3rd+ arguments) is relatively well
supported these days and may work on compact profile (ECMA 327)
implementations that take advantage of the option not to implement the -
eval - function (which is internally required to process string
arguments). It is also more efficient than the string argument only
version of setTimeout because it can execute the function without having
to interpret a string as source code. Finally the function reference
version of setTimeout can be exploited, along with javascript's ability
to form closures, to provide another means of passing arguments with
setTimeout.

There is no point trying to explain this without saying something about
closures, which will need some background: When a function is called the
implementation enters something called an "execution context"
(implementation details are not specified) and that execution context is
provided with an internal property known as the "variable" object (by
ECMA 262). Each call to a function creates a new execution context and
each execution context has its own variable object. The variable object
is used to store the values of the function's formal parameters the
function's inner function declarations and the function's local
variables, all as named properties.

When the code within a function body attempts to resolve an identifier
(or the leftmost identifier in a property accessor) the first place it
looks for a value with the corresponding name is on the variable object
in its execution context, and there it would find the function local
variables, inner function declarations and the function's formal
parameters (if not found the implementation may (subject to the
following notes) then set off down the scope chain looking for
properties with that name).

One of the features of javascript is that it allows inner functions;
functions that are declared within other function or function
expressions that occur within the code of a function body. Although ECMA
262 allows function object to be shared whenever it would not be
possible to distinguish between two function objects, experimentation
suggests that no current implementation have take advantage of this
possibility and as a result all inner function are created as distinct
function objects, either during the second stage of the initialisation
of the variable object when inner function declarations are resolved, or
inline as function expressions are evaluated. So inner function objects
can be considered to exist within the execution context and separate
executions of an outer function would create different function objects
for its inner functions. (But even if sharing were implemented any
shared functions would have to behave as if they were distinct to the
execution context. Which probably explains why this has apparently never
been implemented.)

Inner functions are allowed direct access to the parameters, local
variables and declared inner functions of their outer function.
Identifier resolution starts with the variable object in their own
execution context but if the identifier is not resolved at that point
the variable object in the execution context in which they were created
is examined prior to resolution against the scope chain. Inner functions
may also be indefinitely nested so all of the variable objects in
containing execution contexts will be examined prior to scope chain
resolution.

(Note that within the execution context of inner functions, where the
outer function is executed as the method of an object and the - this -
keyword would represent a reference to that object, the - this - keyword
always refers to the *global* object. That is, inner functions do not
inherit the association with an object that may apply to the execution
of their outer function.)

At the end of the execution of a function the execution context and its
variable object would normally become available for garbage collection,
freeing any references to inner function objects and making them also
available for garbage collection.

However, function objects, including those created as inner functions,
are just objects and references to those functions can be assigned as
properties of other objects (either directly or returned from a function
call and assigned to an object property or local variable). If this is
done it remains possible to call the inner function after the end of the
execution of its outer function call. That inner function is still
allowed to resolve identifiers as properties of the variable object from
the execution context in which it was created. So the assignment of the
inner function object to a property/variable outside the execution
context in which it was created preserves, at minimum, the variable
object from that execution context (by holding a reference to it,
preventing the garbage collection of it). That preserved variable object
acts as a sort of "private" repository, retaining its initial values and
only exposing them to access/modification by code within function
objects created in the execution context for which the variable objects
was created. It is the relationship between the preserved variable
object of the execution context of outer function and references to
inner functions held in properties of objects outside of that execution
context that is a closure.

So, how to take advantage of that to pass arguments to setTimeout? The
possibilities are endless but in the case of the OP's original function
a simple inner function expression will do:-

function imgOff(menu, num){
if(document.ima ges){
document.images["mt"+menu].src = this["mt"+menu].src;
}
hideMenu=setTim eout((function( ){Hide(menu, num);}), 500);
}

In this case the function object that represents the inner function is
created when the function expression is evaluated. The function
expression evaluates as a reference to that function object and it is
that reference that is passed to the setTimeout function as its first
argument. setTimeout holds on to the reference to that function object
until it is time to execute it. When the function gets executed it still
has access to the variable object in the execution context in which it
was created; the execution of - imgOff - that initially made the call to
setTimout. That variable object holds named properties corresponding
with the formal parameters - munu - and - num -, so when the inner
function uses those identifiers to pass arguments to - Hide - it is the
values that were passed to - imgOff - when it was called that are passed
on to - Hide -.

Once the inner function has been executed by setTimeout there will no
longer be any reference to it and so it becomes available for garbage
collection, freeing its reference to the variable object form the
execution context in which it was created and allowing that object to
also be garbage collected.

If the - imgOff - function was big and had a lot of parameters and local
variables then the closure formed would be relatively large and might
represent an unreasonable burden on the system. An alternative approach
to using a closure to pass parameter to setTimeout would be to create a
smaller (and potentially more general) function specifically for the
task:-

function callWithSetTime out(funcRef, a, b, c, d, e, f, g){
/* Return a reference to the inner function created with
the function expression:
*/
return (function(){
/* Call the function passed by reference as the first
argument to the outer function and pass all of the
7 remaining parameters to it as its arguments:
*/
funcRef(a, b, c, d, e, f, g);
});
}

function imgOff(menu, num){
if(document.ima ges){
document.images["mt"+menu].src = this["mt"+menu].src;
}
hideMenu=setTim eout(callWithSe tTimeout(Hide,m enu, num), 500);
}

Now the - imgOff - function calls the - callWithSetTime out - function,
passing a reference to - Hide - as the first argument and - menu - and -
num - as the second ant third arguments. Then - callWithSetTime out -
returns a reference to its inner function (created with an anonymous
function expression) and it is that function reference that is passed on
as the first argument to setTimeout.

When the inner function of - callWithSetTime out - is called it executes
the - Hide - function, which is referred to by its - funcRef -
parameter, and passes all of its other parameters to - Hide - as its
arguments. It shouldn't matter that only - a - and - b - have had values
assigned as javascript functions do not care how many arguments are
passed when they are called or whether those arguments are undefined.
However, if - Hide - acts directly on its - arguments - property then
this implementation of - callWithSetTime out - would not be appropriate.

The advantage of this type of approach is that it is more general and
could be directly employed by other functions, either with or without
setTimeout calls.

Using setTimeout with a function reference as its first argument works
on modern browsers but IE 4 and Opera 5, for example, only support
string arguments. Using closures to allow function references to be used
where supported and transparently fall-back to string arguments was the
subject of one of the branches in the thread: "closures, what are they
good for?" from 2003-04-22:-

<URL:
http://groups.google.com/groups?thre...8300dec7%40new
s.demon.co.uk >
(will wrap)

Richard.
Jul 20 '05 #3
On Thu, 19 Feb 2004 12:33:49 -0600, domeceo
<do************ @mail.forum4des igners.com> wrote:

can anyone tell me why I cannot pass values in a setTimeout function.
whenever I use this function it says "menu is undefined" after the
alert.

function imgOff(menu, num) {
if (document.image s) {
document.images["mt" +menu].src = eval("mt" +menu+ ".src")
There is often very little need to use the eval function. In most cases,
there is an alternative that is, at least, much faster. In this instance,
the alternative is a little obscure, but still preferred:

document.images[ 'mt' + menu ].src = this[ 'mt' + menu ].src;

In this instance, the this operator refers to the global object. The
brackets then allow the string-based construction of a property in that
context. That would be the global variable, mt<menu>, and its property,
src.

Is the general policy of this group to discourage the use of eval as it
tends to be used as a catch-all fudge for users that don't understand the
language sufficiently.
}
alert("imgOff_h idemenu");
hideMenu=setTim eout('Hide(menu ,num)',500);
}


It is advisable that you properly indent source code. The general
consensus is between 2 and 6 spaces. Tabs are not recommended as they
appear differently on different computers (you might set tabs stops to 4,
others might leave them at 8). They defeat the goal of readability through
consistency. Furthermore, when displayed at an level greater than 6
spaces, readability is actually adversely affected. Remember that the more
readable your posts are, the easier it will be for readers to help you.

The biggest obstacle you will face in presenting well laid-out code to
this group is the service you are using to send posts. Forum4Designers
(F4D) provide a poor service, and present material in a way that generally
isn't suitable for the medium (there are other reasons mentioned in other
posts to F4D users). Google Groups are a better service, but nothing can
replace your ISP's Usenet service (if available) and a good news reader.

Mike

--
Michael Winter
M.******@blueyo nder.co.invalid (replace ".invalid" with ".uk" to reply)
Jul 20 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
14823
by: Raphael Bauduin | last post by:
Hi, I'm working with mozilla, building a little XUL app. I have a datasource, and want to display a message once it is loaded (datasource.loaded is true). So, I thought to use timouts, but as the code to execute is passed as a string, I cannot pass local variable to this code. Anyone has a suggestion?
2
5059
by: RootShell | last post by:
Hello First of all i know that PHP is a server side, and JavaScript is a Client side programming language, but i need to know if there is any way i can add the variable "countDownInterval" from this particular FULL code into a MySQL field. Here's the drill: I have a timer on a PHP webpage, and i want to prevent the user from doing a
4
8409
by: Ken | last post by:
Hello I am trying to change the color of a font in a text box. I have been reading about and trying various examples found it this group, but still can't get it right. Here is where I am now: <script language="JavaScript">
12
5554
by: Andrew Poulos | last post by:
With the following code I can't understand why this.num keeps incrementing each time I create a new instance of Foo. For each instance I'm expecting this.num to alert as 1 but keeps incrementing. Foo = function(type) { this.num = 0; this.type = type this.trigger(); } Foo.prototype.trigger = function() {
4
5234
by: E | last post by:
I am having trouble with setTimeout working on a second call to the setTimeout function from a second page which is an html page. Here is the scenario. I have a web page and onload it calls a javascript function which calls setTimeout and will process a second javascript function "Warn" just before the session expires. The Warn function displays an html page with a button. A second timer is started to cause the html page to close...
6
7312
by: rynato | last post by:
I am embarrassed that I cannot figure this out, as it seems fairly simple. I found a JS function I'd like to use, which animates a layer so that it moves across the screen. The problem is the function, as found, simply names the DIV directly. I want to be able to use the function in the HTML to pass the ID of the DIV which gets moved. Sounds fairly straight-forward, right? Well it doesn't work and I have spent HOURS on this. Yes, I am...
15
3795
by: nikki_herring | last post by:
I am using setTimeout( ) to continuously call a function that randomly rotates/displays 2 images on a page. The part I need help with is the second image should rotate 3 seconds after the first image rotates. I cannot figure out how to accomplish the 3 second delay. My code is pasted below: function randPic(){ randPic1(); randPic2();
7
2415
by: Martin | last post by:
Can I have two setTimeouts running at the same time - with two different intervals? I want to start one timer and, before it times out, start another one I've tried this and they seems to interfer with one another.
1
17643
by: pingalkar | last post by:
Hi, In my application, I call one popup winodow by using this link.. <a href="#" onClick="return showWindow('1','XYZ');"> <img src="images/magnifier.gif" ALT="Chemicals" width=18 height=20 border=0> </a> In this showWindow function.... var newWindow = '';
0
8752
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9257
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9179
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9116
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8099
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6702
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4519
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3228
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2637
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.