creating a class

W

windandwaves

Hi Folk

I just wrote a function (see below). Now, it occurred to me that it
is hard to use the same function on a page twice and at the same
time. How would I change the function below into an object / class
that:
- I can use twice at the same time
- the variables don't affect other variables that maybe used on the
page (i.e. take them out the global domain)



Hope that makes sense.

Thank you.


//you can set these variables
var totalTime = 1000;//in milliseconds
var startOpacity = 99.9999; // starting point for fade
var stopOpacity = 0; //end point for fade
var numberOfSteps = 30; //number of steps

//other variables
var speed; //in milliseconds
var opacity; //starting point
var step; //interval for each one
var div;
var startOpacity;

function startFade(elName){
opacity = startOpacity;
step = (stopOpacity - startOpacity) / numberOfSteps;
speed = totalTime / numberOfSteps;
div = document.getElementById(elName);
repeatFade();
return true;
}


function repeatFade() {
opacity += step;
var last = false;
if(Math.abs(stopOpacity - opacity) < Math.abs(step)) {
opacity = stopOpacity;
last = true;
}
if(opacity >= 0 && opacity <= 100) {
div.style.filter = "alpha(opacity="+Math.round(opacity)+")";// IE/
Winfilter: alpha(opacity=50)
div.style.KHTMLOpacity = opacity/100;// Safari<1.2, Konqueror
div.style.MozOpacity = opacity/100;// Older Mozilla and Firefox
div.style.opacity = opacity/100;// Safari 1.2, newer Firefox and
Mozilla, CSS3
if(last == false) {
window.setTimeout("repeatFade()", speed);
}
}
}
 
P

Peter Michaux

Hi Folk

I just wrote a function (see below). Now, it occurred to me that it
is hard to use the same function on a page twice and at the same
time. How would I change the function below into an object / class
that:
- I can use twice at the same time
- the variables don't affect other variables that maybe used on the
page (i.e. take them out the global domain)

Hope that makes sense.

Thank you.

//you can set these variables
var totalTime = 1000;//in milliseconds
var startOpacity = 99.9999; // starting point for fade
var stopOpacity = 0; //end point for fade
var numberOfSteps = 30; //number of steps

//other variables
var speed; //in milliseconds
var opacity; //starting point
var step; //interval for each one
var div;
var startOpacity;

function startFade(elName){
opacity = startOpacity;
step = (stopOpacity - startOpacity) / numberOfSteps;
speed = totalTime / numberOfSteps;
div = document.getElementById(elName);
repeatFade();
return true;

}

function repeatFade() {
opacity += step;
var last = false;
if(Math.abs(stopOpacity - opacity) < Math.abs(step)) {
opacity = stopOpacity;
last = true;
}
if(opacity >= 0 && opacity <= 100) {
div.style.filter = "alpha(opacity="+Math.round(opacity)+")";// IE/
Winfilter: alpha(opacity=50)
div.style.KHTMLOpacity = opacity/100;// Safari<1.2, Konqueror
div.style.MozOpacity = opacity/100;// Older Mozilla and Firefox
div.style.opacity = opacity/100;// Safari 1.2, newer Firefox and
Mozilla, CSS3
if(last == false) {
window.setTimeout("repeatFade()", speed);
}
}

}

You don't need a class or object. Just functions and closures are the
cleanest options for this sort of animation. Just moving some of your
code around I get the following untested code. This is roughly how I
do anmiations.

function startFade(elName){

//you can set these variables
var totalTime = 1000;//in milliseconds
var startOpacity = 99.9999; // starting point for fade
var stopOpacity = 0; //end point for fade
var numberOfSteps = 30; //number of steps

//other variables
var speed; //in milliseconds
var opacity; //starting point
var step; //interval for each one
var div;
var startOpacity;

opacity = startOpacity;
step = (stopOpacity - startOpacity) / numberOfSteps;
speed = totalTime / numberOfSteps;
div = document.getElementById(elName);

function repeatFade() {
opacity += step;
var last = false;
if(Math.abs(stopOpacity - opacity) < Math.abs(step)) {
opacity = stopOpacity;
last = true;
}
if(opacity >= 0 && opacity <= 100) {
div.style.filter = "alpha(opacity="+Math.round(opacity)+")";// IE/
Winfilter: alpha(opacity=50)
div.style.KHTMLOpacity = opacity/100;// Safari<1.2, Konqueror
div.style.MozOpacity = opacity/100;// Older Mozilla and Firefox
div.style.opacity = opacity/100;// Safari 1.2, newer Firefox and
Mozilla, CSS3
if(last == false) {
window.setTimeout("repeatFade()", speed);
}
}

}

repeatFade();
return true;
}




Peter
 
R

RobG

Hi Folk

I just wrote a function (see below). Now, it occurred to me that it
is hard to use the same function on a page twice and at the same
time. How would I change the function below into an object / class
that:

Using terminology like "class" in javascript is really only
appropriate for those who know about classic OO programming, and even
then it often confuses when applied to javascript. Just think of
Objects. :)
- I can use twice at the same time
- the variables don't affect other variables that maybe used on the
page (i.e. take them out the global domain)

Rather than convert your code, I'll give you a strategy for creating a
constructor that you can use to create as many objects as you like
using javascript prototype inheritance.

You crate a function to use as a constructor, it adds properties to
individual instances of the objects you are going to create. You then
add the shared properties to the constructor's prototype property -
pretty simple really. I suggest you try it with something really
simple first, like a constructor that adds a single property and a
prototpye that supplies a single method[1].


// Declare a function to use as a constructor
function Fader(arg0, arg1, ...){

// Add properties that each instance of new
// object should have to themselves
this.totalTime = arg0;
this.startOpacity = arg1;
this.stopOpacity = arg2;
this.numberOfSteps = arg3;
...

// The methods that each instance of new
// object should have to themselves
this.method0 = function(){ ... }
this.method1 = function(){ ... }
}

Now add methods and variables to the Fader prototype that you want
constructed Fader objects to share:

Fader.prototype.startFade = function(el) {
var step = (this.stopOpacity-this.startOpacity)/this.numberOfSteps;
...
}

And so on. Now you can do:

var fader0 = new Fader(100, 0, 100, ...);
fader0.startFade(el);

Have a go and see how far you get. :)

When you think you've mastered that, you can start to look at more
advanced strategies such as that proposed by Richard Cornford here:

<URL: http://www.litotes.demon.co.uk/js_info/private_static.html >


1. e.g.

function Foo(arg){
this.name = arg;
}

Foo.prototype.sayName = function(){
alert(this.name);
}

var bar = new Foo('bar');
bar.sayName(); // Shows 'bar'
 
R

RobG

Tell that to David Flanagan who specifically states, "In addition to
functions and arrays, core JavaScript defines a few other specialized
kinds of objects. These objects do not represent new datatypes, just
new /classes/ of objects."

My comments were in regard to the confusion caused when people discuss
javascript in terms of classic OO features. Those new to javascript
and who are familiar with say C++ or Java immediately view javascript
"classes" in terms of those languages. Subsequently they are often
disappointed or confused when things don't go as expected - much like
the usage of hash or associative array, but let's not start that
again! :)

I can't add anything to the footnote add by Richard Cornford to his
article "Private Static Members in Javascript" headed:

"Note: The Applicability of the Terminology from Class-Based Languages
to Javascript."
<URL: http://www.litotes.demon.co.uk/js_info/private_static.html#nTerm
[...]

Thereby any declaration of a function with "private" member
variables is essentially a class, at least by Flanagan's explanation.

QED - whether a javascript constructor has "private member variables"
or not is irrelevant:

function Foo(){};
var x = new Foo();

the fact that Foo is a function means it can be used as a
constructor. Similarly, the fact that an object was constructed from
a particular object doesn't mean it necessarily inherits *anything*
from its constructor - you can re-assign its prototype, add to the
scope chain, shadow properties and so on.

Whilst I understand this concept, I was quite happy in the knowledge
that these were constructors, not classes with constructors. And now
instead of instantiating new objects of type *whatever*, I am using a
"class" that returns objects, to which an identifier is assigned.

If you are comfortable with that, fine. I just think that for anyone
learning javascript terms like "class" or "private member" should be
introduced solely as hints to behaviour, not as fundamental components
of the language.
 
P

Peter Michaux

Tell that to David Flanagan who specifically states, "In addition to
functions and arrays, core JavaScript defines a few other specialized
kinds of objects. These objects do not represent new datatypes, just
new /classes/ of objects."

He then goes on to call Date, RegExp, and Error specifically, classes.

David Flanagan also writes books on Java and some of that terminology
leaks into the JavaScript book.

-Peter
 
D

dhtmlkitchen

Hi Folk

I just wrote a function (see below). Now, it occurred to me that it
is hard to use the same function on a page twice and at the same
time. How would I change the function below into an object / class
that:
- I can use twice at the same time
- the variables don't affect other variables that maybe used on the
page (i.e. take them out the global domain)

Hope that makes sense.

Thank you.

//you can set these variables
var totalTime = 1000;//in milliseconds
var startOpacity = 99.9999; // starting point for fade
var stopOpacity = 0; //end point for fade
var numberOfSteps = 30; //number of steps

//other variables
var speed; //in milliseconds
var opacity; //starting point
var step; //interval for each one
var div;
var startOpacity;

function startFade(elName){
opacity = startOpacity;
step = (stopOpacity - startOpacity) / numberOfSteps;
speed = totalTime / numberOfSteps;
div = document.getElementById(elName);
repeatFade();
return true;

}

function repeatFade() {
opacity += step;
var last = false;
if(Math.abs(stopOpacity - opacity) < Math.abs(step)) {
opacity = stopOpacity;
last = true;
}
if(opacity >= 0 && opacity <= 100) {
div.style.filter = "alpha(opacity="+Math.round(opacity)+")";// IE/
Winfilter: alpha(opacity=50)
div.style.KHTMLOpacity = opacity/100;// Safari<1.2, Konqueror
div.style.MozOpacity = opacity/100;// Older Mozilla and Firefox
div.style.opacity = opacity/100;// Safari 1.2, newer Firefox and
Mozilla, CSS3
if(last == false) {
window.setTimeout("repeatFade()", speed);
}
}

}

Create a constructor function and a prototype for the instance method.

function Fade() {

}

Fade.prototype = {

activate : function fadeIn() {

}

,deactivate : function fadeOut() {


};

I would consider:

* using a base class Effect and extending that. You can use
aggregation to build up widgets with Effect instances.
* using a decorator pattern to decorate the base class.
* Having Effect subclasses take a Widget as a parameter argument.
This would make it easy to wire in event subscription.


For extension, I recommend looking at YAHOO.extend();

YAHOO.extend(Fade, Effect, {

// Your override instance methods here.
});

Then you program to the Interface of Effect and have activate and
deactivate.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top