View Full Version : using one function on several items
immedicable
04-05-2004, 02:03 PM
how would i consolidate the following into a single function, and how would i call that out?
and is there a newb forum i should know about? this was all i could find.
thank you.
<html>
<head>
<script language="javascript">
function fadein1() {
layer1.filters(0).Apply();
layer1.style.visibility = "visible";
layer1.filters(0).Play();
}
function fadein2() {
layer2.filters(0).Apply();
layer2.style.visibility = "visible";
layer2.filters(0).Play();
}
function fadein3() {
layer3.filters(0).Apply();
layer3.style.visibility = "visible";
layer3.filters(0).Play();
}
function fadein4() {
layer4.filters(0).Apply();
layer4.style.visibility = "visible";
layer4.filters(0).Play();
}
function fadein5() {
layer5.filters(0).Apply();
layer5.style.visibility = "visible";
layer5.filters(0).Play();
}
function fadein6() {
layer6.filters(0).Apply();
layer6.style.visibility = "visible";
layer6.filters(0).Play();
}
function fadein7() {
layer7.filters(0).Apply();
layer7.style.visibility = "visible";
layer7.filters(0).Play();
}
function fadein8() {
layer8.filters(0).Apply();
layer8.style.visibility = "visible";
layer8.filters(0).Play();
}
</script>
<script language="javascript">
function fadeout1() {
layer1.filters(0).Apply();
layer1.style.visibility = "hidden";
layer1.filters(0).Play();
}
function fadeout2() {
layer2.filters(0).Apply();
layer2.style.visibility = "hidden";
layer2.filters(0).Play();
}
function fadeout3() {
layer3.filters(0).Apply();
layer3.style.visibility = "hidden";
layer3.filters(0).Play();
}
function fadeout4() {
layer4.filters(0).Apply();
layer4.style.visibility = "hidden";
layer4.filters(0).Play();
}
function fadeout5() {
layer5.filters(0).Apply();
layer5.style.visibility = "hidden";
layer5.filters(0).Play();
}
function fadeout6() {
layer6.filters(0).Apply();
layer6.style.visibility = "hidden";
layer6.filters(0).Play();
}
function fadeout7() {
layer7.filters(0).Apply();
layer7.style.visibility = "hidden";
layer7.filters(0).Play();
}
function fadeout8() {
layer8.filters(0).Apply();
layer8.style.visibility = "hidden";
layer8.filters(0).Play();
}
</script>
</head>
<body background=white topmargin=100 leftmargin=100>
<div id="layer1" style="position:absolute;left:100px;top:0px;height:50px;width:50px;color:white;background-color:navy;visibility:hidden;filter:blendTrans(duration=.5)">layer1</div>
<div id="layer2" style="position:absolute;left:200px;top:0px;height:50px;width:50px;background-color:navy;visibility:hidden;filter:blendTrans(duration=.5)">layer2</div>
<div id="layer3" style="position:absolute;left:300px;top:0px;height:50px;width:50px;background-color:navy;visibility:hidden;filter:blendTrans(duration=.5)">layer3</div>
<div id="layer4" style="position:absolute;left:400px;top:0px;height:50px;width:50px;background-color:navy;visibility:hidden;filter:blendTrans(duration=.5)">layer4</div>
<div id="layer5" style="position:absolute;left:500px;top:0px;height:50px;width:50px;background-color:navy;visibility:hidden;filter:blendTrans(duration=.5)">layer5</div>
<div id="layer6" style="position:absolute;left:600px;top:0px;height:50px;width:50px;background-color:navy;visibility:hidden;filter:blendTrans(duration=.5)">layer6</div>
<div id="layer7" style="position:absolute;left:700px;top:0px;height:50px;width:50px;background-color:navy;visibility:hidden;filter:blendTrans(duration=.5)">layer7</div>
<div id="layer8" style="position:absolute;left:800px;top:0px;height:50px;width:50px;background-color:navy;visibility:hidden;filter:blendTrans(duration=.5)">layer8</div>
<br />
<br />
<a href="#" onmouseover="fadein1()" onmouseout="fadeout1()">layer 1 rollover</a><br />
<a href="#" onmouseover="fadein2()" onmouseout="fadeout2()">layer 2 rollover</a><br />
<a href="#" onmouseover="fadein3()" onmouseout="fadeout3()">layer 3 rollover</a><br />
<a href="#" onmouseover="fadein4()" onmouseout="fadeout4()">layer 4 rollover</a><br />
<a href="#" onmouseover="fadein5()" onmouseout="fadeout5()">layer 5 rollover</a><br />
<a href="#" onmouseover="fadein6()" onmouseout="fadeout6()">layer 6 rollover</a><br />
<a href="#" onmouseover="fadein7()" onmouseout="fadeout7()">layer 7 rollover</a><br />
<a href="#" onmouseover="fadein8()" onmouseout="fadeout8()">layer 8 rollover</a><br />
<br />
<br />
<a href="#" onclick="fadein1(); fadein2(); fadein3(); fadein4(); fadein5(); fadein6(); fadein7(); fadein8();">layers 1-8 fade in onclick</a><br />
<a href="#" onclick="fadeout1(); fadeout2(); fadeout3(); fadeout4(); fadeout5(); fadeout6(); fadeout7(); fadeout8();">layers 1-8 fade out onclick</a><br />
</body>
</html>
Choopernickel
04-05-2004, 02:37 PM
Welcome to the forums.
All you'll need to do is recode your functions to accept a parameter each.
function fadein(whichElement) {
whichElement.filters(0).Apply();
whichElement.style.visibility = "visible";
whichElement.filters(0).Play();
}
This tells the fadein function to operate on the element supplied as the argument whichElement.
Then, when calling the function, supply the argument.
<body background=white topmargin=100 leftmargin=100>
<div id="layer1" style="position:absolute;left:100px;top:0px;height:50px;w idth:50px;color:white;background-color:navy;visibility:hidden;filter:blendTrans(duration=.5)">layer1</div>
<div id="layer2" style="position:absolute;left:200px;top:0px;height:50px;w idth:50px;background-color:navy;visibility:hidden;filter:blendTrans(duration=.5)">layer2</div>
<a href="#" onmouseover="fadein(document.getElementById('layer1'));" onmouseout="fadeout1()">layer 1 rollover</a><br />
<a href="#" onmouseover="fadein(document.getElementById('layer2'))" onmouseout="fadeout2()">layer 2 rollover</a><br />
I'm certain you can recode the fadeout() function by yourself.
Good luck, and happy scripting! :thumbsup:
immedicable
04-05-2004, 03:05 PM
thank you, that worked great.
the last two links are supposed to call the function on several elements, i tried scripting it like this :
<a href="#" onclick="fadein(document.getElementById('layer1'),('layer2'), ('layer3'),('layer4'));">layers 1-8 fade in onclick</a>
but it didnt work, so i tried this:
<a href="#" onclick="fadein(document.getElementById('layer1')),fadein(document.getElementById('layer2')),fadein(document. getElementById('layer3')),fadein(document.getElementById('layer4')),fadein(document.getElementById(' layer5')),fadein(document.getElementById('layer6')),fadein(document.getElementById('layer7')),fadein (document.getElementById('layer8'));">layers 1-8 fade in onclick</a><br />
but that seems bulky. is there a better way?
thanks again.
Vincent Puglia
04-05-2004, 03:32 PM
Hi,
javascript functions have a built-in 'arguments' property that you can take advantage of. Simply call the function with as many parameters as needed:
<.....onmouseover="fadein('layer1','layer2'......)....>
And then, use the arguments property to loop through and execute whatever you want:
function fadein() {
for (var i = 0; i < arguments.length; i++)
{
var divObj = document.getElementById(arguments[i])
divObj.filters(0).Apply();
divObj.style.visibility = "visible";
divObj.filters(0).Play();
}
}
Vinny
Choopernickel
04-05-2004, 03:51 PM
For multiple fades, I'd create a separate function that calls the other. What I'm going to do here is use the arguments scope as an array, which allows me to pass in an arbitrary number of arguments.
fadeInMany () {
if (!arguments.length) {
return;
}
var len = arguments.length,
i = 0;
do {
fadeIn(document.getElementById(arguments[i++]));
} while (len > i);
}
Let me take you through that statement by statement.
if (!arguments.length) {return}
If there is no length to the arguments array, that means none were passed in. Quit the execution of the function.
var len=arguments.length, i=0;
I'm creating local variables to use in my loop, starting with the length of the arguments array, for comparison.
do {...} while (len > i);
This is a fast loop which will execute at least once - guaranteed - and quit when the while criteria are not met, in this case, when i is equal to or greater than len.
fadeIn(document.getElementById(arguments[i++]));
Looks familiar, right? Using the notation arguments[i++] will grab the next argument passed to the function, and increase the iterator all at the same time.
Call the function like this:
<a href="#" onclick="fadeInMany('layer1','layer2','layer3','layer4'...);">layers 1-8 fade in onclick</a>
Your fadeout function can be developed along the exact same lines.
Vincent Puglia
04-05-2004, 04:05 PM
Hi Choopernickel,
I admit your solution is a viable one, but why create two functions when one would do? Doing so only bloats the page (imho) and makes debugging more difficult.
Vinny
immedicable
04-05-2004, 04:06 PM
vinny : that's exactly what i was going for. thanks. is the divObj arbitrary? if i wanted to use the same type of function in the document, just change the terms 'fadein' and 'divObj' to anything else and that's it, right?
choop: thanks again, the explanation cleared up a lot for me. is there any benefit to using the longer script you posted instead of the shorter one vinny posted?
appreciate the help guys.
Vincent Puglia
04-05-2004, 04:10 PM
all variable and function names are arbitrary.
afaik, there is no functional difference between the 2 scripts. My subjective impressions, however, are stated above.
Vinny
Garadon
04-05-2004, 05:07 PM
This is based on those 2 others idea but some changes, there is one 1 fade function only, and instead of writing document.get... in each event it simply sends the id to the function, in your case only the number, there by minimising your file size.
<html>
<head>
<script language="javascript">
var fIn=true;var fOut=false;
function fade(aWay)
{
for(I=1;I<arguments.length;I++)
{
obj=document.getElementById('layer'+arguments[I]);
obj.filters(0).Apply();
obj.style.visibility =(aWay)?"visible":"hidden";
obj.filters(0).Play();
}
}
</script>
</head>
<body background=white topmargin=100 leftmargin=100>
<div id="layer1" style="position:absolute;left:100px;top:0px;height:50px;w idth:50px;color:white;background-color:navy;visibility:hidden;filter:blendTrans(dur ation=.5)">layer1</div>
<div id="layer2" style="position:absolute;left:200px;top:0px;height:50px;w idth:50px;background-color:navy;visibility:hidden;filter:blendTrans(dur ation=.5)">layer2</div>
<div id="layer3" style="position:absolute;left:300px;top:0px;height:50px;w idth:50px;background-color:navy;visibility:hidden;filter:blendTrans(dur ation=.5)">layer3</div>
<div id="layer4" style="position:absolute;left:400px;top:0px;height:50px;w idth:50px;background-color:navy;visibility:hidden;filter:blendTrans(dur ation=.5)">layer4</div>
<div id="layer5" style="position:absolute;left:500px;top:0px;height:50px;w idth:50px;background-color:navy;visibility:hidden;filter:blendTrans(dur ation=.5)">layer5</div>
<div id="layer6" style="position:absolute;left:600px;top:0px;height:50px;w idth:50px;background-color:navy;visibility:hidden;filter:blendTrans(dur ation=.5)">layer6</div>
<div id="layer7" style="position:absolute;left:700px;top:0px;height:50px;w idth:50px;background-color:navy;visibility:hidden;filter:blendTrans(dur ation=.5)">layer7</div>
<div id="layer8" style="position:absolute;left:800px;top:0px;height:50px;w idth:50px;background-color:navy;visibility:hidden;filter:blendTrans(dur ation=.5)">layer8</div>
<br />
<br />
<a href="#" onmouseover="fade(fIn,1)" onmouseout="fade(fOut,1)">layer 1 rollover</a><br />
<a href="#" onmouseover="fade(fIn,2)" onmouseout="fade(fOut,2)">layer 2 rollover</a><br />
<a href="#" onmouseover="fade(fIn,3)" onmouseout="fade(fOut,3)">layer 3 rollover</a><br />
<a href="#" onmouseover="fade(fIn,4)" onmouseout="fade(fOut,4)">layer 4 rollover</a><br />
<a href="#" onmouseover="fade(fIn,5)" onmouseout="fade(fOut,5)">layer 5 rollover</a><br />
<a href="#" onmouseover="fade(fIn,6)" onmouseout="fade(fOut,6)">layer 6 rollover</a><br />
<a href="#" onmouseover="fade(fIn,7)" onmouseout="fade(fOut,7)">layer 7 rollover</a><br />
<a href="#" onmouseover="fade(fIn,8)" onmouseout="fade(fOut,8)">layer 8 rollover</a><br />
<br />
<br />
<a href="#" onclick="fade(fIn,1,2,3,4,5,6,7,8);">layers 1-8 fade in onclick</a><br />
<a href="#" onclick="fade(fOut,1,2,3,4,5,6,7,8)">layers 1-8 fade out onclick</a><br />
</body>
</html>
Choopernickel
04-05-2004, 06:50 PM
It's interesting to watch the progression of complexity in these scripts evolve. It is just about how I would have imagined.
1 - Repeated, non-reusable functions
2 - Dual, reusable functions with supplemental function managers
3 - Combination of managerial functions and executable functions
4 - Combination of dual complex functions into single complex function, with somewhat different arguments
I think Garadon's version might be nearly optimal; however, it breaks a couple of rules. The function isn't applicable to any old random page element, since it looks for specific element ID strings, which should be left to the calling of the function. It is no longer encapsulated, as it relies on a pair of global variables (fIn, fOut). It breaks scope by instantiating its own global variables (I and obj). It seems that constants would work well here: the next step is object-orientation (or object-basing) of the script. I'll add in a couple extras here, too.
function fade(dir) {
// validation of arguments
if ((2 > arguments.length) || (dir != fade.IN && dir != fade.OUT)) {
return;
}
// create local variables
var len = arguments.length,
i = 1,
toFade;
do {
// we can pass in object IDs or actual objects as arguments
if (typeof(arguments[i]) == 'string') {
toFade = document.getElementById(arguments[i]);
} else {
toFade = arguments[i];
}
try { // in case it doesn't work
toFade.filters(0).Apply();
toFade.style.visibility = dir ? "visible" : "hidden";
toFade.filters(0).Play();
} catch (err) {
continue;
}
} while (len > ++i); // don't forget to increment
}
// create constants for the function
fade.IN = true;
fade.OUT = false;
...
<style type="text/css">
.fader {
position: absolute;
top: 0px;
height: 50px;
width: 50px;
color: white;
background-color: navy;
visibility: hidden;
filter: blendTrans(duration=.5);
}
</style>
</head><body>
<div id="layer1" class="fader" style="left:100px">layer1</div>
<div id="layer2" class="fader" style="left:200px">layer2</div>
...
<a href="#" onmouseover="fade(fade.IN,'layer1')" onmouseout="fade(fade.OUT,'layer1')">layer 1 rollover</a><br />
<a href="#" onmouseover="fade(fade.OUT,'layer2')" onmouseout="fade(fade.OUT,'layer2')">layer 2 rollover</a><br />
...
<a href="#" onclick="fade(fade.IN,'layer1','layer2'...);">layers 1-8 fade in onclick</a><br />
The reasons I don't mind more typing -- and neither should you -- are various and sundry, but always lead back to good programming practices.
Readable code makes for maintainable code.
Encapsulated scripts cause fewer problems, especially with other scripts.
Global variables lead to massive memory consumption, which leads to performance issue - granted, that isn't typically a problem in javascript, but wouldn't you prefer to know that the browser's crashing due to its own memory leak instead of one in what you coded? ;)
Vincent asked a few posts ago why I used an extra function (what I called 'managerial' above) instead of wrapping that functionality into the main fader function. Most of my programs follow a very strict delegational pattern, where only what is meant to do a specific task does that specific task. According to those guidelines, no such thing as a quick and dirty javascript should exist. The delegation of the loop and call to fade() away from the function that actually fades is a way to provide room in the future should some other feature become desired or necessary to execute with the fade in that special case when all fade at once. Not that such a change will happen, but that it might. Future-proofing, that's all. It bloats the page (by about 60 characters, not too much at all), but it gives me more readable code, which is more maintainable code.
Garadon
04-05-2004, 07:46 PM
Addressing the conserm that 2 global booleans migth break the max memory boundary and that logical naming of ids was to hard for future users I made some alterations. :)
<html>
<head>
<script language="javascript">
function fade()
{
for(var I=0;I<arguments.length;I++)
{
var obj=document.getElementById(arguments[I]);
obj.filters(0).Apply();
if(!obj.jsfaded){obj.style.visibility="visible";obj.jsfaded=true;}else{obj.style.visibility="hidden";obj.jsfaded=false;}
obj.filters(0).Play();
}
}
</script>
<style>
.fader{
position:absolute;
top:0px;
height:50px;
width:50px;
color:white;
background-color:navy;
visibility:hidden;
filter:blendTrans(dur ation=.5)
}
</style>
</head>
<body background=white topmargin=100 leftmargin=100>
<div id="layer1" class="fader" style="left:100px;">layer1</div>
<div id="layer2" class="fader" style="left:200px;">layer2</div>
<div id="layer3" class="fader" style="left:300px;">layer3</div>
<div id="layer4" class="fader" style="left:400px;">layer4</div>
<div id="layer5" class="fader" style="left:500px;">layer5</div>
<div id="layer6" class="fader" style="left:600px;">layer6</div>
<div id="layer7" class="fader" style="left:700px;">layer7</div>
<div id="layer8" class="fader" style="left:800px;">layer8</div>
<br />
<br />
<a href="#" onmouseover="fade('layer1')" onmouseout="fade('layer1')">layer 1 rollover</a><br />
<a href="#" onmouseover="fade('layer2')" onmouseout="fade('layer2')">layer 2 rollover</a><br />
<a href="#" onmouseover="fade('layer3')" onmouseout="fade('layer3')">layer 3 rollover</a><br />
<a href="#" onmouseover="fade('layer4')" onmouseout="fade('layer4')">layer 4 rollover</a><br />
<a href="#" onmouseover="fade('layer5')" onmouseout="fade('layer5')">layer 5 rollover</a><br />
<a href="#" onmouseover="fade('layer6')" onmouseout="fade('layer6')">layer 6 rollover</a><br />
<a href="#" onmouseover="fade('layer7')" onmouseout="fade('layer7')">layer 7 rollover</a><br />
<a href="#" onmouseover="fade('layer8')" onmouseout="fade('layer8')">layer 8 rollover</a><br />
<br />
<br />
<a href="#" onclick="fade('layer1','layer2','layer3','layer4','layer5','layer6','layer7','layer8');">layers 1-8 fade in onclick</a><br />
<a href="#" onclick="fade('layer1','layer2','layer3','layer4','layer5','layer6','layer7','layer8')">layers 1-8 fade out onclick</a><br />
</body>
</html>
Vincent Puglia
04-05-2004, 09:26 PM
Hi Choopernickel,
I now understand your rationale for the two functions. In many cases I would agree (eg. where the 'inner' function can be used by a different app with different circumstances/parameters). That's the beauty of coding -- many roads to reach the same destination.
Unfortunately, I've seen many a script/program with umpteen functions that did one thing only -- to the point where each included file (such as *.js files) contained only one function -- where some overloading and/or switching would have made the code easier to follow (at least to me). I believe, but don't know, that too much encapulation is what Windows the hog it is.
Vinny
Choopernickel
04-05-2004, 10:13 PM
Addressing the [concerns] that 2 global booleans [might] break the max memory boundary and that logical naming of ids was [too] hard for future users I made some alterations. :)
It's not the specific instances of the global variables, it's the practice of using global variables that is bad. We have no idea if immedicable (the O.P.) plans on only using this script, or if s/he means to use this in conjunction with others. Now, two globals per script is fine and all, but the practice of using globals may encourage a developer to declare hundreds of globals, such as with overLib (google if you don't know it), which will just eat memory like mad.
The logical naming of IDs isn't the other problem- it's that you developed a function that was so specific to a page, it couldn't be linked to and reused by another page with a different navigation naming scheme, or for a photo gallery for example.
Also, you seem to have forgotten that [ code] tags exist. Any reason?
-p.s. Don't think me harsh, I'm really just trying to continue the conversation.
Choopernickel
04-05-2004, 10:22 PM
I now understand your rationale for the two functions. In many cases I would agree (eg. where the 'inner' function can be used by a different app with different circumstances/parameters). That's the beauty of coding -- many roads to reach the same destination.
Unfortunately, I've seen many a script/program with umpteen functions that did one thing only -- to the point where each included file (such as *.js files) contained only one function -- where some overloading and/or switching would have made the code easier to follow (at least to me). I believe, but don't know, that too much encapulation is what [makes] Windows the hog it is.
And in this script, it's probably just as well that the two functions are pulled in together. It's a matter of refactoring when it makes sense. As for Windows, I can't say. As for complicated javascript libraries, wherein certain functions are designated to have specific purposes (such as GetElement() or IsNode() etc.), having well-delegated responsibilities makes more sense every time you look at it. This script, I have to say, was probably refactored at just the right speed and to just the right efficiency. Not bad for eight hours' wait, right? Now, if it gets to a point where seventeen script files are imported for a single small function each, then there's a problem: the developer was not weighing HTTP traffic into the equation at all.
Overloading and switching, you mention, are wonderful functionality to put into controller-like scripts. I'll say again, this is a script clear enough not to demand it. I have to reveal something about my activity in this thread now: I purposefully did not post a complete solution at 9:37 or 10:51 because I knew this could be a better welcome for a new member. Why encourage someone to post a question, get the answer, and leave immediately? Thanks for the discussion, Vinny and Garadon, and welcome again to immedicable.
Vincent Puglia
04-05-2004, 10:33 PM
You're welcome & thanks for adding '[makes]' (though you missed the 'encapulation' [sic] )
:D
I also enjoyed the discussion.
Vinny
Garadon
04-05-2004, 10:57 PM
I must admit I don't like that new [code] textares I more or less find it extremely irritating having them. compared to the old where is was simply a part of the page l like all other text.
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.