Log in

View Full Version : Jasoop Toolbox



magicyte
10-04-2008, 01:11 AM
I created this toolbox called Jasoop. Jasoop stands for JavaScript Object Oriented Programming Toolbox. I created it and it was originally created for programmers who wanted to animate elements on a webpage (by moving them) easily. Here it is. Anybody on the forums and in the world is allowed to use it. I am not sure it works in some browsers, such as FF, but it works in IE7. Here it is:

Jasoop Toolbox (jasoop.js)


/******** - IMPORTANT LABEL - ********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Copyright: 2008 Arthur C. Watkins */
/* Noice: This label is to exist in */
/* this document in order for this */
/* document to be legal. */
/******** - IMPORTANT LABEL - ********/

// Start Jasoop Toolbox

var _ = function (a) {
if(document.getElementById()) return document.getElementById(a);
else if(document.layers) return document.layers[a];
else if(document.all) return document.all[a];
}

function Animation (elementName)
{
var animationClass = this;
var animateX = new Array();
var animateY = new Array();
var animateInt = new Array();
var llCounter=0;
var animationCounter=0;
this.pxWidth = function (w) {
_(elementName).style.width = w;
};
this.pxHeight = function (h) {
_(elementName).style.height = h;
};
this.backgroundColor = function (bgcol) {
_(elementName).style.backgroundcolor = bg;
};
this.textColor = function (txtcol) {
_(elementName).style.color = txtcol;
};
this.moveTo = function (x,y) {
_(elementName).style.position = "absolute";
_(elementName).style.left = x;
_(elementName).style.top = y;
};
this.add = function (x,y,int) {
animateX[llCounter] = x;
animateY[llCounter] = y;
animateInt[llCounter] = int;
llCounter++;
};
this.animate = function () {
if(animationCounter < llCounter)
{
_(elementName).style.position = "absolute";
_(elementName).style.left = animateX[animationCounter];
_(elementName).style.top = animateY[animationCounter];
animationCounter++;
setTimeout(function () { animationClass.animate() },animateInt[animationCounter]);
}
else if(animationCounter >= llCounter)
{
for(i = 0; i <= animationCounter; i++)
{
animateX[i]=0;
animateY[i]=0;
animateInt[i]=0;
}
llCounter=0;
animationCounter=0;
}
};
this.reset = function () {
for(i=0; i<=animationCounter; i++)
{
animateX[i]=0;
animateY[i]=0;
animateInt[i]=0;
}
llCounter = 0;
animationCounter = 0;
};
}

// End Jasoop Toolbox

Here is an example HTML page:


<html>
<head>
<title>Jasoop Toolbox Test</title>
<script type="text/javascript" src="jasoop.js">
<!--
-->
</script>
<script type="text/javascript">
var animator = new Animation ("animation");

for(i = 0; i < 400; i++) {
animator.add(i,i,10);
}

animator.add(0,0,10);
</script>
</head>
<body onload="animator.moveTo(0,0);">
<input type="button" value="Animate" onclick="animator.animate()">
</body>
</html>

Feel free to give me feedback or suggestions on the toolbox.

-magicyte

magicyte
10-04-2008, 06:32 PM
I also do have one question for any good programmers out there. Is it possible that I could add some sort of image function to this? You know, like if the programming user wants to add an image to the animation (as well as movement), such as changing the image source of the element, that may make the animation more or less interesting?

-magicyte

Twey
10-05-2008, 12:25 PM
var $ = function (a) {The character $ is meant to be reserved for use by machine-generated code.
this.pxWidth = function (w) {You probably don't want to recreate all your methods every time you construct an instance. Move them to the prototype.

Additionally, your indentation is irregular.

magicyte
10-05-2008, 08:04 PM
Thanks. Yeah, my intentation IS irregular. I do 4 spaces, while it is supposed to be 2.

-magicyte

Twey
10-05-2008, 09:46 PM
Ten spaces? That's far too much. Nobody uses more than eight. Personally I think anything over four is excessive, and two is usually quite sufficient. No, the issue is that sometimes you indent, and sometimes you don't.

magicyte
10-06-2008, 09:24 PM
Oh. Nevermind!! :D

By the way, I changed the $('id') to _('id'). Is this good?

-magicyte

Twey
10-06-2008, 10:29 PM
Lovely, I'm sure. However, your indentation is still irregular, and you're still recreating your methods for every new instance — a horrible and unnecessary drain on resources.

magicyte
10-07-2008, 01:19 AM
Could you provide a formatted version of my JS file? Also, do you have any reference that I could use to learn how to prototype methods into my objects, or even you telling me?

Thanks for your dedication.

-magicyte

Twey
10-07-2008, 03:57 PM
Oh, I was wary of doing so since it says 'DO NOT EDIT THIS DOCUMENT'. That was a bit of a scary noice! Having your explicit permission, I'm sure I can find it in me to perform a C-x h C-M-\ and maybe even add some sanity... :)
/******** - IMPORTANT LABEL - ********/
/* Title: Jasoop Toolbox (c) */
/* Name: jasoop.js */
/* Copyright: 2008 Arthur C. Watkins */
/* Noice: This label is to exist in */
/* this document in order for this */
/* document to be legal. */
/* DO NOT EDIT THIS DOCUMENT */
/******** - IMPORTANT LABEL - ********/

// Start Jasoop Toolbox

function Animation(elementName) {
this.animateX = [];
this.animateY = [];
this.animateInt = [];
this.llCounter = 0;
this.animationCounter = 0;
this.element = document.getElementById(elementName);
}

Animation.prototype = function() {
return {
pxWidth: function(w) {
this.element.style.width = w + "px";
},

pxHeight: function(h) {
this.element.style.height = h + "px";
},

backgroundColor: function(bgcol) {
this.element.style.backgroundcolor = bg;
},

textColor: function(txtcol) {
this.element.style.color = txtcol;
},

moveTo: function(x, y) {
this.element.style.position = "absolute";
this.element.style.left = x;
this.element.style.top = y;
},

add: function(x, y, n) {
this.animateX[this.llCounter] = x;
this.animateY[this.llCounter] = y;
this.animateInt[this.llCounter] = n;
this.llCounter++;
},

animate: function() {
if (this.animationCounter < this.llCounter) {
this.element.style.position = "absolute";
this.element.style.left = this.animateX[this.animationCounter];
this.element.style.top = this.animateY[this.animationCounter];
this.animationCounter++;
setTimeout(function() { animationClass.animate(); }, this.animateInt[this.animationCounter]);
} else if (this.animationCounter >= this.llCounter) {
for (i = 0; i <= this.animationCounter; i++) {
this.animateX[i] = 0;
this.animateY[i] = 0;
this.animateInt[i] = 0;
}

this.llCounter = 0;
this.animationCounter = 0;
}
},

reset: function() {
for (var i = 0; i <= this.animationCounter; ++i) {
this.animateX[i] = 0;
this.animateY[i] = 0;
this.animateInt[i] = 0;
}

this.llCounter = 0;
this.animationCounter = 0;
}
};
}();

// End Jasoop ToolboxNote that I've just restructured and fixed it, rather than performed any serious modification... parallel arrays are rarely a good idea, and you have a lot of redundant functions (if it's only one statement, it doesn't need to be a function [unless it's a really complicated one that you want labelled]; if it's never used, it doesn't need to be a function). It can be greatly simplified:
/******** - IMPORTANT LABEL - ********/
/* Title: Jasoop Toolbox (c) */
/* Name: jasoop.js */
/* Copyright: 2008 Arthur C. Watkins */
/* Noice: This label is to exist in */
/* this document in order for this */
/* document to be legal. */
/* DO NOT EDIT THIS DOCUMENT */
/******** - IMPORTANT LABEL - ********/

// Start Jasoop Toolbox

var Animation = function() {
function Animation(elementName) {
this.steps = [];
this.animationCounter = 0;
this.style = document.getElementById(elementName).style;
}

Animation.prototype = {
moveTo: function(x, y) {
this.style.position = "absolute";
this.style.left = x + "px";
this.style.top = y + "px";
},

applyStep: function(step) {
this.moveTo(step.x, step.y);
step.callback(this, step);
setTimeout((function(me) { return function() { me.animate(); }; })(this),
step.pause);
},

add: function(x, y, pause, callback) {
this.steps[this.steps.length] = new Step(x, y, pause, callback);
},

animate: function() {
if (this.steps.length)
this.applyStep(steps.shift());
},

reset: function() {
this.steps = [];
}
};

function Step(x, y, pause, callback) {
this.x = x;
this.y = y;
this.pause = pause;
this.callback = callback || noop;
}

function noop() {}

return Animation;
}();

// End Jasoop ToolboxOther problems found on more detailed examination: 'int' is a reserved word, and the styles you set do not have units.

Twey
10-07-2008, 03:57 PM
Oh, I was wary of doing so since it says 'DO NOT EDIT THIS DOCUMENT'. Having your explicit permission, I'm sure I can find it in me to perform a C-x h C-M-\ and maybe even add some sanity... :)
/******** - IMPORTANT LABEL - ********/
/* Title: Jasoop Toolbox (c) */
/* Name: jasoop.js */
/* Copyright: 2008 Arthur C. Watkins */
/* Noice: This label is to exist in */
/* this document in order for this */
/* document to be legal. */
/* DO NOT EDIT THIS DOCUMENT */
/******** - IMPORTANT LABEL - ********/

// Start Jasoop Toolbox

function Animation(elementName) {
this.animateX = [];
this.animateY = [];
this.animateInt = [];
this.llCounter = 0;
this.animationCounter = 0;
this.element = document.getElementById(elementName);
}

Animation.prototype = function() {
return {
pxWidth: function(w) {
this.element.style.width = w + "px";
},

pxHeight: function(h) {
this.element.style.height = h + "px";
},

backgroundColor: function(bgcol) {
this.element.style.backgroundcolor = bg;
},

textColor: function(txtcol) {
this.element.style.color = txtcol;
},

moveTo: function(x, y) {
this.element.style.position = "absolute";
this.element.style.left = x;
this.element.style.top = y;
},

add: function(x, y, n) {
this.animateX[this.llCounter] = x;
this.animateY[this.llCounter] = y;
this.animateInt[this.llCounter] = n;
this.llCounter++;
},

animate: function() {
if (this.animationCounter < this.llCounter) {
this.element.style.position = "absolute";
this.element.style.left = this.animateX[this.animationCounter];
this.element.style.top = this.animateY[this.animationCounter];
this.animationCounter++;
setTimeout(function() { animationClass.animate(); }, this.animateInt[this.animationCounter]);
} else if (this.animationCounter >= this.llCounter) {
for (i = 0; i <= this.animationCounter; i++) {
this.animateX[i] = 0;
this.animateY[i] = 0;
this.animateInt[i] = 0;
}

this.llCounter = 0;
this.animationCounter = 0;
}
},

reset: function() {
for (var i = 0; i <= this.animationCounter; ++i) {
this.animateX[i] = 0;
this.animateY[i] = 0;
this.animateInt[i] = 0;
}

this.llCounter = 0;
this.animationCounter = 0;
}
};
}();

// End Jasoop ToolboxNote that I've just restructured and fixed it, rather than performed any serious modification... parallel arrays are rarely a good idea, and you have a lot of redundant functions (if it's only one statement, it doesn't need to be a function [unless it's a really complicated one that you want labelled]; if it's never used, it doesn't need to be a function). It can be greatly simplified:
/******** - IMPORTANT LABEL - ********/
/* Title: Jasoop Toolbox (c) */
/* Name: jasoop.js */
/* Copyright: 2008 Arthur C. Watkins */
/* Noice: This label is to exist in */
/* this document in order for this */
/* document to be legal. */
/* DO NOT EDIT THIS DOCUMENT */
/******** - IMPORTANT LABEL - ********/

// Start Jasoop Toolbox

var Animation = function() {
function Animation(elementName) {
this.steps = [];
this.animationCounter = 0;
this.style = document.getElementById(elementName).style;
}

Animation.prototype = {
moveTo: function(x, y) {
this.style.position = "absolute";
this.style.left = x + "px";
this.style.top = y + "px";
},

applyStep: function(step) {
this.moveTo(step.x, step.y);
step.callback(this, step);
setTimeout((function(me) { return function() { me.animate(); }; })(this), step.pause);
},

add: function(x, y, pause, callback) {
this.steps[this.steps.length] = new Step(x, y, pause, callback);
},

animate: function() {
if (this.steps.length)
this.applyStep(steps.shift());
},

reset: function() {
this.steps = [];
}
};

function Step(x, y, pause, callback) {
this.x = x;
this.y = y;
this.pause = pause;
this.callback = callback || noop;
}

function noop() {}

return Animation;
}();

// End Jasoop ToolboxOther problems found on more detailed examination: 'int' is a reserved word, and the styles you set do not have units.

magicyte
10-07-2008, 09:09 PM
heh, sorry. I just put that DO NOT EDIT THIS DOCUMENT thing there so that any innocent people who wanted my code would hesitate. I should probably take that off. And also the (c) part. It obviously isn't copyrighted... :D

Boy, oh boy!! Thanks for making that code for me! :)

I may possibly be considered the happiest man on Earth (for a slight second or so, considering the fact that there are people happier than me)! Hey, thanks for doing all of this for me. I'll show my thanks :-). Heh, I should probably have posted this somewhere else in the first place!

2 last questions (so I think):

1) You have my permission to edit the document :D - could it be better? Y/N. If so, I ask that you make it better for me and I will promise you 3 more thanks.

2) Could you please provide a link to where you learn this stuff?! :D I wanna learn more. I already have that www.howtocreate.co.uk link, so any others? If not a link, any references for JavaScript?

Once again, I greatly thank you for your kind help and effort, even though it may have been easy for you to accomplish. :)

-magicyte

Twey
10-08-2008, 01:17 AM
1) I would maybe do it something like this (untested, written late at night, may break):
var Objects = function() {
function copy(o) {
var r = {};

for (var x in o)
if(o.hasOwnProperty(x))
r[x] = o[x];

return r;
}

function combine(o1, o2) {
var r = copy(o1);

for (var x in o2)
if (o2.hasOwnProperty(x))
r[x] = o2[x];

return r;
}

return {
copy: copy,
combine: combine
};
};

var Effects = function() {
function moveEl(s, x, y) {
s.position = "absolute";
s.top = x + ("" + parseFloat(x) == x ? "px" : "");
s.left = y + ("" + parseFloat(y) == y ? "px" : "");
}

function noop() {}

function loop(a) {
return new Loop(a);
}

function Loop(a) {
this._a = a;
this._count = 0;
}

Loop.prototype = {
shift: function() {
if (this._count > this._a.length)
this._count = 0;

return this._a[this._count++];
}
};

var defaultOpts = {
default_timeout: 30,
finished_callback: noop,
step_callback: noop
};

function animate(el, steps, opts) {
var c = steps.shift(),
os = Objects.combine(defaultOpts, opts),
t = os.default_timeout;

if (typeof c === 'function')
c = c(el);

if (c === undefined)
return os.finished_callback.call(null, el);
else if (c instanceof Loop)
animate(el, c, Objects.combine(opts,
{finished_callback: function() { animate(el, steps, opts); }}));
else if (c instanceof Array) {
moveEl(el.style, c[0], c[1]);

if (typeof c[2] === 'number')
t = c[2];
} else if (typeof c === 'number')
t = c;

os.step_callback.call(null, el);

setTimeout(function() { animate(el, steps, opts); }, t);
}

return {
animate: animate,
loop: loop
};
}();2) Mostly from reading other code, I think, in JS. If you search for some of mwinter's old posts here on the forum, you may find them quite enlightening. Learning programming in general (http://dynamicdrive.com/forums/showpost.php?p=164524&postcount=1337) could help you, too. There's also a link in my signature to a list of common coding errors, which also contains some style mistakes (unfortunately not very many, since it had to fit into ten thousand characters — I'll add more once I get it hosted elsewhere).

magicyte
10-08-2008, 09:37 PM
Thank you, VERY MUCH!!!

-magicyte

magicyte
10-13-2008, 01:05 AM
Just for a heads up, (even though my code is HORRIFICALLY, what's the word, uh, 'bad') I upgraded my Jasoop Toolbox.
I wrote a basic tutorial as well for the, uh, 'impaired' (said loosely :D).

jasoop.js


/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label is to stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

// Start Jasoop Toolbox

var _ = function (el) {
if(document.getElementById()) return document.getElementById(el);
else if(document.layers) return document.layers[el];
else if(document.all) return document.all[el];
else return false;
};

var Concatenate = function (/*string arguments*/) {
var argv = arguments;
var argc = arguments.length;
var string;
string="";
for(x=0;x<argc;x++) {
string=string+argv[x];
}
return string;
};

var Shift = function (txt) {
var argv = txt;
var argc = txt.length;
var string;
string=argv.toUpperCase();
return string;
};

var Unshift = function (txt) {
var argv = txt;
var argc = txt.length;
var string;
string=argv.toLowerCase();
return string;
};

var getCookie = function (name) {
var argv = name + "=";
var argc = argv.length;
var clen = document.cookie.length;
var x = 0;
while (x < clen) {
var y = x + argc;
if(document.cookie.substring(x,y)==argv)
var e = document.cookie.indexOf(";",y);
if(e==-1)
e=document.cookie.length;
return unescape(document.cookie.substring(y,e));
x = document.cookie.indexOf(" ",x)+1;
if(x==0) break;
}
return null;
};

var setCookie = function () {
var argv = arguments;
var argc = arguments.length;
var name = (argc > 0) ? argv[0] : null;
var value = (argc > 1) ? argv[1] : null;
var expires = (argc > 2) ? argv[2] : null;
var path = (argc > 3) ? argv[3] : null;
var domain = (argc > 4) ? argv[4] : null;
var secure = (argc > 5) ? argv[5] : false;
document.cookie = ((name == null) ? "" : (name)) + "=" + ((value == null) ? "" : (escape(value))) + ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) + ((path == null) ? "" : ("; path=" + path)) + ((domain == null) ? "" : ("; domain=" + domain)) + ((secure == true) ? "; secure" : "");
};

var Animation = function (el) {
var animation = this;
var stop = false;
var x = [];
var y = [];
var delay = [];
var ac=0;
var lc=0;
this.autodelete = false;
this.loop = false;
};

Animation.prototype.moveTo = function (x,y) {
_(el).style.position="absolute";
_(el).style.left=x;
_(el).style.top=y;
}
Animation.prototype.compute = function (l,t,d) {
x[lc]=l;
y[lc]=t;
delay[lc]=d;
lc++;
}
Animation.prototype.start = function () {
if(!stop)
{
if(ac<lc)
{
_(el).style.position="absolute";
_(el).style.left=x[ac];
_(el).style.top=y[ac];
ac++;
setTimeout(function(){animation.start()},delay[ac]);
}
else if(ac>=lc)
{
(animation.autodelete) ? animation.reset() : ac=0;
(animation.loop) ? animation.start() : "";
}
}
else if(stop)
{
stop = !stop;
}
}
Animation.prototype.stop = function () {
stop = true;
}
Animation.prototype.reset = function() {
for(i=0;i<=ac;i++)
{
x[i]=0;
y[i]=0;
delay[i]=0;
}
lc=0;
ac=0;
}

// End Jasoop Toolbox

/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label is to stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

jttutorial.txt


Jasoop Toolbox Tutorial
2008 Arthur C. Watkins
This tutorial is based comepletely on JavaScript.

Getting Started:
To use Jasoop Toolbox, simply insert this code in between the <head> tag and the </head> tag in your HTML document:

<script type="text/javascript" src="jasoop.js"><!-- --></script>

Features of Jasoop Toolbox:
I. Makes animating elements easy
II. Makes accessing elements easy
III. Makes handling strings easier
IV. Makes cookie functions easier

I. Makes animating elements easy

To create an Animation object, create a variable with any name and create a new Animation object. Example:

var myAnim = new Animation("animId");

The parameter in Animation is the element-you-wish-to-animate's id or name. Example:

<head>
<script type="text/javascript">
<!--
var myAnim = new Animation("animId");
-->
</script>
</head>
<body>
<input type="button" id="animId" value="Animation">
</body>

There are five (5) functions in the Animation object:

1. moveTo(x,y);
2. compute(l,t,d);
3. start();
4. stop();
5. reset();

There are two (2) bool variables in the Animation object:

1. autodelete
2. loop

Functions:

1. moveTo(x,y);

To use this function, simply type in how many pixels from the left you want your element to move and how many pixels from the right you want your element to move. Example:

myAnim.moveTo(5,5);

2. compute(l,t,d);

To use this function, simply type in how many pixels from the left you want your element to move and how many pixels from the right you want your element to move. After that, type in the delaying time in milliseconds you want the animation to delay after it is started. Example:

myAnim.compute(5,5,50);

This function is used in the animation process of your element.

3. start();

To use this function, simply type it. This is used after you have computed the amount of animations you want to happen to your element. Example:

myAnim.start();

This can be stopped by the next function.

4. stop();

To use this function, simply type it. This is used to stop your animation after it is started. You can prevent this happenning too long by using the start() function again. Example:

myAnim.stop();

Once again, this can be reverted by the start() function.

5. reset();

To use this function, simply type it. This is used to completely delete all of your computations used in compute. Example:

myAnim.reset();

This will set all of your animation's information to zero (0).

Bool Variables:

1. autodelete

This bool variable is automatically set to false. It is used so that once your animation has finished animating your animation's information is set to zero (0), in which case the reset() function is called. Example:

myAnim.autodelete = true;
myAnim.autodelete = false;

2. loop

This bool variable is automatically set to false. It is used so that once your animation has finished animating your animation will start again. This can be stopped by setting it to false. Example:

myAnim.loop = true;
myAnim.loop = false;

II. Makes accessing elements easy

To access elements on your webpage easily, you can use the _("idornamehere") function. This accesses an element no matter what kind of browser your user uses. This also makes your code compatible With five (5) main browsers: Netscape, Internet Explorer, Firefox, Opera, and Safari. An example is shown here:

<head>
<script type="text/javascript">
<!--
_("indy").value = "cool";
-->
</script>
</head>
<body>
<input type="text" id="indy">
</body>

It accesses your element and leaves the rest to you for manipulating the element you wish for.

III. Makes handling strings easier

To handle strings easier, there are three (3) functions you can use.

There are three (3) string handler functions:
1. Concatenate();
2. Shift(txt);
3. Unshift(txt);

Functions:

1. Concatenate();

To use the Concatenate() function, enter any number of parameters that are strings in between the parinthesis. It will then concatenate the strings and return them as a whole. Remember to seperate the strings by commas. Example:

alert(Concatenate('This,',' this,',' and',' this','.')); // emits "This, this, and this."

2. Shift(txt);

To use the Shift(txt) function, enter some text as a parameter. It will then capatilize all of your text and return it as a string. This is the exact opposite of Unshift(txt). Example:

alert(Shift('this')); // emits "THIS"

3. Unshift(txt);

To use the Unshift(txt) function, enter some text as a parameter. It will then de-capitalize all of your text and return it as a string. This is the exact opposite of Shift(txt). Example:

alert(Unshift('THIS')); // emits "this"

IV. Makes cookie functions easier

To make cookie functions easier, there are two (2) functions you can use.

There are two (2) cookie functions:
1. getCookie(name);
2. setCookie();

Functions:

1. getCookie(name);

To use the getCookie(name) function, enter the name of a document cookie as the parameter. This will then return the cookie's value. Example:

getCookie('myCook');

2. setCookie();

To use the setCookie() function, enter, in this order: name, value, expiration, path, domain, secure;, the name of the cookie, the value of the cookie, the expiration date of the cookie, the path of the cookie, the domain of the cookie, and if the cookie is secure or not (true, false). You may leave any of these parameters blank and there will be no error flagged. This will set a cookie with the information. To delete a cookie, set the expiration date before the current time. Example:

var expdate = new Date();
expdate.setTime(expdate.getTime() + (24 * 60 * 60 * 1000 * 31));
setCookie("myCook","myVal",expdate,"yourpath","domain(s)eaccessableby",true);

This is the end of the Jasoop Toolbox Tutorial. Questions or comments? E-mail the author at:

magicyte@gmail.com

If anyone has new comments, questions, or code changes, let me know and post 'em. Also, this code is allowed to be changed. :)

-magicyte

Twey
10-13-2008, 08:31 PM
Capital letters are reserved for constructors and namespacing objects, by convention. Your indentation is messed up again.

One of the biggest issues with having a function like your _() is that it encourages excessive use, like this:
_(el).style.position="absolute";
_(el).style.left=x;
_(el).style.top=y;A document.getElementById() lookup is expensive. You definitely oughtn't do a series of redundant lookups in a row like that, and you should not, if you can avoid it, be passing IDs around at all — it's much better to pass a reference to the element itself (the exception being in order to avoid memory leaks in certain situations). Also, no browser worth targeting these days fails to implement document.getElementById().

And once again, all your methods have gone back into the constructor, so we've got them being redundantly recreated again. I do hate being ignored.

magicyte
10-13-2008, 08:59 PM
You aren't being ignored. I have actually used your example for my ACTUAL toolbox that is CONFIDENTIAL. I was posting this changed code to the best of my programming ability. No, I was NOT ignoring you AT ALL. I thanked you many times. Trust me, I wasn't ignoring you... :) I get what you're saying: prototype them in. I will. :)

Well, I have modified my code. I don't know if it is valid, though. :D Haven't tested it yet...

What you said about _(): Could you explain a bit more? I didn't quite understand "expensive" thuroughly and completely, nor "reference". Thank you for time and effort.

IMPORTANT!!!:::!!!:::
Hey: The new code I posted is my creation. I am experimenting with it. I AM MOST DEFINATELY NOT ABUSING NOR NEGLETING YOUR CODE. I am using it as a guideline to create my own code. Thank you for it!!

-magicyte

Twey
10-13-2008, 09:58 PM
I don't mean that you should have copy/pasted my code verbatim, but you don't seem to have integrated any of the improvements I suggested.
What you said about _(): Could you explain a bit more? I didn't quite understand "expensive" thuroughly and completely, nor "reference". Thank you for time and effort.'Expensive', in terms of computing, means 'uses a significant amount of resources and should be avoided where possible'. A 'reference' is a variable that points to something — in C terms, a pointer, but handled a little differently. C++ has actual references.
var a = {}; // a is a reference to this new object we've just created.
var b = a; // b is now a reference to that same object.
b.c = 5; // Now that object looks like this: {c: 5}
a.c; // 5 — because a is a reference to the same object.

var d = document.getElementById("foo");
// Now d is a reference to the DOM node with ID 'foo'.
var e = document.getElementById("foo");
// Now e is also a reference to that same DOM node, but getElementById() had to
// go all through the document to find that node again, since it had only the ID to go on.
// This costs quite a lot in terms of CPU time and memory.
var f = e;
// now f is a reference to the same DOM node as d and e, but this was done much more
// cheaply. This statement will execute many times faster and with less memory usage.

magicyte
10-14-2008, 12:33 AM
Yeah. I understand C references and pointers, and apparently NOW I understand JavaScript references and pointers!! Whoopee!! I've always wanted to know this.

Don't worry: I am getting to it for your suggestions! :) Thank you for e'rything.

-magicyte

magicyte
10-14-2008, 09:50 PM
Alas: I finally used prototype. Check it out.

I am happy that is saves memory!!

-magicyte

magicyte
10-14-2008, 09:58 PM
/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label is to stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

// Start Jasoop Toolbox

var _ = function (el) {
if(document.getElementById()) return document.getElementById(el);
else if(document.all) return document.all[el];
else if(document.layers) return document.layers[el];
else return false;
};

var Concatenate = function (/*string arguments*/) {
var argv = arguments;
var argc = arguments.length;
var string;
string="";
for(x=0;x<argc;x++) {
string=string+argv[x];
}
return string;
};

var Shift = function (txt) {
var argv = txt;
var argc = txt.length;
var string;
string=argv.toUpperCase();
return string;
};

var Unshift = function (txt) {
var argv = txt;
var argc = txt.length;
var string;
string=argv.toLowerCase();
return string;
};

var getCookie = function (name) {
var argv = name + "=";
var argc = argv.length;
var clen = document.cookie.length;
var x = 0;
while (x < clen) {
var y = x + argc;
if(document.cookie.substring(x,y)==argv)
var e = document.cookie.indexOf(";",y);
if(e==-1)
e=document.cookie.length;
return unescape(document.cookie.substring(y,e));
x = document.cookie.indexOf(" ",x)+1;
if(x==0) break;
}
return null;
};

var setCookie = function () {
var argv = arguments;
var argc = arguments.length;
var name = (argc > 0) ? argv[0] : null;
var value = (argc > 1) ? argv[1] : null;
var expires = (argc > 2) ? argv[2] : null;
var path = (argc > 3) ? argv[3] : null;
var domain = (argc > 4) ? argv[4] : null;
var secure = (argc > 5) ? argv[5] : false;
document.cookie = ((name == null) ? "" : (name)) + "=" + ((value == null) ? "" : (escape(value))) + ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) + ((path == null) ? "" : ("; path=" + path)) + ((domain == null) ? "" : ("; domain=" + domain)) + ((secure == true) ? "; secure" : "");
};

var Animation = function (el) {
animation = this; // dangerous ?? should be var ?? won't work with var...
this.element = el;
this.x = [];
this.y = [];
this.delay = [];
this.ac = 0;
this.lc = 0;
this.pause = false;
this.autodelete = false;
this.loop = false;
};

Animation.prototype.moveTo = function (x,y) {
_(this.element).style.position="absolute"; // must make reference - tried but won't work...
_(this.element).style.left=(x+"px"); // must make reference - tried but won't work...
_(this.element).style.top=(y+"px"); // must make reference - tried but won't work...
};

Animation.prototype.start = function () {
if(!this.pause)
{
if(this.ac<this.lc)
{
this.moveTo(this.x[this.ac],this.y[this.ac]);
this.ac++;
setTimeout(function(){animation.start()},this.delay[this.ac]);
}
else if(this.ac>=this.lc)
{
(this.autodelete) ? this.reset() : this.ac=0;
(this.loop && !this.autodelete) ? this.start() : "";
}
}
else if(this.pause)
{
this.pause = !this.pause;
}
};


Animation.prototype.stop = function () {
this.pause = true;
};

Animation.prototype.compute = function (l,t,d) {
this.x[this.lc]=l;
this.y[this.lc]=t;
this.delay[this.lc]=d;
this.lc++;
};


Animation.prototype.reset = function() {
for(i=0;i<=this.ac;i++)
{
this.x[i]=0;
this.y[i]=0;
this.delay[i]=0;
}
this.lc=0;
this.ac=0;
};

// End Jasoop Toolbox

/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label is to stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

Twey
10-14-2008, 11:34 PM
var Concatenate = function (/*string arguments*/) {
var argv = arguments;
var argc = arguments.length;
var string;
string="";
for(x=0;x<argc;x++) {
string=string+argv[x];
}
return string;
};

var Shift = function (txt) {
var argv = txt;
var argc = txt.length;
var string;
string=argv.toUpperCase();
return string;
};

var Unshift = function (txt) {
var argv = txt;
var argc = txt.length;
var string;
string=argv.toLowerCase();
return string;
};
Where is the indentation here? Additionally, why do you keep renaming arguments to argv? It seems quite pointless, especially when it doesn't even behave like a C argv. Also, these functions are very redundant, and have capital names, something which, as I stated before, is reserved for constructors and namespaces.
function concatenate() {
return Array.prototype.join.call(arguments, "");
}

function shift(s) {
return s.toUpperCase();
}

function unshift(s) {
return s.toLowerCase();
}They are not worth making into new functions (since they're all only one expression each anyway, none of them particularly complex) and by doing so, you lose the organisation provided by the original functions on the appropriate prototypes (concatenate() excepted) and also provide new, confusing names: shift() and unshift() in most people's minds refer to adding an element to or removing an element from the beginning of a data-structure. See, for example, Array.prototype.shift() and Array.prototype.unshift(), Perl's shift function, or the term 'bit-shifting' (operators such as >>, <<, and >>>).
var setCookie = function () {
var argv = arguments;
var argc = arguments.length;
var name = (argc > 0) ? argv[0] : null;
var value = (argc > 1) ? argv[1] : null;
var expires = (argc > 2) ? argv[2] : null;
var path = (argc > 3) ? argv[3] : null;
var domain = (argc > 4) ? argv[4] : null;
var secure = (argc > 5) ? argv[5] : false;
document.cookie = ((name == null) ? "" : (name)) + "=" + ((value == null) ? "" : (escape(value))) + ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) + ((path == null) ? "" : ("; path=" + path)) + ((domain == null) ? "" : ("; domain=" + domain)) + ((secure == true) ? "; secure" : "");
};This isn't C. There are easier ways. There is also sane code formatting, a boon for which I thank the gods every time I look upon a piece of code that doesn't have it...
function setCookie(name, value, expires, path, domain, secure) {
name = escapeURIComponent(name || "");
value = escapeURIComponent(value || "");
expires = expires ? "; expires=" + expires.toGMTString() : "";
path = path ? "; path=" + path : "";
domain = domain ? "; domain=" + domain : "";
secure = secure ? "; secure" : "";

document.cookie = name + "=" + value + expires + path + domain + secure;
};Look, readability!
var getCookie = function (name) {
var argv = name + "=";
var argc = argv.length;
var clen = document.cookie.length;
var x = 0;
while (x < clen) {
var y = x + argc;
if(document.cookie.substring(x,y)==argv)
var e = document.cookie.indexOf(";",y);
if(e==-1)
e=document.cookie.length;
return unescape(document.cookie.substring(y,e));
x = document.cookie.indexOf(" ",x)+1;
if(x==0) break;
}
return null;
};Er... or, alternatively:
function getCookie(name) {
name = decodeURIComponent(name) + "=";

var c = document.cookie,
idx = c.indexOf(name) + name.length,
si = c.indexOf(";", idx);

c = c.substr(idx);

return decodeURIComponent(si > -1 ? c.substr(0, si) : c);
}The original setCookie() is a perfect example of irregular indentation. Why is some of it indented properly and some not? Also, why are all these functions global? Put things in namespaces! It helps keep the global namespace clean and drastically and automatically improve compatibility with other scripts, something I would think is rather vital for a 'toolbox'.
animation = this; // dangerous ?? should be var ?? won't work with var...Not only dangerous: it effectively limits your object to one instance per page, and is completely redundant anyway. You can refer to this object with 'this' from any prototype function, presuming it's called correctly. If you'd gone through the code I posted earlier, you'd have realised this.
Animation.prototype.moveTo = function (x,y) {
_(this.element).style.position="absolute"; // must make reference - tried but won't work...
_(this.element).style.left=(x+"px"); // must make reference - tried but won't work...
_(this.element).style.top=(y+"px"); // must make reference - tried but won't work...
};Well, the 'dumb' way would be:
Animation.prototype.moveTo = function(x, y) {
var s = _(this.element).style;
s.position = "absolute";
s.left = x + "px";
s.top = y + "px";
};However, this still does the lookup once every time that function is called, which isn't necessary. There's only one element per Animation, so you might as well attach the element reference to the Animation object directly — again, as I did in my earlier code.

You've also still got the parallel arrays design going on, which makes your code needlessly complex and inefficient in several places.

I didn't post an analysis of your code and an example of how to do it better just for fun: I had hoped you would read through it and incorporate the ideas into your code.

P.S.: A minor point in comparison to all the others, but the convention in C-syntax code is to put spaces before brackets after keywords, but not between function/method calls and their brackets: you seem to have this backwards. Arguments should be separated with spaces as well as commas. In C/C++, the dominant style is to place opening braces on separate lines for several constructs. In Javascript, Java-style is dominant: the opening brace goes on the same line as the keyword and options.

magicyte
10-15-2008, 01:54 AM
Thank you.

-magicyte

magicyte
10-28-2008, 10:15 PM
/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label is to stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

// Start Jasoop Toolbox

var _ = function(el) {
if (document.getElementById()) return document.getElementById(el);
else if (document.all) return document.all[el];
else if (document.layers) return document.layers[el];
else return false;
};

var Concatenate = function() {
var string = '';
for (x = 0; x < arguments.length; x++) {
string = string + arguments[x];
}
return string;
};

var clock = Date.now || // inspired by MooTools
function() {
return new Date().getTime();
};

/* // CAUTION
var delay = function(statement, delay) {
var start, end, loop;
start = clock();
end = (start + delay);
do {
loop = clock();
} while ( loop < end );
return setTimeout(statement, 0);
};
*/

var Animation = function(el) {
this.element = el;
this.x = [];
this.y = [];
this.delay = [];
this.ac = 0;
this.lc = 0;
this.pause = false;
this.autodelete = false;
this.loop = false;
};

Animation.prototype.moveTo = function(x, y) {
document.getElementById(this.element).style.position = "absolute";
document.getElementById(this.element).style.left = (x + "px");
document.getElementById(this.element).style.top = (y + "px");
};

Animation.prototype.start = function() {
if (!this.pause) {
if (this.ac < this.lc) {
this.moveTo(this.x[this.ac], this.y[this.ac]);
this.ac++;
setTimeout((function(animation) {
return function() {
animation.start();
};
})(this), this.delay[this.ac]);
}
else if (this.ac >= this.lc) { (this.autodelete) ? this.reset() : this.ac = 0; (this.loop && !this.autodelete) ? this.start() : ""; // used from Twey - LOVE IT!!
}
}
else if (this.pause) {
this.pause = !this.pause;
}
};

Animation.prototype.stop = function() {
this.pause = true;
};

Animation.prototype.compute = function(l, t, d) {
this.x[this.lc] = l;
this.y[this.lc] = t;
this.delay[this.lc] = d;
this.lc++;
};

Animation.prototype.reset = function() {
for (i = 0; i <= this.ac; i++) {
this.x = [];
this.y = [];
this.delay = [];
}
this.lc = 0;
this.ac = 0;
};

// End Jasoop Toolbox

/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label is to stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/


Best I've come so far.

-magicyte

Twey
10-28-2008, 10:42 PM
OK, we seem to have reasonable formatting. How about implementing some of the suggestions I made? :)
var delay = function(statement, delay) {
var start, end, loop;
start = clock();
end = (start + delay);
do {
loop = clock();
} while ( loop < end );
return setTimeout(statement, 0);
};Never, ever do this. It will result in the entire browser hanging, including the UI.

magicyte
11-01-2008, 03:33 AM
OK, we seem to have reasonable formatting.

Aye, aye, capn'! But I cheated. Used Online JavaScript Beautifier. I am still learning from everything you posted and WILL, repeat WILL implement the suggestions you made.


Never, ever do this. It will result in the entire browser hanging, including the UI.

Aw, shoot!! 2 questions/comments:

1. What is the 'UI'?

2. I understand why I shouldn't do it. The user may have a slow browser OR the loop the user made may, in fact, be too long for the browser to handle and yet stay 'in', you know, 'alive' and 'well'. In fact, I used it in C++ as a delay function using time.h. In this case, could I use John Scheuer's idea of timeout vagaries as seen in the thread? Of course I'd have to ask for permission first, but I just want the client-side script to loop on time, 'no matter what' (<- I exaggerate this).

Thank you for your kind contribution and time.

-magicyte

magicyte
11-04-2008, 09:50 PM
Nevermind. Here. I have formatted and changed the Jasoop Toolbox Code to the BEST of my ability. I really want lots of people to use and manipulate it.

Here it is:

jasoop.js


/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for legal usage of this document. */
/********** - IMPORTANT LABEL - **********/

// Start Jasoop Toolbox

var _ = function(el) {
if (document.getElementById()) return document.getElementById(el);
else if (document.all) return document.all[el];
else if (document.layers) return document.layers[el];
else return false;
};

var Animation = function() {
function Animation(el) {
// private variables - are these possible in JavaScript?
this.x = [];
this.y = [];
this.delay = [];
this.ac = 0;
// public variables - are these possible in JavaScript?
this.pause = false;
this.autodelete = false;
this.loop = false;
this.element = el;
}

Animation.prototype = {
moveTo: function(x, y) {
document.getElementById(this.element).style.position = "absolute";
document.getElementById(this.element).style.left = (x + "px");
document.getElementById(this.element).style.top = (y + "px");
},

compute: function(l, t, d) {
this.x[this.x.length] = l;
this.y[this.y.length] = t;
this.delay[this.delay.length] = d;
},

start: function() {
if (!this.pause) {
if ((this.ac < this.x.length) && (this.ac < this.y.length) && (this.ac < this.delay.length)) {
this.moveTo(this.x[this.ac], this.y[this.ac]);
this.ac++;
setTimeout((function(animation){return function(){animation.start();};})(this), this.delay[this.ac]);
}
else if ((this.ac >= this.x.length) && (this.ac >= this.y.length) && (this.ac >= this.delay.length)) { (this.autodelete) ? this.reset() : this.ac = 0; (this.loop && !this.autodelete) ? this.start() : "";
}
}
else if (this.pause) {
this.pause = !this.pause;
}
},

stop: function() {
this.pause = true;
},

reset: function() {
this.ac = 0;
this.x = [];
this.y = [];
this.delay = [];
}

};

return Animation;
} ();

// End Jasoop Toolbox

/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for legal usage of this document. */
/********** - IMPORTANT LABEL - **********/

My Big Ol' List O' Things: Questions and Advancements

--I want some varaibles in my Animation to be private to the users and some to be public to the users. For example, I don't want the user to jack up the x, y, or delay arrays and kill the thing, nor do I want the user to jack up the ac variable. However, he can manipulate the rest. Please help me on this. Is this even possible to make public, private, or protected variables in JavaScript?

The best I've come so far. Thanks for everything Twey. :).

-magicyte

Trinithis
11-05-2008, 09:30 AM
UI = User Interface.

About the hanging issue... it has nothing to do with the user's computer being slow. It has to do with an infinite loop and the fact that javascript is single-threaded.

Twey
11-05-2008, 05:18 PM
A single thread that includes the whole browser.
2. I understand why I shouldn't do it. The user may have a slow browser OR the loop the user made may, in fact, be too long for the browser to handle and yet stay 'in', you know, 'alive' and 'well'. In fact, I used it in C++ as a delay function using time.h. In this case, could I use John Scheuer's idea of timeout vagaries as seen in the thread? Of course I'd have to ask for permission first, but I just want the client-side script to loop on time, 'no matter what' (<- I exaggerate this).But it's fundamentally useless. The point of setTimeout() is that the browser can do other things in the meantime. In this case, the browser can't do anything in the meantime, including basic things like painting — the browser will hang, and the OS will most likely notice this and try to kill it (or to kill the script, in the case of some browsers).


--I have added aliases to my Animation variable/prototype functions so that the programmer may use them with ease and understanding.Hooray, more redundancy. If the names aren't easy and comprehensible in the first place then change them, don't add redundant functions.
--I have added the ischeck(el) function to my 'toolbox', per se, so that it is easier to figure out if an element is checked.Which takes an element ID instead of a reference, making it slow, calls document.getElementById() twice, making it slower, has a daft name (if a checkbox is selected then it's 'checked', not 'check': 'check' is the American name for the mark placed in the box) and is fundamentally redundant, since if (foo) return true; else return bar; is equivalent to return !!foo;, or, in this case, since foo is already boolean, simply return foo;. If you write it properly, ischecked(foo) is equivalent to foo.checked, and is therefore a pointless reinvention of the wheel, along with much of the rest of this toolkit.
--I have kept the clock variable.... but why?
--I don't want to use Array.prototype.join.call(arguments, ""); on my Concatenate(); function.Again... why? What you're doing is pointless. 'I don't want to walk down the road to the house next door, I think I'm going to walk all around the block and come at it from the other side.' If you're just doing it to teach yourself then it kind of makes sense, but if you intend this code to be at all practical, it doesn't. Decide.
--I want some varaibles in my Animation to be private to the users and some to be public to the users. For example, I don't want the user to jack up the x, y, or delay arrays and kill the thing, nor do I want the user to jack up the ac variable. However, he can manipulate the rest. Please help me on this. Is this even possible to make public, private, or protected variables in JavaScript?Possible... sort of (that is, private and public members: protected members make no sense in Javascript). Advisable? No. There is a vast performance penalty associated with the method, and it lowers your users' control over your code, making it less useful.

magicyte, you haven't made even the most basic corrections I've suggested, like fixing the name of Concatenate or taking all these miscellaneous and redundant functions out of the global scope (and, preferably, out of the code entirely). How about doing something with the suggestions I've given you before asking for more? I feel like I'm wasting my time, and I'm almost certain that I'm going to end up forgetting that I've already suggested something and repeating myself.

magicyte
11-05-2008, 10:40 PM
I'm sorry. I was just making the thing to help me better understand OOP. I edited the thing again, and I have a very important thing to tell you. I use Internet Explorer 7 and when I try to make a reference for this.style = document.getElementById(el).style;, it says that there is an object error. The only way I can do it is with multiple document.getElementById(el)'s. Again, this is a simple experiment. Perhaps I should not have distributed this thing online.

-magicyte

Twey
11-06-2008, 04:08 PM
Well, I tested that, and IE7 doesn't mind one assigning a style object to a variable or property, so I must conclude that you're doing it incorrectly.

There's nothing wrong with getting tips on the code, but you really should have made it clearer that this code is not practical and not feasible for serious use.

magicyte
11-06-2008, 11:05 PM
but you really should have made it clearer that this code is not practical and not feasible for serious use

Yeah. Sorry I didn't tell you earlier. I actually did this in one of my objects:


this.style = document.getElementById(el).style;

I manipulated it in my object's code like this:


this.style.position = "absolute";

I got an error flagged like this:


Error: Line 30 character 2

Object required

I don't know what is wrong, and I swear I did everything correctly. Do you have any ideas? I wonder if it works in IE6... Would it? I accidentally said I used IE7 - This is the computer I'm using now. The computer I test it on is IE6. Here is the code I tried it in:


/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

// Start Jasoop Toolbox

var _element = function() {
if(document.getElementById()) return document.getElementById(el);
else if(document.all) return document.all[el];
else if(document.layers) return document.layers[el];
else return false;
};

var Effect = function() {
function Effect(el) {
// private variables
this.x = [];
this.y = [];
this.delay = [];
this.ac = 0;
// public variables
this.pause = false;
this.autodelete = false;
this.loop = false;
this.style = document.getElementById(el).style;
}

Effect.prototype = {

moveTo: function(x, y) {
this.style.position = "absolute";
this.style.left = (x + "px");
this.style.top = (y + "px");
},

compute: function(options) {
(options.left) ? this.x[this.x.length] = options.left : "";
(options.top) ? this.y[this.y.length] = options.top : "";
(options.delay) ? this.delay[this.delay.length] = options.delay : "";
},

start: function() {
if(!this.pause)
{
if((this.ac<this.x.length)&&(this.ac<this.y.length)&&(this.ac<this.delay.length))
{
this.moveTo(this.x[this.ac],this.y[this.ac]);
this.ac++;
setTimeout((function(animation){return function(){animation.start();};})(this),this.delay[this.ac]);
}
else
{
(this.autodelete) ? this.reset() : this.ac=0;
(this.loop && !this.autodelete) ? this.start() : "";
}
}
else if(this.pause)
{
this.pause = !this.pause;
}
},

stop: function() {
this.pause = true;
},

reset: function() {
this.x = [];
this.y = [];
this.delay = [];
this.ac = 0;
}

};

return Effect;
} ();

// End Jasoop Toolbox

/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

-magicyte

Jesdisciple
11-07-2008, 03:00 AM
Even if assigning the element's style property to a variable doesn't work, you can assign the element to the variable and access the property without the expensive ID lookup. See if this code fixes the IE6 problem... (I do something similar in every function I write which requires an element.)
this.element = document.getElementById(el);
this.element.style.position = "absolute";

magicyte
11-07-2008, 03:49 AM
Sorry, but this flags an error as well. I used this:


this.element = document.getElementById(el);

The error IE6 flags is:


Error: Line 36 character 13

Object required

Here is the code I tried it in:


/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

// Start Jasoop Toolbox

var _element = function() {
if(document.getElementById()) return document.getElementById(el);
else if(document.all) return document.all[el];
else if(document.layers) return document.layers[el];
else return false;
};

var Effect = function() {
function Effect(el) {
// private variables
this.x = [];
this.y = [];
this.delay = [];
this.ac = 0;
// public variables
this.pause = false;
this.autodelete = false;
this.loop = false;
this.element = document.getElementById(el);
}

Effect.prototype = {

moveTo: function(x, y) {
this.element.style.position = "absolute";
this.element.style.left = (x + "px");
this.element.style.top = (y + "px");
},

compute: function(options) {
(options.left) ? this.x[this.x.length] = options.left : "";
(options.top) ? this.y[this.y.length] = options.top : "";
(options.delay) ? this.delay[this.delay.length] = options.delay : "";
},

start: function() {
if(!this.pause)
{
if((this.ac<this.x.length)&&(this.ac<this.y.length)&&(this.ac<this.delay.length))
{
this.moveTo(this.x[this.ac],this.y[this.ac]);
this.ac++;
setTimeout((function(animation){return function(){animation.start();};})(this),this.delay[this.ac]);
}
else
{
(this.autodelete) ? this.reset() : this.ac=0;
(this.loop && !this.autodelete) ? this.start() : "";
}
}
else if(this.pause)
{
this.pause = !this.pause;
}
},

stop: function() {
this.pause = true;
},

reset: function() {
this.x = [];
this.y = [];
this.delay = [];
this.ac = 0;
}

};

return Effect;
} ();

// End Jasoop Toolbox

/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

Jesdisciple
11-07-2008, 04:05 AM
What are you using as an entry point? (In C terms, what's your main function?)

Jesdisciple
11-07-2008, 05:07 AM
Update: I found your problem (I think): document.getElementById is returning null; you then try to access a member of null, but only objects have members. You're wondering, of course, why does it return null?

document.getElementById only returns null when the page doesn't contain an element with a matching id. It contains nothing until the page is rendered. JS placed in the head executes before the page is rendered. (I can't know for certain that this is your problem because I don't have IE and my error doesn't look like yours.)

There are two ways to avoid this. The simpler, less common way is favored by Douglas Crockford (http://javascript.crockford.com/script.html), a JS guru whom I highly regard as my signature testifies.
<html>
<head>
<title>Titled Document</title>
</head>
<body>
First the page content, then the
<script type="text/javascript" src="script.js"></script>
</body>
</html>The more common way makes beginners think entry points can go directly in the head and, as the above link explains, prolongs the page's loading time. Folks who use this must be sure that references to the actual document aren't executed until the document either has loaded or, in special cases, is loading. (The "is loading" stuff must be called from script tags in the body.)
<html>
<head>
<title>Titled Document</title>
<script type="text/javascript" src="script.js">/*
// content of script.js
... a bunch of constructors, prototypes, and other stuff that doesn't
immediately require a document ...
window.onload = function(){
... your entry point ...
};
*/</script>
</head>
<body>
...
</body>
</html>

magicyte
11-07-2008, 11:21 PM
Great! It works! However, I NEED the script tag to be in the "head" tag for my experiment. Is this possible at all w/o interfering with the this.style variable? I would LOVE it to be.

-magicyte

Jesdisciple
11-07-2008, 11:36 PM
First, note that you can have script tags in both the head and the body.

However, to put everything in the head you only need to put your entry point in the window.onload function. The entry point is typically very small; if you need help isolating it, post the rest of your JS source (excluding the framework).

EDIT: I think I misunderstood your question. You can probably assign the style property to a variable without any problems now.

magicyte
11-07-2008, 11:48 PM
Here:


However, to put everything in the head you only need to put your entry point in the window.onload function. The entry point is typically very small; if you need help isolating it, post the rest of your JS source (excluding the framework).

Please. I don't get what you're trying to say.

jasoop.js [Framework I Made :: Edited it, so I had to include it, not exclude it]


/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

// Start Jasoop Toolbox

var _element = function() {
if(document.getElementById()) return document.getElementById(el);
else if(document.all) return document.all[el];
else if(document.layers) return document.layers[el];
else return false;
};

var Effect = function() {
function Effect(el) {
// private variables
this.x = [];
this.y = [];
this.delay = [];
this.bg = [];
this.ac = 0;
// public variables
this.pause = false;
this.autodelete = false;
this.loop = false;
this.style = document.getElementById(el).style;
}

Effect.prototype = {

moveTo: function(x, y) {
this.style.position = "absolute";
this.style.left = (x + "px");
this.style.top = (y + "px");
},

compute: function(options) {
(options.left) ? this.x[this.x.length] = options.left : "";
(options.top) ? this.y[this.y.length] = options.top : "";
(options.delay) ? this.delay[this.delay.length] = options.delay : "";
(options.bg) ? this.bg[this.bg.length] = options.bg : "";
},

start: function() {
if(!this.pause)
{
if((this.ac<this.x.length)&&(this.ac<this.y.length)&&(this.ac<this.delay.length))
{
this.moveTo(this.x[this.ac],this.y[this.ac]);
this.style.backgroundColor = this.bg[this.ac];
this.ac++;
setTimeout((function(animation){return function(){animation.start();};})(this),this.delay[this.ac]);
}
else
{
(this.autodelete) ? this.reset() : this.ac=0;
(this.loop && !this.autodelete) ? this.start() : "";
}
}
else if(this.pause)
{
this.pause = !this.pause;
}
},

stop: function() {
this.pause = true;
},

reset: function() {
this.x = [];
this.y = [];
this.delay = [];
this.ac = 0;
}

};

return Effect;
} ();

// End Jasoop Toolbox

/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

jasoop.html [HTML subject using Jasoop.js Framework I made]


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Jasoop Toolbox Experiment 01</title>
<style type="text/css">
</style>
</head>
<body>
<div onclick="myAnimation.start();" value="Jasoop Toolbox Experiment" id="animation" style="background:red;width:20px;height:20px;position:absolute;left:10;top:10;"></div>

<script type="text/javascript" src="jasoop.js"></script>
<script type="text/javascript">
var myAnimation = new Effect('animation');

myAnimation.loop = true;

for(i=10;i<570;i++) {
myAnimation.compute({
left:i,
top:10,
delay:10,
bg:"#FF0000"
});
myAnimation.compute({
left:i,
top:i,
delay:10,
bg:"#00FF00"
});
myAnimation.compute({
left:10,
top:i,
delay:10,
bg:"#0000FF"
});
}

for(i=570;i>10;i--) {
myAnimation.compute({
left:i,
top:10,
delay:10,
bg:"#0000FF"
});
myAnimation.compute({
left:i,
top:i,
delay:10,
bg:"#00FF00"
});
myAnimation.compute({
left:10,
top:i,
delay:10,
bg:"#FF0000"
});
}
</script>
</body>
</html>

In case you didn't know already, I made the framework.

-magicyte

Jesdisciple
11-08-2008, 01:02 AM
jasoop.js [Framework I Made :: ...]

jasoop.html [HTML subject using Jasoop.js Framework I made]

In case you didn't know already, I made the framework.... (emphasis adjusted) ... Have you ever heard the saying that the nail which sticks its head up gets hammered first?

Anyway, did you read the edit to my previous post? I think that might be what you were really asking.

Your entry point is currently the entire second script tag. If you wrap that JS in a function assigned to window.onload and put both script tags in the head, your experiment will be satisfied.

If you ever need to do something other than use the framework, you should move that code to another function and call both it and the other code from window.onload. That will keep your code neat and orderly.

magicyte
11-08-2008, 02:32 AM
No, I read your post. And, YES!! I FINALLY understand what you mean. However...

I tried this code out, but it doesn't work on my browser:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Jasoop Toolbox Experiment 01</title>
<script type="text/javascript" src="jasoop.js"></script>
<script type="text/javascript">
window.onload = function() {

var myAnimation = new Effect('animation');

myAnimation.loop = true;

for(i=10;i<570;i++) {
myAnimation.compute({
left:i,
top:10,
delay:10,
bg:"#FF0000"
});
myAnimation.compute({
left:i,
top:i,
delay:10,
bg:"#00FF00"
});
myAnimation.compute({
left:10,
top:i,
delay:10,
bg:"#0000FF"
});
}

for(i=570;i>10;i--) {
myAnimation.compute({
left:i,
top:10,
delay:10,
bg:"#0000FF"
});
myAnimation.compute({
left:i,
top:i,
delay:10,
bg:"#00FF00"
});
myAnimation.compute({
left:10,
top:i,
delay:10,
bg:"#FF0000"
});
}

};
</script>
<style type="text/css">
</style>
</head>
<body>
<div onclick="myAnimation.start();" value="Jasoop Toolbox Experiment" id="animation" style="background:red;width:20px;height:20px;position:absolute;left:10;top:10;"></div>
</body>
</html>

I also tried it the other way around, in the Jasoop include script tag. It gives an error message saying: "myAnimation undefined"

-magicyte

Jesdisciple
11-08-2008, 04:53 AM
That's because myAnimation is local to window.onload. We could just make it global, but I have a better idea: Let's avoid that poor practice and eliminate another - namely using inline event-handlers.

I modified your framework in two ways:
added the constructor property to Effect.prototype for type detection (useful for both debugging and special deployment cases);
added the element property to each Effect instance (so I can modify it).


I also moved the onclick handler to your entry point.

jasoop.js
/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

// Start Jasoop Toolbox

var _element = function() {
if(document.getElementById()) return document.getElementById(el);
else if(document.all) return document.all[el];
else if(document.layers) return document.layers[el];
else return false;
};

var Effect = function() {
function Effect(el) {
// private variables
this.x = [];
this.y = [];
this.delay = [];
this.bg = [];
this.ac = 0;
// public variables
this.element = document.getElementById(el);
this.pause = false;
this.autodelete = false;
this.loop = false;
this.style = this.element.style;
}

Effect.prototype = {
constructor: Effect,

moveTo: function(x, y) {
this.style.position = "absolute";
this.style.left = (x + "px");
this.style.top = (y + "px");
},

compute: function(options) {
(options.left) ? this.x[this.x.length] = options.left : "";
(options.top) ? this.y[this.y.length] = options.top : "";
(options.delay) ? this.delay[this.delay.length] = options.delay : "";
(options.bg) ? this.bg[this.bg.length] = options.bg : "";
},

start: function() {
if(!this.pause)
{
if((this.ac<this.x.length)&&(this.ac<this.y.length)&&(this.ac<this.delay.length))
{
this.moveTo(this.x[this.ac],this.y[this.ac]);
this.style.backgroundColor = this.bg[this.ac];
this.ac++;
setTimeout((function(animation){return function(){animation.start();};})(this),this.delay[this.ac]);
}
else
{
(this.autodelete) ? this.reset() : this.ac=0;
(this.loop && !this.autodelete) ? this.start() : "";
}
}
else if(this.pause)
{
this.pause = !this.pause;
}
},

stop: function() {
this.pause = true;
},

reset: function() {
this.x = [];
this.y = [];
this.delay = [];
this.ac = 0;
}

};

return Effect;
} ();

// End Jasoop Toolbox

/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

jasoop.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Jasoop Toolbox Experiment 01</title>
<script type="text/javascript" src="jasoop.js"></script>
<script type="text/javascript">
window.onload = function() {

var myAnimation = new Effect('animation');

myAnimation.element.onclick = function(){
myAnimation.start();
};
//Avoid a really nasty compatibility bug.
myAnimation.element.addEventListener('click', myAnimation.element.onclick, false);

myAnimation.loop = true;

for(i=10;i<570;i++) {
myAnimation.compute({
left:i,
top:10,
delay:10,
bg:"#FF0000"
});
myAnimation.compute({
left:i,
top:i,
delay:10,
bg:"#00FF00"
});
myAnimation.compute({
left:10,
top:i,
delay:10,
bg:"#0000FF"
});
}

for(i=570;i>10;i--) {
myAnimation.compute({
left:i,
top:10,
delay:10,
bg:"#0000FF"
});
myAnimation.compute({
left:i,
top:i,
delay:10,
bg:"#00FF00"
});
myAnimation.compute({
left:10,
top:i,
delay:10,
bg:"#FF0000"
});
}

};
</script>
<style type="text/css">
</style>
</head>
<body>
<div value="Jasoop Toolbox Experiment" id="animation" style="background:red;width:20px;height:20px;position:absolute;left:10;top:10;"></div>
</body>
</html>

magicyte
11-09-2008, 09:21 PM
Aye. Thanks for the help. Is there ANY possible way to have the user (particularly me) to execute the only code that they want without interference with the .style property of 'Effect'? The code should also be easy for the user to use without using any other functions to make it work. I appreciate the help, and I also agree with your 'constructor' part of the prototyping and the Effect.element part of Effect. It makes everything easier if the user were to use the stuff in the <head> section of the HTML document. Thanks! :)

-magicyte

Jesdisciple
11-10-2008, 12:51 AM
Sorry I took so long to respond; I've been wrestling with Firefox (http://forums.mozillazine.org/viewtopic.php?f=9&t=940905&p=4942315) over the whitespace in your entry point. I don't understand it; I didn't have that problem until I pasted your code from my post into a file and ran it.

While I was trying to figure what might be causing that problem, I validated your XHTML Transitional and ran into 3 errors. I won't post the resulting source because the errors are so few and, besides, that's a valuable learning experience.

But please indent your (X)HTML just like your JS from now on.


Aye. Thanks for the help. Is there ANY possible way to have the user (particularly me) to execute the only code that they want without interference with the .style property of 'Effect'? The code should also be easy for the user to use without using any other functions to make it work.I don't understand what you mean... What's "the only code that they want" or "interference with the .style property of 'Effect'"?


I appreciate the help, and I also agree with your 'constructor' part of the prototyping and the Effect.element part of Effect. It makes everything easier if the user were to use the stuff in the <head> section of the HTML document. Thanks! :)About that... I didn't like having such reusable code in the entry point, so here's a new function for your prototype:
on: function(action, response, capturing){
var listener = 'on' + action;
this.element[listener] = response;
var w3c = this.element.addEventListener;
var ie = this.element.attachEvent;
if(w3c){
w3c.call(this.element, action, response, !!capturing);
}else if(ie){
ie.call(this.element, listener, response);
}
}And here's the entry point call to replace the code I gave before:
myAnimation.on('click', function(){
myAnimation.start();
});Oh, and see http://www.quirksmode.org/js/events_advanced.html for some principles I used in the on method.

magicyte
11-10-2008, 04:16 AM
I don't understand what you mean... What's "the only code that they want" or "interference with the .style property of 'Effect'"?


I needed the user to have a normal entry point without having to using window.onload to build up their Effect() variable. (or anything else that requires manual handling of construction of the user's variable).

Thanks, and the above stuff doesn't matter anymore. That's all I need.

-magicyte

Jesdisciple
11-10-2008, 05:34 AM
One last thing... Would you like to submit your framework as a wiki script (http://javascript.wikia.com/wiki/Category:Wiki_scripts)? It would mean that anyone can remove any part of your source (including the important notice) without taking on any responsibilities.

magicyte
11-10-2008, 10:06 PM
I'd like for it to be seen, but I don't want anyone to edit it and call it their own. It really means something to mean 'cause it was my first ever 'important' project I handled. So, I don't really think so. Sorry. However, if people weren't allowed to edit it, I'd be just fine with posting it there.

-magicyte

Jesdisciple
11-10-2008, 11:11 PM
If you can host it yourself, I'll link to it. (Everything on the wiki itself must be licensed under the GFDL, which allows anyone to do anything to the content.)

BTW, you might want to apply a formal license to it, although I'm not sure what would work.

magicyte
11-11-2008, 12:05 AM
Well, I never thought anyone would like it. I wouldn't like people to edit it and place it back on the wiki so that everyone else sees it.

-magicyte

Jesdisciple
11-11-2008, 01:45 AM
Depending on how you license it, that wouldn't be allowed. Wikis (including the JavaScript Wiki, which I administrate) have a strict policy of disallowing any content not explicitly placed under a GFDL-compatible license by the author(s). Of course, folks could simply copy your source - but that's true for any publicly released JS library. The license dictates what's legal, but not what's possible.

But then again, I think you should examine your reasoning. Why do you not want anyone to modify your framework? The usual motive is profit, but that doesn't apply here. You seem to prefer never releasing your framework at all over fully releasing it. By fully releasing it you would benefit the JS community the most. By keeping it locked up forever you benefit no one - not even yourself.

magicyte
11-15-2008, 08:18 PM
Aww! The 'on' function gives an error in IE6, but it still works. I took it out of the 'toolbox' anyway:


/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

// Start Jasoop Toolbox

var _element = function(el) {
if(document.getElementById()) return document.getElementById(el);
else if(document.all) return document.all[el];
else if(document.layers) return document.layers[el];
else return false;
};

var Effect = function() {
function Effect(el) {
// 'privates'
this.x = [];
this.y = [];
this.z = [];
this.h = [];
this.w = [];
this.delay = [];
this.bg = [];
this.fg = [];
this.ac = 0;
this.lc = 0;
// 'publics'
this.pause = false;
this.autodelete = false;
this.loop = false;
this.visible = false;
this.element = _element(el);
this.style = this.element.style;
}

Effect.prototype = {
moveTo: function(x, y) {
this.style.position = "absolute";
this.style.left = (x + "px");
this.style.top = (y + "px");
},

toggle: function() {
if(!this.visible) {
this.style.display = "inline";
this.visible = true;
}
else {
this.style.display = "none";
this.visible = false;
}
},

compute: function(options) {
(options.delay != undefined) ? this.delay[this.lc] = options.delay : this.delay[this.lc] = 0;
(options.left != undefined) ? this.x[this.lc] = options.left : "";
(options.top != undefined) ? this.y[this.lc] = options.top : "";
(options.height != undefined) ? this.h[this.lc] = options.height : "";
(options.width != undefined) ? this.w[this.lc] = options.width : "";
(options.layer != undefined) ? this.z[this.lc] = options.layer : "";
(options.bgcolor != undefined) ? this.bg[this.lc] = options.bgcolor : "";
(options.fgcolor != undefined) ? this.fg[this.lc] = options.fgcolor : "";
this.lc++;
},

start: function() {
if(!this.pause)
{
if(this.ac<this.lc)
{
if(this.x[this.ac] != undefined) {
this.style.position = "absolute";
this.style.left = this.x[this.ac];
}
if(this.y[this.ac] != undefined) {
this.style.position = "absolute";
this.style.top = this.y[this.ac];
}
if(this.z[this.ac] != undefined) {
this.style.position = "absolute";
this.style.zIndex = this.z[this.ac];
}
(this.h[this.ac] != undefined) ? this.style.height = this.h[this.ac] : "";
(this.w[this.ac] != undefined) ? this.style.width = this.w[this.ac] : "";
(this.bg[this.ac] != undefined) ? this.style.backgroundColor = this.bg[this.ac] : "";
(this.fg[this.ac] != undefined) ? this.style.color = this.fg[this.ac] : "";
setTimeout((function(animation){return function(){animation.start();};})(this),this.delay[this.ac]);
this.ac++;
}
else
{
(this.autodelete) this.reset() : this.ac = 0;
(!this.autodelete) && (this.loop)) this.start() : "";
}
}
else
{
this.pause = false;
}
},

stop: function() {
this.pause = true;
},

reset: function() {
this.x = [];
this.y = [];
this.z = [];
this.h = [];
this.w = [];
this.delay = [];
this.bg = [];
this.fg = [];
this.ac = 0;
this.lc = 0;
},

constructor: Effect

};

return Effect;
} ();

// End Jasoop Toolbox

/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

There is redundancy in 'start()' and 'reset()', but I don't know how to reduce the code and save memory MORE... I do know what I should do, but don't know how to do it. I can make one variable that can hold others and it would reduce the amount of variables I use. Hmm...

-magicyte

Jesdisciple
11-15-2008, 08:29 PM
Do you mean the Effect constructor and reset?
function Effect(el) {
this.reset();

this.pause = false;
this.autodelete = false;
this.loop = false;
this.visible = false;
this.element = _element(el);
this.style = this.element.style;
}

Also, this second if is unnecessary (will never evaluate to false):
if(!this.pause)
...
else if(this.pause)
...

magicyte
11-15-2008, 08:33 PM
Well, I was talking about 'Effect'. It has too many 'style-of-the-element' variables-- my only problem. I want those to be in one variable. Also: Thanks for the 'else if' info.

-magicyte

Jesdisciple
11-15-2008, 08:38 PM
I'm confused... I was talking about Effect as well. But why/how do you think all those variables can be condensed into one?

magicyte
11-15-2008, 08:55 PM
Because I know it's possible. I'm sure I can make an empty 'object' variable with curly braces. When the user wants to use the compute function, it will add variables to the empty 'object' variable like this:


this.whatever = {};

this.whatever.newVar = 'sdfkjh';

The above code is kind of what I was visualizing. This way it saves memory for the actual toolbox and then uses memory that is only needed by the user. I just want to save memory.

-magicyte

Jesdisciple
11-16-2008, 10:42 PM
Any object does exactly what you're talking about, including this. Just remove all the empty (i.e., [] and 0) property assignments from your constructor. When those properties are used for the first time, they will be allocated just as they are currently when you set them empty. (What you were saying is valid but unnecessary, and actually uses insignificantly more memory than adding the properties to this because an extra object and identifier are involved.)

magicyte
11-20-2008, 10:42 PM
All right. Thanks for clarification! And about Douglas Crockford: you take classes from him, right? Where do you get classes from him? Just curious...:D

-magicyte

Jesdisciple
11-20-2008, 11:53 PM
Nah, I just read his articles and try to apply them in my own coding. For that reason, my code sometimes varies in style because I'm experimenting with his suggestions (and some of my own ideas).

Twey
11-21-2008, 05:14 AM
I find Crockford a bit wacky. He's a little too focussed on making Javascript more like Java. Eich seems to be drifting in that direction, too: the 'everybody knows classical and is confused by prototypical, so let's make JS classical' philosophy. If Javascript ends up being a classical language just so that they can pander to the Java-sedated CS grads, I will be disappointed — especially since, looking at the plans for JS2, they're going keep bits and pieces of the old system, merely exacerbating the problem. A language should not implement both OO styles: it isn't healthy, and they can't mix properly.

Jesdisciple
11-21-2008, 05:27 AM
I find that an odd critique of his work... He's the most prototypal author I know of, and that's why I selected him as my 'guru'. In particular, see Prototypal Inheritance (http://javascript.crockford.com/prototypal.html).

Twey
11-21-2008, 08:33 AM
I see he's finally seen the error of his ways: he's modified http://javascript.crockford.com/inheritance.html to talk about the disadvantages of using the method he describes, and put a note at the bottom saying that the original was a mistake. http://javascript.crockford.com/private.html is still up and disclaimer-free, though (the huge performance hit associated with this method, and the fact that it's never really necessary, should really be made very explicit).

<brag>Incidentally, I've been writing Javascript for as long as he has :p</brag>

magicyte
11-21-2008, 06:42 PM
Well, if Crockford isn't good, where do you think some good sites are about JavaScript?

<rephrase>What are some really good JavaScript tutorials/walkthroughs you have seen? Where may they be found?</rephrase>

I've always used W3Schools, though it isn't good. Suggestions?

-magicyte

Twey
11-21-2008, 07:38 PM
http://www.howtocreate.co.uk/ have a variety of tutorials on Web development. I highly recommend them. The information on the MDC (https://developer.mozilla.org/en/JavaScript) isn't half bad, either.

Don't misunderstand me, Crockford is a smart guy and has done some good work, much of which is an excellent reference. He shouldn't be followed blindly, however: he's not an authority on Javascript, merely a high-profile user.

magicyte
11-23-2008, 12:34 AM
Okay. Thanks. I think I'll stick with the three you mentioned.

(When you say 'blindly', what do you mean? With little knowledge?)

-magicyte

Jesdisciple
11-23-2008, 12:48 AM
Blind means unquestioning, and he probably objected to my post because I called Crockford my "guru" (wise teacher) without qualification. However, I do frequently question him; I take his writings as suggestions from a teacher wiser than me but still imperfect.

By the way, an unquestioning follower is necessarily ignorant (with little/no knowledge) of the issues. And given that the knowledge is within his grasp and his leader is not leading him to it, not questioning his leader prolongs his ignorance.

magicyte
11-23-2008, 12:57 AM
I do have yet another question: I've been to www.crockford.com, but where are the JavaScript classes located?

-magicyte

Jesdisciple
11-23-2008, 01:02 AM
They're not exactly classes, but they're in the right column. They're mostly opinion pieces, really.

magicyte
11-23-2008, 06:48 PM
All right! Many thanks!

-magicyte

magicyte
11-23-2008, 07:36 PM
New edition 1.2 (lol):

Version #1 (with new keyword in compute() [uses more memory]:


/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

// Start Jasoop Toolbox

var jasoop = {
name: "Jasoop Toolbox",
version: "1.2",
created: "2008",
lastmod: "8:06 PM 11/20/2008",
author: "Arthur Christopher Watkins"
};

var _element = function(el) {
if (document.getElementById()) return document.getElementById(el);
else if (document.all) return document.all[el];
else if (document.layers) return document.layers[el];
else return false;
};

var Effect = function() {
function Effect(el) {
this.privates = [];
this.durations = {
'short': 250,
'normal': 500,
'long': 1000
};
this.ac = 0;
this.pause = false;
this.autodelete = false;
this.loop = false;
this.visible = false;
this.element = _element(el);
this.style = this.element.style;
}

Effect.prototype = {
moveTo: function(x, y) {
this.style.position = "absolute";
this.style.left = (x + "px");
this.style.top = (y + "px");
},

toggle: function() {
if (!this.visible) {
this.style.display = "inline";
this.visible = true;
}
else {
this.style.display = "none";
this.visible = false;
}
},

compute: function(options) {
this.privates[this.privates.length] = new Entry((this.durations[options.delay] || options.delay),
options.left,
options.top,
options.height,
options.width,
options.layer,
options.bgcolor,
options.fgcolor
);
},

start: function() {
if (!this.pause) {
if (this.ac < this.privates.length) {
if (this.privates[this.ac].x != undefined) {
this.style.position = "absolute";
this.style.left = this.privates[this.ac].x;
}
if (this.privates[this.ac].y != undefined) {
this.style.position = "absolute";
this.style.top = this.privates[this.ac].y;
}
if (this.privates[this.ac].z != undefined) {
this.style.position = "absolute";
this.style.zIndex = this.privates[this.ac].z;
}
if (this.privates[this.ac].h != undefined) this.style.height = this.privates[this.ac].h;
if (this.privates[this.ac].w != undefined) this.style.width = this.privates[this.ac].w;
if (this.privates[this.ac].bg != undefined) this.style.backgroundColor = this.privates[this.ac].bg;
if (this.privates[this.ac].fg != undefined) this.style.color = this.privates[this.ac].fg;
setTimeout((function(effect) {
return function() {
effect.start();
};
})(this), this.privates[this.ac].delay);
this.ac++;
}
else {
if (this.autodelete) this.reset();
else this.ac = 0;
if ((!this.autodelete) && (this.loop)) this.start();
}
}
else {
this.pause = false;
}
},

stop: function() {
this.pause = true;
},

reset: function() {
this.privates = [];
this.ac = 0;
},

on: function(ev, response, capturing) {
var listener = ("on" + ev);
var w3c = this.element.addEventListener;
var ie = this.element.attachEvent;
this.element[listener] = response;
if (w3c) {
w3c.call(this.element, listener, response, !!capturing);
}
else if (ie) {
ie.call(this.element, listener, response);
}
},

constructor: Effect

};

function Entry(d, x, y, h, w, z, b, f) {
this.x = x;
this.y = y;
this.h = h;
this.w = w;
this.z = z;
this.bg = b;
this.fg = f;
this.delay = d || 0;
}

return Effect;
} ();

// End Jasoop Toolbox

/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

Continued (wouldn't fit in one whole post...)

magicyte
11-23-2008, 09:52 PM
Version #2 (without new keyword in compute() [saves memory]):


/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

// Start Jasoop Toolbox

var jasoop = {
name: "Jasoop Toolbox",
version: "1.2",
created: "2008",
lastmod: "8:06 PM 11/20/2008",
author: "Arthur Christopher Watkins"
};

var _element = function(el) {
if (document.getElementById()) return document.getElementById(el);
else if (document.all) return document.all[el];
else if (document.layers) return document.layers[el];
else return false;
};

var Effect = function() {
function Effect(el) {
this.privates = [];
this.durations = {
'short': 250,
'normal': 500,
'long': 1000
};
this.ac = 0;
this.pause = false;
this.autodelete = false;
this.loop = false;
this.visible = false;
this.element = _element(el);
this.style = this.element.style;
}

Effect.prototype = {
moveTo: function(x, y) {
this.style.position = "absolute";
this.style.left = (x + "px");
this.style.top = (y + "px");
},

toggle: function() {
if (!this.visible) {
this.style.display = "inline";
this.visible = true;
}
else {
this.style.display = "none";
this.visible = false;
}
},

compute: function(options) {
this.privates[this.privates.length].delay = this.durations[options.delay] || options.delay);
this.privates[this.privates.length].x = options.left;
this.privates[this.privates.length].y = options.top;
this.privates[this.privates.length].h = options.height;
this.privates[this.privates.length].w = options.width;
this.privates[this.privates.length].z = options.layer;
this.privates[this.privates.length].bg = options.bgcolor;
this.privates[this.privates.length].fg = options.fgcolor;
},

start: function() {
if (!this.pause) {
if (this.ac < this.privates.length) {
if (this.privates[this.ac].x != undefined) {
this.style.position = "absolute";
this.style.left = this.privates[this.ac].x;
}
if (this.privates[this.ac].y != undefined) {
this.style.position = "absolute";
this.style.top = this.privates[this.ac].y;
}
if (this.privates[this.ac].z != undefined) {
this.style.position = "absolute";
this.style.zIndex = this.privates[this.ac].z;
}
if (this.privates[this.ac].h != undefined) this.style.height = this.privates[this.ac].h;
if (this.privates[this.ac].w != undefined) this.style.width = this.privates[this.ac].w;
if (this.privates[this.ac].bg != undefined) this.style.backgroundColor = this.privates[this.ac].bg;
if (this.privates[this.ac].fg != undefined) this.style.color = this.privates[this.ac].fg;
setTimeout((function(effect) {
return function() {
effect.start();
};
})(this), this.privates[this.ac].delay);
this.ac++;
}
else {
if (this.autodelete) this.reset();
else this.ac = 0;
if ((!this.autodelete) && (this.loop)) this.start();
}
}
else {
this.pause = false;
}
},

stop: function() {
this.pause = true;
},

reset: function() {
this.privates = [];
this.ac = 0;
},

on: function(ev, response, capturing) {
var listener = ("on" + ev);
var w3c = this.element.addEventListener;
var ie = this.element.attachEvent;
this.element[listener] = response;
if (w3c) {
w3c.call(this.element, listener, response, !!capturing);
}
else if (ie) {
ie.call(this.element, listener, response);
}
},

constructor: Effect

};

return Effect;
} ();

// End Jasoop Toolbox

/********** - IMPORTANT LABEL - **********/
/* Title: Jasoop Toolbox */
/* Name: jasoop.js */
/* Author: 2008 Arthur C. Watkins */
/* Notice: This label must stay intact */
/* for usage of this document. */
/********** - IMPORTANT LABEL - **********/

Any problems which I know exist, yet I cannot interpret nor possibly find them? :D

-magicyte

Jesdisciple
11-23-2008, 10:48 PM
Why do you assign an anonymous function rather than declaring it in the ordinary manner?
var _element = function(el) {
if (document.getElementById()) return document.getElementById(el);
else if (document.all) return document.all[el];
else if (document.layers) return document.layers[el];
else return false;
};Anonymous functions aren't quite as preferable, although they are necessary in some cases. A web search might reveal more reasons, but the only one I know is that a named function is defined throughout its scope (at compile-time), while the above construct only defines _element at the point of assignment. That's why this is legal and logical:
foo();
function foo(){
//...
}

This post is mostly just for the sake of responding and letting you know I'm still interested. I'm rather busy with other issues right now, but I do intend to keep helping you.

magicyte
11-24-2008, 10:57 PM
Post Summary: I lost you when you first said 'anonymous functions'. This diminished my understanding of the rest...:o hehe...

Post [Beware of misunderstandings I make...]:

'_element' is for the users...

I don't quite understand what you mean by 'anonymous' functions. Maybe you think this was for the 'Effect' object. It is actually created for the users and I just happened to use it in 'Effect' for full compat('i' || 'a')bility w/ other browsers. Could you now explain with this in mind, even though it may not enhance my knowledge considering I may be wrong thinking that you think '_element' is supposed to be a part of 'Effect'? (<- phew! *takes breath*) I do kind of get the 'second code' you posted. I've used it in prototyping in C/C++. What does this do in JavaScript?

-magicyte

Jesdisciple
11-25-2008, 01:08 AM
Anonymous = with no name; see the syntax details for functions (http://javascript.wikia.com/wiki/Function). (That's a fairly low-information page... I would appreciate any questions whose answers would help it - or any page, for that matter.)

In this case, there is no practical difference (that I know of) between the two syntaxes, because the only time you call the function is below its assignment. I just think it's a good habit to declare functions in the ordinary manner.

BTW, where did you read that constructors are expensive? Either I've never heard that or I forgot it (probably the latter).

magicyte
12-26-2008, 08:31 PM
This is the newest version of Jasoop:

jasoop.js


var Effect = function() {
var durations = {
"very fast": 50,
"fast": 100,
"normal": 250,
"slow": 500,
"very slow": 1000
},
styles = [],
counter = 0,
toggled = false,
fader = setTimeout(function() {
return false;
},
10);
function Effect(el) {
this.element = document.getElementById(el);
this.style = this.element.style;
this.visible = true;
this.opacity = 100;
this.autodelete = false;
this.loop = false;
this.pause = false;
}
Effect.prototype = {
move: function(x, y) {
this.style.position = "absolute";
this.style.left = x + "px";
this.style.top = y + "px";
},
toggle: function() {
if (this.style.display == "none") {
this.style.display = "block";
this.visible = true;
} else {
this.style.display = "none";
this.visible = false;
}
},
fade: function(inc, dur) {
if (inc < 0 || inc > 0) { // to make
} else { // to make
}
},
compute: function(options, dur) {
options = options.replace(/ /g, "");
var ss = options.split(",");
var privates = {};
for (var i = 0; i < ss.length; ++i) {
var s = ss[i].split(":");
privates[s[0]] = [s[0], s[1]];
}
privates.delay = dur;
styles.push(privates);
},
start: function() {
if (!this.pause) {
if (counter < styles.length) {
for (var i in styles[counter]) {
this.style[styles[counter][i][0]] = styles[counter][i][1];
}
setTimeout((function(effect) {
return function() {
effect.start();
};
})(this), (typeof styles[counter].delay == "string") ? durations[styles[counter].delay] : styles[counter].delay);
counter++;
} else {
if (this.autodelete) this.reset();
else counter = 0;
if (!this.autodelete && this.loop) this.start();
}
} else {
this.pause = false;
}
},
stop: function() {
this.pause = true;
},
reset: function() {
styles = [];
counter = 0;
},
addEvent: function(ev, response) {
if (this.element.addEventListener) this.element.addEventListener(ev, response, false);
else if (this.element.attachEvent) {
var res = function() {
response.apply(this.element);
};
this.element.attachEvent("on" + ev, res);
} else this.element["on" + ev] = response;
},
addEvents: function(evs, response) {
for (var i = 0; i < evs.length; ++i) this.addEvent(evs[i], response);
},
constructor: Effect
};
return Effect;
} ();

Please report any errors, comments, and suggestions to magicyte (http://www.dynamicdrive.com/forums/member.php?u=31099). All is appreciated.

Jesdisciple
12-26-2008, 09:27 PM
You can condense addEvent and addEvents into a single function by wrapping the single arguments in arrays:
if(typeof argument !== 'array')
argument = [argument];
//Proceed with the plural function after checking that the arrays have the same length.

Any questions? I'm better at answering than at finding problems.

magicyte
12-26-2008, 10:08 PM
I do have some questions:

1. When, in the toggle function, I see if this.style.display == 'none', could it be this.style.display === 'none'? If so, which is better (recommended)?

2. I don't understand what you are trying to say. Could you implement the function into that excerpt of Jasoop to let me see what you mean? I implemented what I thought you meant in my code, so let me know if it is incorrect.

Also, what do you think of the way I made the constructor possible to hold a document.getElementsByTagName()[]? I like the convenience, but how about you? Also, the fade function. Any comments on that? Feedback, no matter how it is displayed, even as criticism, is valuable. :)

Jesdisciple
12-27-2008, 12:41 AM
1. When, in the toggle function, I see if this.style.display == 'none', could it be this.style.display === 'none'? If so, which is better (recommended)?I'm not sure what the majority/consensus says, but I currently apply Crockford's advice: Only use loose comparisons (== and !=) when they offer added value/efficiency to your program. So if you have a function with an optional Boolean argument which defaults to false (actually undefined, which is falsy), this is appropriate (and roughly equivalent to a loose comparison with true):
if(argument)
//...This doesn't really matter for CSS properties, because they're always strings and a loose comparison of strings might as well be strict.
document.body.style.display = {};
alert(typeof document.body.style.display);


Also, what do you think of the way I made the constructor possible to hold a document.getElementsByTagName()[]? I like the convenience, but how about you?It's not very flexible. If I want to make an effect on a certain element out of the middle of several similar ones, I don't want to count them just so I can use my framework. If an element is important enough to have a behavior, I'll usually just give it an ID. Then I make the relevant function take either the element or the ID.

Also, let's say I have a type of element, like a draggable widget, and several elements of that type on the same page. Each widget contains several elements, mostly divs and spans, but the markup is consistent. This is a good example of my primary use for getElementsByTagName, which is the only element-finding method available on elements. Even though Jasoop uses this method (or rather, a method by the same name with similar functionality), it wouldn't support this usage and I would have to implement it myself.


Also, the fade function.You should condense the first two arguments (and the increase/decrease variables) into one and add an optional Boolean "toggle" which ignores the sign (inc = Math.abs(inc)). This will almost halve the function's length.

"del" doesn't seem like a very descriptive name to me... I read it as "delete," but it's a length/duration. (I see you picked up on the short-circuit OR. :))


Any comments on that? Feedback, no matter how it is displayed, even as criticism, is valuable. :)You're speaking my language... Actually, that's what Open Source is all about.

magicyte
12-29-2008, 12:22 AM
I'm having trouble. I'm trying to improve Jasoop so that it can parse styles and apply them to the element w/o having to take up so much coding space. Could you explain what is wrong? Also, please demonstrate how to do it correctly.

jasoop.js


var Effect = function(el) {
this.element = document.getElementById(el);
this.style = this.element.style;
this.visible = true;
this.opacity = 100;
this.autodelete = false;
this.loop = false;
this.pause = false;
this.durations = {
"very fast": 50,
"fast": 100,
"normal": 250,
"slow": 500,
"very slow": 1000
};
this.privates = [];
this.entries = 0;
this.toggled = false;
this.fader = setTimeout(function() { return false; }, 10);
};

Effect.prototype = {
move: function(x, y) {
this.style.position = "absolute";
this.style.left = x + "px";
this.style.top = y + "px";
},
toggle: function() {
if (this.style.display == "none") {
this.style.display = "block";
this.visible = true;
} else {
this.style.display = "none";
this.visible = false;
}
},
fade: function(inc, dur) {
if(inc < 0 || inc > 0) {
// fade increments and set timeout
} else {
// toggle because zero will run fade forever
}
},
compute: function(options, dur) {
options = options.replace(/ /g, "");
var ss = options.split(",");
for(i = 0; i < ss.length; i++) {
var s = ss[i].split(":");
this.privates[this.privates.length][s[0]] = [s[0], s[1]];
}
this.privates[this.privates.length].delay = dur;
},
start: function() {
if (!this.pause) {
if (this.entries < this.privates.length) {
for (i = 0; i < this.privates[this.entries].length; i++) this.style[this.privates[this.entries][i[0]]] = this.privates[this.entries][i[1]];
setTimeout(function() {
this.start();
}, durations[this.privates[this.entries].delay]);
this.entries++;
} else {
if (this.autodelete) this.reset();
else this.entries = 0;
if (!this.autodelete && this.loop) this.start();
}
} else {
this.pause = false;
}
},
stop: function() {
this.pause = true;
},
reset: function() {
this.privates = [];
this.entries = 0;
},
addEvent: function(ev, response) {
if (this.element.addEventListener) this.element.addEventListener(ev, response, false);
else if (this.element.attachEvent) {
var res = function() {
response.apply(this.element);
};
this.element.attachEvent("on" + ev, res);
} else this.element["on" + ev] = response;
},
addEvents: function(evs, response) {
for (x = 0; x < evs.length; ++x) this.addEvent(evs[x], response);
},
constructor: Effect
};

There is an error displayed saying that on line 49, this.privates[this.privates.length] is undefined.

Nile
12-29-2008, 12:53 AM
Can you post an ONLINE example?

magicyte
12-29-2008, 10:31 PM
link: http://magicyte1.freehostia.com/ (http://magicyte1.freehostia.com)

please help

Jesdisciple
12-29-2008, 10:46 PM
What browser are you using? (I think you answered before, but I don't recall.) Firefox 3.0.5 displays errors when the page finishes loading:
missing ] in index expression
http://magicyte1.freehostia.com/jasoop.js
Line 59

Effect is not defined
http://magicyte1.freehostia.com/move.html
Line 10

magicyte
12-30-2008, 12:35 AM
FF 3.0.5 - I don't get those errors.


There is an error displayed saying that on line 49 [when visiting magicyte1.freehostia.com/effect.html], this.privates[this.privates.length] is undefined.

There aren't any other errors.

-magicyte

Nile
12-30-2008, 12:41 AM
Download:
https://addons.mozilla.org/en-US/firefox/addon/1843
https://addons.mozilla.org/en-US/firefox/addon/60

Jesdisciple
12-30-2008, 01:39 AM
FF 3.0.5 - I don't get those errors.


There is an error displayed saying that on line 49 [when visiting magicyte1.freehostia.com/effect.html], this.privates[this.privates.length] is undefined.

There aren't any other errors.

-magicytePlease don't lie to me anymore.

Anyway, "this.privates[this.privates.length] is undefined" because an array's length is dynamic. That is, when you add an element to an array, the length is automatically incremented by the JS parser. Thus these scripts have the same effect, and I've given an example of the fix you need to apply:
var arr = [];
arr[arr.length] = "foo";
arr[arr.length] = "bar";
document.write(arr[arr.length - 1]);
var arr = [];
arr[0] = "foo";
arr[1] = "bar";
document.write(arr[1]);

Nile
12-30-2008, 02:30 AM
@Jesdisciple He's not really lying, he doesn't see the errors b/c obviously he doesn't have Web Developers toolbar, or Firebug.

See magicyte, I told you! Thanks for proving me Jesdisciple. (BTW, if your saying "Nile didn't post what Jesdisciple posted, I told him in a chat on gmail)

magicyte
12-30-2008, 08:26 AM
Sorry guys: it doesn't work. I updated jasoop:

jasoop.js


var Effect = function() {
var durations = {
"very fast": 50,
"fast": 100,
"normal": 250,
"slow": 500,
"very slow": 1000
},
privates = [],
entries = 0,
toggled = false,
fader = setTimeout(function() {
return false;
},
10);
function Effect(el) {
this.element = document.getElementById(el);
this.style = this.element.style;
this.visible = true;
this.opacity = 100;
this.autodelete = false;
this.loop = false;
this.pause = false;
}
Effect.prototype = {
move: function(x, y) {
this.style.position = "absolute";
this.style.left = x + "px";
this.style.top = y + "px";
},
toggle: function() {
if (this.style.display == "none") {
this.style.display = "block";
this.visible = true;
} else {
this.style.display = "none";
this.visible = false;
}
},
fade: function(inc, dur) {
if (inc < 0 || inc > 0) { // fade increments and set timeout
} else { // toggle because zero will run fade forever
}
},
compute: function(options, dur) {
options = options.replace(/ /g, "");
var ss = options.split(",");
for (var i = 0; i < ss.length; ++i) {
var s = ss[i].split(":");
privates[privates.length-1][s[0]] = [s[0], s[1]];
}
privates[privates.length-1].delay = dur;
},
start: function() {
if (!this.pause) {
if (entries < privates.length) {
for (var i = 0; i < privates[entries].length; ++i) this.style[privates[entries][i[0]]] = privates[entries][i[1]];
setTimeout(function() {
start();
},
durations[privates[entries].delay]);
entries++;
} else {
if (this.autodelete) this.reset();
else entries = 0;
if (!this.autodelete && this.loop) this.start();
}
} else {
this.pause = false;
}
},
stop: function() {
this.pause = true;
},
reset: function() {
privates = [];
entries = 0;
},
addEvent: function(ev, response) {
if (this.element.addEventListener) this.element.addEventListener(ev, response, false);
else if (this.element.attachEvent) {
var res = function() {
response.apply(this.element);
};
this.element.attachEvent("on" + ev, res);
} else this.element["on" + ev] = response;
},
addEvents: function(evs, response) {
for (var i = 0; i < evs.length; ++i) this.addEvent(evs[i], response);
},
constructor: Effect
};
return Effect;
} ();

Firebug gives an error: privates[this.privates.length - 1] is undefined
http://magicyte1.freehostia.com/jasoop.js
Line 50

Just got Firebug, btw. Nile and I have tried so flippin' hard to figure out what's wrong, cause everything should work. It doesn't. Please provide assistance.

-magicyte

Jesdisciple
12-30-2008, 04:52 PM
@Nile: I don't mean that he was lying about not seeing an error in the first place, but he went to a good bit of trouble to cover his mistake up. Yet all of it was unnecessary because every programmer has made stupid mistakes.

magicyte, the privates array doesn't contain anything because you never add anything to it. What's it supposed to contain?

Nile
12-30-2008, 05:00 PM
He wants the privates variable to be a global variable that all part's of his class can use.

Jesdisciple
12-30-2008, 05:22 PM
Then part of the problem is that it's not global... But what's it supposed to contain?

Also, this.entries is undefined, should be entries.

magicyte
12-30-2008, 06:29 PM
privates is supposed to contain an array of styles and their values that the user enters. This way, there will be an unlimited amount of styles that the user can apply to their effect element.

-magicyte

Nile
12-30-2008, 06:40 PM
Change:


private = [],

To:


private = [''],

magicyte
12-30-2008, 07:08 PM
Thanks again, guys. I fixed most of it up:


var Effect = function() {
var durations = {
"very fast": 50,
"fast": 100,
"normal": 250,
"slow": 500,
"very slow": 1000
},
privates = [''],
entries = 0,
toggled = false,
fader = setTimeout(function() {
return false;
},
10);
function Effect(el) {
this.element = document.getElementById(el);
this.style = this.element.style;
this.visible = true;
this.opacity = 100;
this.autodelete = false;
this.loop = false;
this.pause = false;
}
Effect.prototype = {
move: function(x, y) {
this.style.position = "absolute";
this.style.left = x + "px";
this.style.top = y + "px";
},
toggle: function() {
if (this.style.display == "none") {
this.style.display = "block";
this.visible = true;
} else {
this.style.display = "none";
this.visible = false;
}
},
fade: function(inc, dur) {
if (inc < 0 || inc > 0) { // fade increments and set timeout
} else { // toggle because zero will run fade forever
}
},
compute: function(options, dur) {
options = options.replace(/ /g, "");
var ss = options.split(",");
for (var i = 0; i < ss.length; ++i) {
var s = ss[i].split(":");
privates[privates.length-1][s[0]] = [s[0], s[1]];
}
privates[privates.length-1].delay = dur;
},
start: function() {
if (!this.pause) {
if (entries < privates.length) {
for (var i = 0; i < privates[entries].length; ++i) this.style[privates[entries][i[0]]] = privates[entries][i[1]];
setTimeout("this.start", durations[privates[entries].delay]);
entries++;
} else {
if (this.autodelete) this.reset();
else entries = 0;
if (!this.autodelete && this.loop) this.start();
}
} else {
this.pause = false;
}
},
stop: function() {
this.pause = true;
},
reset: function() {
privates = [''];
entries = 0;
},
addEvent: function(ev, response) {
if (this.element.addEventListener) this.element.addEventListener(ev, response, false);
else if (this.element.attachEvent) {
var res = function() {
response.apply(this.element);
};
this.element.attachEvent("on" + ev, res);
} else this.element["on" + ev] = response;
},
addEvents: function(evs, response) {
for (var i = 0; i < evs.length; ++i) this.addEvent(evs[i], response);
},
constructor: Effect
};
return Effect;
} ();

One prob: there are two warnings that firebug gives:

1.
reference to undefined property privates[entries].delay
http://magicyte1.freehostia.com/jasoop.js
Line 58

2.
reference to undefined property durations[privates[entries].delay]
http://magicyte1.freehostia.com/jasoop.js
Line 58

What's going on here?

-magicyte

magicyte
12-30-2008, 08:01 PM
I finally figured out what is wrong, but I don't know how to fix it. I'm trying to define privates, but it isn't being defined, as seen at magicyte1.freehostia.com/effect.html. It alerts the values of s[0] and s[1], then privates' value, which is undefined (though I'm trying to define it), then I alert the delay value. It is undefined as well. Perhaps I'm not defining privates correctly?

-magicyte

Jesdisciple
12-31-2008, 01:28 AM
First, let's start using Firebug. Change every call to alert to call console.log instead. Reserve alert for one-way messages to the user on pages where you haven't built a more graceful solution.

Nothing is in privates because you never perform an assignment that looks like this:
privates[index] = value;You try to assign to properties of properties, but the parent properties are undefined so assignment to the children is invalid. Am I making sense?

magicyte
12-31-2008, 01:36 AM
Yes; yes you are making sense. How would I assign these properties?

-magicyte

Nile
12-31-2008, 01:38 AM
I think:


privates[0] = '';

Then according to what Jesdisciple you would also have to define the childs...


privates[0] = ['[],[]','[],[]'];

Or something like that... Depending on how many childs.

magicyte
12-31-2008, 01:41 AM
Could you provide an example that goes along the lines of the toolbox? Like an example with the toolbox stuff used (if you know what I mean)?

-magicyte

Jesdisciple
12-31-2008, 01:45 AM
That question is hard for me to answer (beyond stating the obvious) because I don't know what the values should be.

Is entries just an alias for privates.length without the pesky autoincrement feature? (The answer will hopefully help me understand what your program is supposed to do with the styles.)

EDIT: I was two posts too late. You can't add properties to any primitive values, including numbers and strings. But why do you want to make an object with only one property?

EDIT2: Oh, it's not only one property. Anyway, replace '' with {} in your last code snippet. But you'll still have some confusion in your code after that... I'll wait for the parser to complain, though, so we take appropriately small steps.

Nile
12-31-2008, 01:47 AM
No, it would be:


privates[0] = '';


And:


privates[0][0[0]] = [new Array(new Array()),new Array(new Array())];
privates[this.privates.length - 1][s[0]] = [s[0], s[1]];

But that is a complete guess, Jesdisciple would have to tell you what to do.

magicyte
12-31-2008, 02:02 AM
@ Jesdisciple


Is entries just an alias for privates.length without the pesky autoincrement feature?

No, it is an animation counter- should've named it differently. It starts @ 0. Okay:

Compute adds styles to the privates variable (or it should). These are given by the user in a string. Those style names are to be added as properties to privates. The value of those properties will be the style's value. This will make a custom animation ex.:


var x = new Effect("myElement");

x.compute("background-color: red, color: blue", 500); // styles are added to privates afterwhich private's length auto increments
x.start(); // this calculates the styles and visually applies them to the element

I hope you understand, though I just now think that what I want to do is incorrect. See, in compute, I use privates[this.private.length - 1]. Then I add something to it. Is it's length automatically incremented after I just add that one property? If so, then I've made a huge mistake and might as well use the entries variable...


But why do you want to make an object with only one property

I don't, I am trying to add multiple properties.

-magicyte

Jesdisciple
12-31-2008, 02:26 AM
So each property of privates is initialized in compute? Then...
compute: function(options, dur) {
options = options.replace(/ /g, "");
var ss = options.split(",");
var private = {};
for (var i = 0; i < ss.length; ++i) {
var s = ss[i].split(":");
console.log("style: " + s[0] + "; value: " + s[1] + ";");
private[s[0]] = [s[0], s[1]];
console.log(private[s[0]]);
}
private.delay = dur;
console.log(private.delay);
privates.push(private);
},Also, the s[0] notation is specific to Mozilla and won't work in IE (maybe not Opera or Safari either). The equivalent, cross-browser syntax is s.charAt(0).

magicyte
01-02-2009, 10:09 PM
Great, Jesdisciple! That's exactly the format that I need! The 'private' variable is given attributes, afterwhich privates is given those attributes in ONE array in the main array (privates), correct? Well, knowing that your function works, how should I change 'start()'?


Oh, it's not only one property. Anyway, replace '' with {} in your last code snippet. But you'll still have some confusion in your code after that... I'll wait for the parser to complain, though, so we take appropriately small steps.

Thanks for all of your help so far. I hope that we can all stay in touch for the benefit of this framework. BTW, 'private' is a reserved word. I changed it to 'privated'.

Also, @ your quote, you can't PUSH (.push) an object. You can only push arrays. You get the idea... What should I do to the code to make the '.push()' function work?? Also, you can't push something into an object, right? I tried privates[privates.length] = privated; and don't have luck...

-magicyte

Jesdisciple
01-02-2009, 11:27 PM
Great, Jesdisciple! That's exactly the format that I need! The 'private' variable is given attributes, afterwhich privates is given those attributes in ONE array in the main array (privates), correct? Well, knowing that your function works, how should I change 'start()'?The loop format needs to be changed to "for(x in y)" because numerical indexes are invalid.

But before you do that, I need to point out a syntax error that will be overwritten. When i is a number, i[0] (as in privates[entries][i[0]]) is silly. The third numerical index shouldn't be contained in the brackets of the second: privates[entries][i][0].


BTW, 'private' is a reserved word. I changed it to 'privated'.Ugh... I hate future reserved words! ECMA should either use them or drop them (preferably the latter).


Also, @ your quote, you can't PUSH (.push) an object. You can only push arrays. You get the idea... What should I do to the code to make the '.push()' function work??You're using it as an array, so naturally you should make it an array. :p


Also, you can't push something into an object, right? I tried privates[privates.length] = privated; and don't have luck...The problem with privates.length is that privates isn't an array (see above).

magicyte
01-02-2009, 11:49 PM
Alright, I need to calm myself down..... It works MUCH BETTER. Thank you all very much..... *inhales deeply* ... *exhales deeply* ...

-----

There are still problems with it, but it FINALLY changed the background color of the page to red and the color of the text to blue! I'm so excited!

Okay, this is it now:

jasoop.js


var Effect = function() {
var durations = {
"very fast": 50,
"fast": 100,
"normal": 250,
"slow": 500,
"very slow": 1000
},
privates = [],
entries = 0,
toggled = false,
fader = setTimeout(function() {
return false;
},
10);
function Effect(el) {
this.element = document.getElementById(el);
this.style = this.element.style;
this.visible = true;
this.opacity = 100;
this.autodelete = false;
this.loop = false;
this.pause = false;
}
Effect.prototype = {
move: function(x, y) {
this.style.position = "absolute";
this.style.left = x + "px";
this.style.top = y + "px";
},
toggle: function() {
if (this.style.display == "none") {
this.style.display = "block";
this.visible = true;
} else {
this.style.display = "none";
this.visible = false;
}
},
fade: function(inc, dur) {
if (inc < 0 || inc > 0) { // fade increments and set timeout
} else { // toggle because zero will run fade forever
}
},
compute: function(options, dur) {
options = options.replace(/ /g, "");
var ss = options.split(",");
var privated = {};
for (var i = 0; i < ss.length; ++i) {
var s = ss[i].split(":");
console.log("style: " + s[0] + "; value: " + s[1] + ";");
privated[s[0]] = [s[0], s[1]];
console.log(privated[s[0]]);
}
privated.delay = dur;
console.log(privated.delay);
privates.push(privated);
},
start: function() {
if (!this.pause) {
if (entries < privates.length) {
for (i in privates[entries]) {
this.style[privates[entries][i][0]] = privates[entries][i][1];
console.log(privates[entries][i][0]);
}
setTimeout("this.start", 250);
entries++;
} else {
if (this.autodelete) this.reset();
else entries = 0;
if (!this.autodelete && this.loop) this.start();
}
} else {
this.pause = false;
}
},
stop: function() {
this.pause = true;
},
reset: function() {
privates = [];
entries = 0;
},
addEvent: function(ev, response) {
if (this.element.addEventListener) this.element.addEventListener(ev, response, false);
else if (this.element.attachEvent) {
var res = function() {
response.apply(this.element);
};
this.element.attachEvent("on" + ev, res);
} else this.element["on" + ev] = response;
},
addEvents: function(evs, response) {
for (var i = 0; i < evs.length; ++i) this.addEvent(evs[i], response);
},
constructor: Effect
};
return Effect;
} ();

The .html: magicyte1.freehostia.com/effect.html (http://magicyte1.freehostia.com/effect.html)

I get 4 warnings in firebug, but, thank goodness and you guys, it works halfway. I think I'll debug a little bit and then if it doesn't work, I'll post a help request. If it DOES work, I'll post a thank you.

-magicyte

Jesdisciple
01-03-2009, 12:04 AM
effect.html doesn't work when I follow any link to it; when I refresh or enter the URL directly, it works fine. I think this is a Firefox bug which prevents window.onload from running, because when I called the function from Firebug's console it worked fine. On the other hand, why haven't I noticed this on any other page with a window.onload function?

magicyte
01-03-2009, 12:06 AM
It works in my FF browser. Maybe something's wrong with your FF browser...

-magicyte

magicyte
01-03-2009, 12:37 AM
SERVER IS BACK UP. http://magicyte1.freehostia.com/effect.html
Okay. I fixed most of everything. My hoster's server is down, so I can't upload the latest version. Here is the code:

jasoop.js


var Effect = function() {
var durations = {
"very fast": 50,
"fast": 100,
"normal": 250,
"slow": 500,
"very slow": 1000
},
privates = [],
counter = 0,
toggled = false,
fader = setTimeout(function() {
return false;
},
10);
function Effect(el) {
this.element = document.getElementById(el);
this.style = this.element.style;
this.visible = true;
this.opacity = 100;
this.autodelete = false;
this.loop = false;
this.pause = false;
}
Effect.prototype = {
move: function(x, y) {
this.style.position = "absolute";
this.style.left = x + "px";
this.style.top = y + "px";
},
toggle: function() {
if (this.style.display == "none") {
this.style.display = "block";
this.visible = true;
} else {
this.style.display = "none";
this.visible = false;
}
},
fade: function(inc, dur) {
if (inc < 0 || inc > 0) { // fade increments and set timeout
} else { // toggle because zero will run fade forever
}
},
compute: function(options, dur) {
options = options.replace(/ /g, "");
var ss = options.split(",");
var privated = {};
for (var i = 0; i < ss.length; ++i) {
var s = ss[i].split(":");
privated[s[0]] = [s[0], s[1]];
}
privated.delay = dur;
privates.push(privated);
},
start: function() {
if (!this.pause) {
if (counter < privates.length) {
for (var i in privates[counter]) {
this.style[privates[counter][i][0]] = privates[counter][i][1];
}
setTimeout((function(effect) {
return function() {
effect.start();
};
})(this), privates[counter].delay);
counter++;
} else {
if (this.autodelete) this.reset();
else counter = 0;
if (!this.autodelete && this.loop) this.start();
}
} else {
this.pause = false;
}
},
stop: function() {
this.pause = true;
},
reset: function() {
privates = [];
counter = 0;
},
addEvent: function(ev, response) {
if (this.element.addEventListener) this.element.addEventListener(ev, response, false);
else if (this.element.attachEvent) {
var res = function() {
response.apply(this.element);
};
this.element.attachEvent("on" + ev, res);
} else this.element["on" + ev] = response;
},
addEvents: function(evs, response) {
for (var i = 0; i < evs.length; ++i) this.addEvent(evs[i], response);
},
constructor: Effect
};
return Effect;
} ();

effect.html


<html>
<head>
<title>Effect.compute(options, dur); and Effect.start();</title>
<script src="jasoop.js" type="text/javascript">
</script>
<script type="text/javascript">
var myBody;

window.onload = function() {
myBody = new Effect("bdy");
myBody.loop = true;
myBody.autodelete = false;
myBody.compute("background: red, color: blue", 250);
myBody.compute("background: blue, color: red", 250);
myBody.start();
}
</script>
</head>
<body style="font-family: Tahoma, Arial;" id="bdy">
<h1>Effect.compute(options, dur); and Effect.start();</h1>
Effect.compute(options, dur); is programmed to add styles to an array which can and will be processed by Effect.start(). This will apply the styles to the element created which happens after a set duration. This background color should be blinking from red to blue and its text from blue to red. If it isn't, there is an error. Check the source.
<br>
<br>
<a href="index.html"><< Back</a>
</body>
</html>

I'm terribly sorry that I can't upload the files.

-magicyte

Jesdisciple
01-03-2009, 01:09 AM
:eek: I disabled all my addons and found that the problem was fixed. (In the process, I found that the effect was supposed to loop, which it hadn't done at all before.) Then I incrementally re-enabled them and none of them was causing the problem. I have no idea what changed.

magicyte
01-03-2009, 02:13 AM
I wonder what's wrong w/ your browser/add-ons.....

Yeah, Nile told me to not use the ()(); method of the timeout. Amazingly, it failed (his solution). I tried Twey's suggestion and it worked. Yeah, it's supposed to loop. There's only one warning given by Firebug. You may be able to see it, but that isn't a matter. The matter is that it works. I am very glad that it does! I have stayed up MANY of my hours in the morning, and now I'm on a bad schedule. Thanks to you (you is plural, sorry :o), I can get back on a good schedule. Again, thanks much.

-magicyte

Jesdisciple
01-03-2009, 05:57 AM
Yeah, Nile told me to not use the ()(); method of the timeout. Amazingly, it failed (his solution). I tried Twey's suggestion and it worked.??? I'm curious of the details on all that.


There's only one warning given by Firebug. You may be able to see it, but that isn't a matter. The matter is that it works. I am very glad that it does!What's the warning?

magicyte
01-03-2009, 07:44 AM
??? I'm curious of the details on all that.

You see, Nile and I have been talking thru Gmail. He said I didn't need the ()(); in my setTimeout function. I agreed with him. I tried to take the ()(); out and put in function(){this.start();} instead. That didn't work. Then I tried "this.start()". That didn't work. Then I tried "this.start". That didn't work. I tried every single way I could do it without using the self-invoking function thingy. I could see why 'function(){this.start();}' didn't work. 'this' was pointing to that function. We didn't want that. The quoted operations didn't work because they were passed into setTimeout, another function, which would have taken the 'this.start()' from the string and think of it as its own property. However, the self-invoking thingy would parse the 'this' into the function first so that it knew we were talking about effect. Then it would be passed into setTimeout. Nile said that I should rarely use the ()(); operator thingy. WHY?


What's the warning?


reference to undefined property privates[counter][i][0]
http://magicyte1.freehostia.com/jasoop.js
Line 60

It says that it's undefined, but the script works fine, so it doesn't matter. As long as it works (plus, it doesn't even make sense. If it's undefined, the script wouldn't work...). BTW, Jasoop is only 2.72 kb. Before it was 8 kb... Amazing at what little code can do! :)...

-magicyte

Jesdisciple
01-03-2009, 06:51 PM
You see, Nile and I have been talking thru Gmail. He said I didn't need the ()(); in my setTimeout function. I agreed with him. I tried to take the ()(); out and put in function(){this.start();} instead. That didn't work. Then I tried "this.start()". That didn't work. Then I tried "this.start". That didn't work. I tried every single way I could do it without using the self-invoking function thingy. I could see why 'function(){this.start();}' didn't work. 'this' was pointing to that function. We didn't want that. The quoted operations didn't work because they were passed into setTimeout, another function, which would have taken the 'this.start()' from the string and think of it as its own property. However, the self-invoking thingy would parse the 'this' into the function first so that it knew we were talking about effect. Then it would be passed into setTimeout. Nile said that I should rarely use the ()(); operator thingy. WHY?I guess because it's confusing...? *shrug* Either way, another way is to assign var that = this; outside of setTimeout and use the closure inside to call that.start();.


It says that it's undefined, but the script works fine, so it doesn't matter. As long as it works (plus, it doesn't even make sense. If it's undefined, the script wouldn't work...).
for (var i in styles[counter]) {
this.style[styles[counter][i][0]] = styles[counter][i][1];
}Actually, it's not completely working, but nothing is breaking simply because you don't depend on the data thus stored. You should either fix it or remove/comment that code, because it takes up both hard-disk space in the file and, more importantly, RAM during operation.

magicyte
01-03-2009, 07:30 PM
Actually, it's not completely working, but nothing is breaking simply because you don't depend on the data thus stored. You should either fix it or remove/comment that code, because it takes up both hard-disk space in the file and, more importantly, RAM during operation.

Do you mean this code?:


for (var i in styles[counter]) {
this.style[styles[counter][i][0]] = styles[counter][i][1];
}

Comment it out? Why, then it wouldn't work. How is the property undefined? If it can be defined, how would it be done? Is this possible to be fixed?

-magicyte

Jesdisciple
01-03-2009, 08:12 PM
Nope, that was wrong. That warning must depend on some unusual circumstances, because I can't reproduce it and its cause isn't immediately obvious. (I thought you were adding to styles at a lower level than you were retrieving data from it.)

When do you get the warning?

magicyte
01-03-2009, 08:48 PM
Well, it's only sometimes. Not all of the time. It happened several times before, and is probably STILL happening. And, I agree with you when you say that it depends on unusual circumstances. How random what that? Something's wrong w/ my computer, I guess.....

Well, again, thanks MUCH for everything you've done. I'm nearly finished with the 'fade()' function- thanks to you!

-magicyte

magicyte
01-04-2009, 12:49 AM
Tada! I've created a fully functional version of Jasoop, which works in FF and IE. Here is the code which I will most likely add another class to boost its growth:

jasoop.js - 3.31 kb


var Effect = function() {
var durations = {
"very fast": 50,
"fast": 100,
"normal": 250,
"slow": 500,
"very slow": 1000
},
styles = [],
counter = 0,
fader = setTimeout(function() {
return false;
},
10);
function Effect(el) {
this.element = document.getElementById(el);
this.style = this.element.style;
this.visible = true;
this.opacity = 100;
this.autodelete = false;
this.loop = false;
this.pause = true;
}
Effect.prototype = {
move: function(x, y) {
this.style.position = "absolute";
this.style.left = x + "px";
this.style.top = y + "px";
},
toggle: function() {
if (this.style.display == "none") {
this.style.display = "block";
this.visible = true;
} else {
this.style.display = "none";
this.visible = false;
}
},
fade: function(inc, dur) {
if (inc < 0 || inc > 0) {
if (this.opacity >= 0 && this.opacity <= 100) {
clearTimeout(fader);
this.opacity += inc;
fader = setTimeout((function(effect) {
return function() {
effect.fade(inc, dur);
};
})(this), (typeof dur == "string") ? durations[dur] : dur);
}
}
if (this.opacity < 0) this.opacity = 0;
if (this.opacity > 100) this.opacity = 100;
this.style.filter = "alpha(opacity = " + this.opacity + ")";
this.style.KHTMLOpacity = this.opacity / 100;
this.style.MozOpacity = this.opacity / 100;
this.style.opacity = this.opacity / 100;
},
compute: function(options, dur) {
options = options.replace(/ /g, "");
var ss = options.split(",");
var privates = {};
for (var i = 0; i < ss.length; ++i) {
var s = ss[i].split(":");
privates[s[0]] = [s[0], s[1]];
}
privates.delay = dur;
styles.push(privates);
},
start: function() {
if (!this.pause) {
if (counter < styles.length) {
for (var i in styles[counter]) {
this.style[styles[counter][i][0]] = styles[counter][i][1];
}
setTimeout((function(effect) {
return function() {
effect.start();
};
})(this), (typeof styles[counter].delay == "string") ? durations[styles[counter].delay] : styles[counter].delay);
counter++;
} else {
if (this.autodelete) this.reset();
else counter = 0;
if (!this.autodelete && this.loop) this.start();
}
} else {
this.pause = false;
}
},
stop: function() {
this.pause = true;
},
reset: function() {
styles = [];
counter = 0;
},
addEvent: function(ev, response) {
if (this.element.addEventListener) this.element.addEventListener(ev, response, false);
else if (this.element.attachEvent) {
var res = function() {
response.apply(this.element);
};
this.element.attachEvent("on" + ev, res);
} else this.element["on" + ev] = response;
},
addEvents: function(evs, response) {
for (var i = 0; i < evs.length; ++i) this.addEvent(evs[i], response);
},
constructor: Effect
};
return Effect;
} ();

Of course, the testing site for the current functions is found here: http://magicyte1.freehostia.com/

Again, please report any errors, comments, and suggestions to magicyte. E-mail me at m\a\g/i/c/y\t/e [at] g/m\a/i/l [dot] c\o/m

Note that the e-mail given is used without the slashes. Take them out and you've got my e-mail!

Kind regards and many thanks,
magicyte

Medyman
01-04-2009, 06:41 AM
If you don't want that email spammed, i'd obfuscate that email a little bit.

magicyte
01-04-2009, 08:53 PM
Many thanks, Medyman and Twey. (even though I'm getting spammed enough as it is :D j/k)

-magicyte

Nile
01-04-2009, 08:54 PM
I'd turn it into an image... Not just like how you have it - bots can read it.

EDIT:
Something like this(made by Me. :)):
http://localhostr.com/files/312c4d/magicyte.png

Jesdisciple
01-04-2009, 09:05 PM
LOL... Technically, bots can read anything they can access if they're sophisticated enough. That includes images, and that's why CAPTCHA images are so weird. There is no such thing as perfect security against bots on the the 'net, but I think the obfuscation magicyte already used is reasonable.

The best protection against bots is ultimately another bot: a spam filter. And GMail's is pretty darn good; its main downside is that you have to break it in at the very first about what's not spam.

Speaking of GMail, I'm surprised Christopher (my full name too, actually) didn't use filters and labels instead of a completely new address.

But we're getting way off-topic here...

Nile
01-04-2009, 09:11 PM
Yeah... more off topic stuff:

If you had an image, used: [at], and [dot], distorted the image - and inserted small leters around the text such as:
a, b, c, d.
Bots would pick that up and sent an email to... You know: emaabcdil@dsfdabc.com Also in my image I've added the gmail logo, a reflection and a budge or two to try and distract the bots.

A weird thing about gmail:

Gmail gets spam messages such as:


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Lots of time spam messages are a bunch of text - gmails is only a sentence. I wonder if gmail is making $$ sending spam to us. :-?

Jesdisciple
01-04-2009, 09:28 PM
Similar tricks can be played with plain text, but you have to avoid standard patterns (which magicyte didn't in this case):
My address is email"remove"@example.com (without the quoted part).
My address is enail@exanple.com (with the 'n's replaced by 'm's).


But one of my fields of particular interest, artificial intelligence (not just ultra-complex hard-coded instructions but actual thought-simulation), may be able to get past even those soon. So I don't think much effort should be recommended for this; a program that automatically imagifies (and obfuscates) text would be neat, but such tasks should be reserved for computers.

magicyte
01-04-2009, 09:42 PM
Wow! I didn't even know that bots did such things... Thanks for saving me! Btw, I changed the e-mail I had to the e-mail that I don't use as often- I don't give it to people either, so don't e-mail me on that (except for of course the suggestions :D).

-magicyte

Jesdisciple
01-04-2009, 09:50 PM
@Nile: I didn't see your comment about Gmail at first... Was the spam message edited by a mod?

What did you use to make the image? You used some pretty neat effects.

Nile
01-04-2009, 09:51 PM
@Jesdisciple:
No, it was the exes in the first place...
And what "image?" He's using text not an image...

Jesdisciple
01-04-2009, 10:03 PM
How would Gmail profit by sending us Xs?

I corrected myself... I thot magicyte made the image at first but it was you.

Nile
01-04-2009, 10:07 PM
I used Paint.net (http://getpaint.net). Has nothing to do with MS Paint.

Gmail doesn't send you Xs - what I mean is in gmail spam the spams are around once sentence long. Others don't have that. Others have a bunch of paragraphs about there great product... etc.

Jesdisciple
01-04-2009, 10:22 PM
Do they make it through your spam filter? The very few that have made it through mine have mostly been phishing scams, and they have to be longer than that.

Also, it could be that Gmail is biased against longer messages (because typical spam is long) so shorter messages make it through more often.

It's certainly possible that Google is scamming us, but I think that would be very dangerous for such a large company. I would prefer something less noticeable like insider trading if I were them.

Nile
01-05-2009, 04:49 AM
Yes - the small spam messagers are filtered.. I think that google is scamming us.

Medyman
01-05-2009, 03:22 PM
Yes - the small spam messagers are filtered.. I think that google is scamming us.

Gmail's spam filters are still better than any other ones I've ever used. If it is a scam (which I highly doubt), I'll live with it.

magicyte
01-25-2009, 09:49 PM
Okay. I have yet another problem. I added an ajax class and it doesn't work. Check it out here:

http://magicyte1.freehostia.com/ajax.html

Here is the Jasoop code:


var Ajax = function() {
var xmlHttp;
function Ajax(file, method) {
this.response = null;
try { xmlHttp = new XMLHttpRequest(); }
catch(e) {
try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); }
catch(e) {
try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); }
catch(e) {
}
}
}
this.open(file, method);
}
Ajax.prototype = {
open: function(file, method) {
if(xmlHttp !== undefined) {
xmlHttp.open(method, file, true);
xmlHttp.send(null);
}
},
send: function(data) {
if(xmlHttp !== undefined) {
xmlHttp.send(data);
}
},
load: function(action) {
if(xmlHttp !== undefined) {
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4) {
if(xmlHttp.status == 200) {
this.response = xmlHttp.responseText;
eval(action); // try not to use eval here?
}
}
};
}
}
};
return Ajax;
} ();

// Effect class - used in making animations

var Effect = function() {
var durations = {
"very fast": 50,
"fast": 100,
"normal": 250,
"slow": 500,
"very slow": 1000
},
styles = [],
counter = 0,
fader = setTimeout(function() {
return false;
},
10);
function Effect(el) {
this.element = document.getElementById(el);
this.style = this.element.style;
this.visible = true;
this.opacity = 100;
this.autodelete = false;
this.loop = false;
this.pause = true;
}
Effect.prototype = {
move: function(x, y) {
this.style.position = "absolute";
this.style.left = x + "px";
this.style.top = y + "px";
},
toggle: function() {
if (this.style.display == "none") {
this.style.display = "block";
this.visible = true;
} else {
this.style.display = "none";
this.visible = false;
}
},
fade: function(inc, dur) {
if (inc < 0 || inc > 0) {
if (this.opacity >= 0 && this.opacity <= 100) {
clearTimeout(fader);
this.opacity += inc;
fader = setTimeout((function(effect) {
return function() {
effect.fade(inc, dur);
};
})(this), (typeof dur == "string") ? durations[dur] : dur);
}
}
if (this.opacity < 0) this.opacity = 0;
if (this.opacity > 100) this.opacity = 100;
this.style.filter = "alpha(opacity = " + this.opacity + ")";
this.style.KHTMLOpacity = this.opacity / 100;
this.style.MozOpacity = this.opacity / 100;
this.style.opacity = this.opacity / 100;
},
compute: function(options, dur) {
var ss = (options.replace(/ /g, "")).split(";");
var privates = {};
for (var i = 0; i < ss.length; ++i) {
var s = ss[i].split(":");
privates[s[0]] = [s[0], s[1]];
}
privates.delay = dur;
styles.push(privates);
},
start: function() {
if (!this.pause) {
if (counter < styles.length) {
for (var i in styles[counter]) {
this.style[styles[counter][i][0]] = styles[counter][i][1];
}
setTimeout((function(effect) {
return function() {
effect.start();
};
})(this), (typeof styles[counter].delay == "string") ? durations[styles[counter].delay] : styles[counter].delay);
counter++;
} else {
if (this.autodelete) this.reset();
else counter = 0;
if (!this.autodelete && this.loop) this.start();
}
} else {
this.pause = false;
}
},
stop: function() {
this.pause = true;
},
reset: function() {
styles = [];
counter = 0;
},
addEvent: function(ev, response) {
if (this.element.addEventListener) this.element.addEventListener(ev, response, false);
else if (this.element.attachEvent) {
var res = function() {
response.apply(this.element);
};
this.element.attachEvent("on" + ev, res);
} else this.element["on" + ev] = response;
},
addEvents: function(evs, response) {
for (var i = 0; i < evs.length; ++i) this.addEvent(evs[i], response);
},
constructor: Effect
};
return Effect;
} ();

The page alerts 'null'. I suppose that this.response isn't being changed... Hmm?

-magicyte

Jesdisciple
01-26-2009, 02:41 AM
When a function is called, the object of which it's a method is passed to it as the implicit this argument. A function never inherits this from its declaring context; if a function isn't called as a method (bar() instead of foo.bar()), then this === window.
this.response = xmlHttp.responseText;You were expecting that to mean the Ajax object's response property, but it means xmlHttp.response. To fix this, put this line somewhere outside the troublesome function - maybe in the same scope as xmlHttp itself - and refer to that.response.
var that = this;

magicyte
01-28-2009, 12:57 AM
Oh yeah. I forgot about that. :D Thanks!

-magicyte

magicyte
02-21-2009, 04:05 AM
Alright, everybody. I've made a newer version of Jasoop. Check out the code and the changes I made. Note that I took the ajax class out because I wanted to improve, or TRY to improve, Effect().

jasoop.js - 4.94 kb


var Effect = (function() {
var durations = {
"very fast": 500,
"fast": 750,
"normal": 1000,
"slow": 1500,
"very slow": 2000
},
styles = [],
counter = 0,
fader = setTimeout(function() {
return false;
},
10);
function Effect(el) {
this.element = document.getElementById(el);
this.style = this.element.style;
this.visible = true;
this.opacity = 100;
this.queue = false;
this.autodelete = false;
this.loop = false;
this.pause = true;
}
Effect.prototype = {
move: function(x, y) {
this.style.position = "absolute";
this.style.left = x + "px";
this.style.top = y + "px";
},
toggle: function() {
if (this.style.display == "none") {
this.style.display = "block";
this.visible = true;
} else {
this.style.display = "none";
this.visible = false;
}
},
css: function(options) {
var ss = (options.replace(/ /g, "")).split(";");
var privates = {};
for (var i = 0; i < ss.length; ++i) {
var s = ss[i].split(":");
while(1) {
if(s[0].indexOf("-") != -1) {
s[0] = s[0].replace(new RegExp(s[0].substr(s[0].indexOf("-"), 2), "g"), (s[0].substr(s[0].indexOf("-"), 2))[1].toUpperCase());
}
else {
break;
}
}
this.style[s[0]] = s[1];
}
},
fadeIn: function(inc, dur) {
this.fadeTo(100, inc, dur);
},
fadeOut: function(inc, dur) {
this.fadeTo(0, inc, dur);
},
fadeTo: function(pt, inc, dur) {
if (inc > 0) {
if (this.opacity > pt) {
clearTimeout(fader);
this.opacity -= inc;
fader = setTimeout((function(effect) {
return function() {
if ((effect.opacity - inc) >= pt) effect.fadeTo(pt, inc, dur);
else effect.opacity = pt;
};
})(this), (typeof dur == "string") ? Math.floor(durations[dur] / (100 / Math.abs(inc))) : Math.floor(dur / (100 / Math.abs(inc))));
} else {
if (this.opacity < pt) {
clearTimeout(fader);
this.opacity += inc;
fader = setTimeout((function(effect) {
return function() {
if ((effect.opacity + inc) <= pt) effect.fadeTo(pt, inc, dur);
else effect.opacity = pt;
};
})(this), (typeof dur == "string") ? Math.floor(durations[dur] / (100 / Math.abs(inc))) : Math.floor(dur / (100 / Math.abs(inc))));
}
}
}
if (this.opacity < 0) this.opacity = 0;
if (this.opacity > 100) this.opacity = 100;
this.style.filter = "alpha(opacity = " + this.opacity + ")";
this.style.KHTMLOpacity = this.opacity / 100;
this.style.MozOpacity = this.opacity / 100;
this.style.opacity = this.opacity / 100;
},
compute: function(options) {
var ss = (options.replace(/ /g, "")).split(";");
var privates = {};
for (var i = 0; i < ss.length; ++i) {
var s = ss[i].split(":");
while(1) {
if(s[0].indexOf("-") != -1) {
s[0] = s[0].replace(new RegExp(s[0].substr(s[0].indexOf("-"), 2), "g"), (s[0].substr(s[0].indexOf("-"), 2))[1].toUpperCase());
}
else {
break;
}
}
privates[s[0]] = [s[0], s[1]];
}
if (arguments[1] !== undefined) privates.callback = arguments[1];
styles.push(privates);
},
start: function(dur) {
if (!this.pause) {
if (counter < styles.length) {
for (var i in styles[counter]) {
this.style[styles[counter][i][0]] = styles[counter][i][1];
}
if (styles[counter].callback !== undefined)(styles[counter].callback).apply(this);
setTimeout((function(effect) {
return function() {
effect.start(dur);
};
})(this), (typeof styles[counter].delay == "string") ? Math.floor(durations[dur] / styles.length) : Math.floor(dur / styles.length));
counter++;
} else {
if (this.autodelete) this.reset();
else counter = 0;
if (!this.autodelete && this.loop) this.start(dur);
}
} else {
this.pause = false;
}
},
stop: function() {
this.pause = true;
},
reset: function() {
styles = [];
counter = 0;
},
addEvent: function(ev, response) {
if (this.element.addEventListener) this.element.addEventListener(ev, response, false);
else if (this.element.attachEvent) {
var res = function() {
response.apply(this.element);
};
this.element.attachEvent("on" + ev, res);
} else this.element["on" + ev] = response;
},
addEvents: function(evs, response) {
for (var i = 0; i < evs.length; ++i) this.addEvent(evs[i], response);
},
constructor: Effect
};
return Effect;
})();

- NEW Added 'css' function to set styles easily

- NEW Added 'fadeTo' function so that the user can easily fade to a specific opacity in a certain duration with a specific incrementation.

- Seperated 'fade' function into two functions (fadeIn and fadeOut) and made it so that it fades smoothly and takes an overall duration, e.g. 1000 milliseconds as the duration and 100 as the opacity range. Opacity is thus changed every 10 milliseconds. They both use 'fadeTo' in order to execute. :D

- Improved (or tried to ;)) 'compute' function so that you can also add in a function that will execute when compute should (note function is optional: Effect.compute(options [, func]);). Also, I took away the duration parameter so that you can give an overall duration in the 'start' function.

- Improved 'start' function so that it takes overall duration. I also allowed it to execute the extra function in 'compute'

Anyway, that's pretty much all that I did. I know it isn't much, but right now, I'm asking that you guys give me suggestions on what to fix or what I could do with Jasoop. Soon, I will be adding an 'ease' function, similar to the effects of 'tweening' height, width, position, whatever in jQuery and MooTools. I may also make a 'tween' function, similar to the 'tween/transition' function in MooTools, where the current styles are smoothly transitioned into the new styles. Again, please, feedback is the best thing a programmer can get. Any comments, suggestions, and questions are highly wanted. Thank you very much!

(Also, the code is kinda jumbled, I guess. Let me know if there are better ways to accomplish what I am doing. Thanks again!)

I'm also planning to use a new boolean 'queue' variable so that if the user wants to queue just about anything Effect provides, they can. Yet, they have the choice to queue or not.