can't reset the left value of a DIV using document.getElementById(thisDiv).style.left = howFarLeft;

L

lawrence

Sorry for the dumb question but I'm new to Javascript. I wrote this
script hoping to animate some div blocks on a page. You can see the
page here: http://www.keymedia.biz/demo.htm

Can anyone tell me why these DIVs don't drift to the left as they are
supposed to?



<script language="javascript">
var allDivs = new array();
allDivs[] = "todd1";
allDivs[] = "todd2";
allDivs[] = "todd3";
allDivs[] = "todd4";
allDivs[] = "todd5";
allDivs[] = "todd6";
allDivs[] = "todd7";
allDivs[] = "todd8";
allDivs[] = "todd9";
allDivs[] = "todd10";
allDivs[] = "todd11";
allDivs[] = "todd12";
allDivs[] = "todd13";
allDivs[] = "todd14";
allDivs[] = "todd15";
allDivs[] = "todd16";
allDivs[] = "todd17";
allDivs[] = "todd18";
allDivs[] = "todd19";
allDivs[] = "todd20";
allDivs[] = "todd21";
allDivs[] = "todd22";
allDivs[] = "todd23";
allDivs[] = "todd24";
allDivs[] = "todd25";
allDivs[] = "todd26";
allDivs[] = "todd27";
allDivs[] = "todd28";
allDivs[] = "todd29";
allDivs[] = "todd30";
allDivs[] = "todd31";
allDivs[] = "todd32";
allDivs[] = "todd33";
allDivs[] = "todd34";
allDivs[] = "todd35";
allDivs[] = "todd36";
allDivs[] = "todd37";
allDivs[] = "todd38";
allDivs[] = "todd39";
allDivs[] = "todd40";

var thisDiv = "";
var howFarLeft = 0;

function moveDivs() {
for (i=0; i < count(allDivs); i++) {
thisDiv = allDivs;
document.getElementById(thisDiv).style.visibility='visible';
howFarLeft = document.getElementById(thisDiv).style.left;
if (thisDiv == "todd1") howFarLeft = howFarLeft - 1;
if (thisDiv == "todd2") howFarLeft = howFarLeft - 1;
if (thisDiv == "todd3") howFarLeft = howFarLeft - 1;
if (thisDiv == "todd4") howFarLeft = howFarLeft - 1;
if (thisDiv == "todd5") howFarLeft = howFarLeft - 1;
if (thisDiv == "todd6") howFarLeft = howFarLeft - 1;
if (thisDiv == "todd7") howFarLeft = howFarLeft - 1;
if (thisDiv == "todd8") howFarLeft = howFarLeft - 1;
if (thisDiv == "todd9") howFarLeft = howFarLeft - 1;
if (thisDiv == "todd10") howFarLeft = howFarLeft - 2;
if (thisDiv == "todd11") howFarLeft = howFarLeft - 2;
if (thisDiv == "todd12") howFarLeft = howFarLeft - 2;
if (thisDiv == "todd13") howFarLeft = howFarLeft - 2;
if (thisDiv == "todd14") howFarLeft = howFarLeft - 2;
if (thisDiv == "todd15") howFarLeft = howFarLeft - 2;
if (thisDiv == "todd16") howFarLeft = howFarLeft - 2;
if (thisDiv == "todd17") howFarLeft = howFarLeft - 2;
if (thisDiv == "todd18") howFarLeft = howFarLeft - 2;
if (thisDiv == "todd19") howFarLeft = howFarLeft - 2;
if (thisDiv == "todd20") howFarLeft = howFarLeft - 2;
if (thisDiv == "todd21") howFarLeft = howFarLeft - 2;
if (thisDiv == "todd22") howFarLeft = howFarLeft - 2;
if (thisDiv == "todd23") howFarLeft = howFarLeft - 3;
if (thisDiv == "todd24") howFarLeft = howFarLeft - 3;
if (thisDiv == "todd25") howFarLeft = howFarLeft - 3;
if (thisDiv == "todd26") howFarLeft = howFarLeft - 3;
if (thisDiv == "todd27") howFarLeft = howFarLeft - 3;
if (thisDiv == "todd28") howFarLeft = howFarLeft - 3;
if (thisDiv == "todd29") howFarLeft = howFarLeft - 3;
if (thisDiv == "todd30") howFarLeft = howFarLeft - 3;
if (thisDiv == "todd31") howFarLeft = howFarLeft - 3;
if (thisDiv == "todd32") howFarLeft = howFarLeft - 3;
if (thisDiv == "todd33") howFarLeft = howFarLeft - 3;
if (thisDiv == "todd34") howFarLeft = howFarLeft - 4;
if (thisDiv == "todd35") howFarLeft = howFarLeft - 4;
if (thisDiv == "todd36") howFarLeft = howFarLeft - 4;
if (thisDiv == "todd37") howFarLeft = howFarLeft - 4;
if (thisDiv == "todd38") howFarLeft = howFarLeft - 4;
if (thisDiv == "todd39") howFarLeft = howFarLeft - 4;
if (thisDiv == "todd40") howFarLeft = howFarLeft - 4;
if (howFarLeft < -1500) howFarLeft = 9000;
document.getElementById(thisDiv).style.left = howFarLeft;
setTimeOut("moveDivs()", 100);
}
}

</script>
 
P

PDannyD

lawrence said:
Sorry for the dumb question but I'm new to Javascript. I wrote this
script hoping to animate some div blocks on a page. You can see the
page here: http://www.keymedia.biz/demo.htm

Can anyone tell me why these DIVs don't drift to the left as they are
supposed to?

Try changing this...
document.getElementById(thisDiv).style.left = howFarLeft;

.... to this.

document.getElementById(thisDiv).style.left = howFarLeft + "px";

I'm no expert but I found the above addition to work when used on my own
pages.
 
O

oeyvind toft

allDivs[] = "todd1"; doesnt do anything.
You would have to do: myArray[aNumber] = something;
If you dont use an index/a number javascript doesnt know what to do with
your value.

Try this:

var allDivs = new Array();
for(var i = 0; i < 40; i++){
allDivs = "todd" + (i+1);
}

Use myArray.length, not count(myArray).

Also, as PDannyD noted, add 'px' to the left values.

Generally: Try creating loops instead of writing big chunks of code.

Oeyvind
 
R

Richard Cornford

lawrence said:
Sorry for the dumb question but I'm new to Javascript. I
wrote this script hoping to animate some div blocks on a
page. You can see the page here: http://www.keymedia.biz/demo.htm

If you are trying to write javascript you should look into error
reporting in your browser:-

Can anyone tell me why these DIVs don't drift to the left
as they are supposed to?
Probably.

<script language="javascript">

In HTML 4.01 the language attribute is deprecated and the type attribute
is required (making any additional language attribute redundant
anyway):-

var allDivs = new array();
allDivs[] = "todd1";

That line represents a syntax error as the property accessor to which
the string value is being assigned does not feature an expression
between the square brackets. as you are constructing an array that
expression would normally be a number literal or a variable that has
been assigned a numeric value.

However, an array of string literals would usualy be more efficiently
constructed with an Array literal:-

var allDivs = [
"todd1";,"todd2","todd3",
"todd4","todd5","todd6",
"todd7",
// etc. ...
"todd40"
];

But, as has already been pointed out, when code become repetitive to
that extent (the only difference being a numeric suffix that is
sequential) there is potential for reducing the code to a loop with a
body acting on the loop counter, or calling a parameterised function.

allDivs[] = "todd40";

var thisDiv = "";
var howFarLeft = 0;

Do either - thisDiv - or - howFarLeft - need to be global variables. as
they are only used within one function body they probably should be
function local variables (declared with the - var - keyword inside the
function body; usually at the top of the body (by convention)). It is
usually best to never give any variable more scope than it absolutely
needs.
function moveDivs() {
for (i=0; i < count(allDivs); i++) {

The function - count - is not defined within your code, and is not a
global function either in ECMAScript or browser object models. However,
array objects have a - length - property that represents the total
number of elements assigned to the array. You probably want:-

Though you could also:-

for (var c=0; c < allDivs.length; c++) {
...
}

- without any impact on the process except that the code would work
through the array in the reverse order.

for (var c=allDivs.length; c--;) {
...
}

Also, notice that I am using the - var - keyword again here. Your use
of - i - effectivly creates - i - as a global variable, which makes its
use marginally less efficient but also give it more scope than it needs.
It is exactly this type of action that justifies the proposal that
variables should never be given more scope than they need. Suppose you
use a similar - i - loop counter in a number of functions, and allow
that variable to escape into the global scope, and then consider what
happens when one of these loops calls a function that employs any loop
using the same - i - global variable. When the called function returns
the value of - i - is not what you expect it to be as its value will
have been re-set from within the called function. The types of bug that
follow form this can be difficult to identify, yet they can be avoided
entirely by the application of an appropriate discipline to the
authoring of code.
thisDiv = allDivs;
document.getElementById(thisDiv).style.visibility='visible';
howFarLeft = document.getElementById(thisDiv).style.left;


The - style - property of an Html element represent the values assigned
with that element's STYLE attribute. In the HTML you are assigning
values along the lines of - left:400px - within the STYLE attribute, and
when you read these values back you will get, for the value of -
style.left -, string values that correspond with the contents of the
style attribute (assuming the CSS is valid). Thus the preceding
operation is returning a string along the lines of "400px".
if (thisDiv == "todd1") howFarLeft = howFarLeft - 1;

The subtraction operator can only meaningfully act on numeric values and
loosely-typed javascript will accommodate this by type-converting the
value of - howFarLeft - into a number. It will use the type-converting
rules and because the string value has "px" on the end the result will
always be NaN (the special Not a Number numeric value). NaN - 1 is NaN.
assigning NaN to a style property will either produce an error or be
ineffective, depending on the browser.

The parseInt and parseFloat function both work by attempting to
interpret string values as numbers up until the point where the result
could no longer represent a number. As a result, if - parseInt("400px",
10); - was used the number returned would be the integer - 400 -. This
is often found useful in the interrogating of - style - properties,
assuming that the units are "px" and not something like "em".

Also, when a value is assigned to a property of the - style - object the
value assigned is expected to conform with the rules for valid CSS (at
least, some browsers will ignore the action if they do not). Valid
non-zero CSS length values are expected to include the type of units, so
you would normally append the string "px" to the value (e.g. -
x.style.length = (y -1) + "px";) to have any numeric value converted to
a string and "px" added to its end.
if (thisDiv == "todd2") howFarLeft = howFarLeft - 1;
<snip>

It is impossible for - thisDiv - to equal "todd2" at the same time as it
equals "todd1" (or any other value). This fact makes all of these - if -
statements mutually exclusive, and that makes it inefficient to evaluate
all of them. An - if( .... ){ ... }else if( ... ){ ... } - construct
would better represent the mutually exclusive nature of the sequence of
statements, and would be more efficient as it would stop testing as soon
as any - if - expression evaluated as true.

However, long blocks of - if/else -, where a single variable values is
tested against a sequence of constant values is exactly the
circumstances for which the - switch - statement exists. Though, if a
clear relationship existed between the numeric suffix on the ID string
and the value by which the DIV was to be moved, neither construct would
be needed as the code could be reduced to a parameterised function call

Richard.
 
R

Richard Cornford

Richard Cornford wrote:
... . You probably want:-

Though you could also:-

for (var c=0; c < allDivs.length; c++) {
...
}

- without any impact on the process except that the code
would work through the array in the reverse order.

for (var c=allDivs.length; c--;) {
...
}
<snip>

That would have made more sense if I had pasted the - for - loops into
the right places:-

<correction>

.... . You probably want:-

for(var c = 0; c < allDivs.length; c++){
...
}

Though you could also use:-

for(var c = allDivs.length; c--;){
...
}

- without any impact on the process except that the code
would work through the array in the reverse order.
</correction>

Richard.
 
S

Stephen Chalmers

lawrence said:
Sorry for the dumb question but I'm new to Javascript. I wrote this
script hoping to animate some div blocks on a page. You can see the
page here: http://www.keymedia.biz/demo.htm

Can anyone tell me why these DIVs don't drift to the left as they are
supposed to?
In addition to all the errors already mentioned, your call to setTimeout is
spelled incorrectly and should not be inside the for loop.

Whenever you make a call to getElementById() (or any function returning a useful
value), you should always test the value returned and act accordingly.

If you want to perform a basic mathematical operation on a variable, you need
only mention it once,
i.e. in preference to howFarLeft=howFarLeft-1, use howFarLeft -= 1.

The numeric values of some properties may be stored as part of a string, so use
a suitable function like parseInt() in this case, to read the integer value.

Here's a slightly more compact working equivalent:

Call with: <body onload='if(document.getElementById)setDivs()';>

<SCRIPT type='text/javascript'>

var allDivs = new Array();

var howFarLeft = 0,
elem=true,
stepChange=new Array(10,23,34,100);

function setDivs()
{
for(var i=0;i<40 && elem!=null;i++)
{
if(elem=document.getElementById("todd"+(i+1)))
{
elem.style.visibility='visible';
allDivs=elem; //store references not IDs
}
}
if(elem) //all expected divs available
moveDivs();
else
alert('Cannot find div called todd'+i+' :-(' );
}

function moveDivs()
{
for(var i=0, ind=0; i < allDivs.length && elem!=null; i++)
{
elem=allDivs;

howFarLeft = parseInt(elem.style.left);

if(i+1 == stepChange[ind])
ind++;

howFarLeft-=(ind+1);

if(howFarLeft < -1500)
howFarLeft = 9000;

elem.style.left = howFarLeft+'px';
}

setTimeout("moveDivs()", 100);
}

</SCRIPT>
 
L

lawrence

Stephen Chalmers said:
In addition to all the errors already mentioned, your call to setTimeout is
spelled incorrectly and should not be inside the for loop.

Thanks for seeing that.

Whenever you make a call to getElementById() (or any function returning a useful
value), you should always test the value returned and act accordingly.
If you want to perform a basic mathematical operation on a variable, you need
only mention it once,
i.e. in preference to howFarLeft=howFarLeft-1, use howFarLeft -= 1.
The numeric values of some properties may be stored as part of a string, so use
a suitable function like parseInt() in this case, to read the integer value.

Thanks. I know PHP better than Javascript. In PHP I would have tested
with is_numeric() or is_int() but I couldn't figure out the Javascript
equivelants. I guess I need to get Danny Goodman's book and study all
the basic methods of the built-in objects. I am a little confused by
Javascripts partial object orientation. Where does parseInt() come
from? Does it belong to some master object, or is some non-OOP
function? Is there a list of all non-OOP functions somewhere?



Here's a slightly more compact working equivalent:

Thanks very much for reworking my code. Your code is a little over my
head. I hope you mind two questions:


stepChange=new Array(10,23,34,100);

What is this? I first assumed it was meant to cause certain DIVs to
move faster than others, but what is the 100 for? And where does the
value come back out? I guess these next lines do it, using ind?
if(i+1 == stepChange[ind])
ind++;

howFarLeft-=(ind+1);

So if I wanted to increase the speed I go ind+2 or ind+3, and if I
want to increase the number of DIVS that move fast, I go

stepChange=new Array(10,12,20,23,27,31,34,100);






Also, I'm used to PHP syntax, so this surprise me:
if(elem) //all expected divs available
moveDivs();
else
alert('Cannot find div called todd'+i+' :-(' );
}

Does it work just as well if I go:

if(elem) {
moveDivs();
} else {
alert('Cannot find div called todd'+i+' :-(' );
}
}



Also, I notice that changing the time on the setTimeout doesn't seem
to speed things up. When I change the 100 to a 10, things seem nearly
the same. How can that be?
setTimeout("moveDivs()", 100);


Sorry for all the dumb questions. I'm sure 3 months from now I'll look
back on this script and wince at my own stupidity.
 
M

Michael Winter

[snip]
Thanks. I know PHP better than Javascript. In PHP I would have tested
with is_numeric() or is_int() but I couldn't figure out the Javascript
equivelants. I guess I need to get Danny Goodman's book and study all
the basic methods of the built-in objects.

There isn't really any direct equivalent. It's best to use a regular
expression and the test method.
I am a little confused by Javascripts partial object orientation.

As far as I'm aware, Javascript is fully object-oriented, it's just not
quite as obvious as in other languages.
Where does parseInt() come from? Does it belong to some master object,
or is some non-OOP function?

It, and other host objects, are part of the global object. The global
object can be referred to using the this operator in global scope or, more
commonly, the window object.
Is there a list of all non-OOP functions somewhere?

All functions are part of an object, at least in theory. Some just don't
seem to be. The core set of built-in functions (as defined in the
ECMAScript specification) are described in the latter two Netscape
JavaScript references. Earlier de-facto host objects are defined in v1.3.

<URL:http://devedge.netscape.com/central/javascript/>

[snip]
stepChange=new Array(10,12,20,23,27,31,34,100);

I can't comment on the purpose of this code (I haven't really been
following this thread), but that would better written using array literal
notation:

stepChange = [10, 12, 20, 23, 27, 31, 34, 100];
Also, I'm used to PHP syntax, so this surprise me:


Does it work just as well if I go:

if(elem) {
moveDivs();
} else {
alert('Cannot find div called todd'+i+' :-(' );
}
}

It's exactly the same. The usual arguments of why it's better to brace
conditional (and other) statement blocks apply to Javascript, too.
Also, I notice that changing the time on the setTimeout doesn't seem to
speed things up. When I change the 100 to a 10, things seem nearly the
same. How can that be?

Most likely because your computer can't call the function every 10
milliseconds.

[snip]

Hope that helps,
Mike
 
L

lawrence

oeyvind toft said:
var allDivs = new Array();
for(var i = 0; i < 40; i++){
allDivs = "todd" + (i+1);
}

Use myArray.length, not count(myArray).


Thanks. I know PHP much better than Javascript, so the PHP syntax and
function names keeps sneaking into my code. Is it best to do this:

var num = myArray.length;
for (var i = 0; i < num; i++) {

or is this better:

for (var i = 0; i < myArray.length; i++) {


Again, thanks for all the help.
 
L

lawrence

Stephen Chalmers said:
if(i+1 == stepChange[ind])
ind++;

howFarLeft-=(ind+1);

If I want to creat multiple speeds, do I create another array like
stepChange, or does the speed change increase as we walk through this
array? If I wanted a high speed set of DIVS, should I do a separate
array?





var allDivs = new Array();

var howFarLeft = 0,
elem=true,
stepChange=new Array(10,23,34,100);

function setDivs()
{
for(var i=0;i<40 && elem!=null;i++)
{
if(elem=document.getElementById("todd"+(i+1)))
{
elem.style.visibility='visible';
allDivs=elem; //store references not IDs
}
}
if(elem) //all expected divs available
moveDivs();
else
alert('Cannot find div called todd'+i+' :-(' );
}

function moveDivs()
{
for(var i=0, ind=0; i < allDivs.length && elem!=null; i++)
{
elem=allDivs;

howFarLeft = parseInt(elem.style.left);

if(i+1 == stepChange[ind])
ind++;

howFarLeft-=(ind+1);

if(howFarLeft < -1500)
howFarLeft = 9000;

elem.style.left = howFarLeft+'px';
}

setTimeout("moveDivs()", 100);
}
 
M

Michael Winter

[snip]
Is it best to do this:

var num = myArray.length;
for (var i = 0; i < num; i++) {

or is this better:

for (var i = 0; i < myArray.length; i++) {

I suppose that in practice, it doesn't make much difference. However, the
former will be marginally faster (so it's what I always use :), though I'd
write:

for(var i = 0, n = myArray.length; i < n; ++i) {
// ...
}

Mike
 
S

Stephen Chalmers

lawrence said:
"Stephen Chalmers" <[email protected]> wrote in message
if(i+1 == stepChange[ind])
ind++;

howFarLeft-=(ind+1);

If I want to creat multiple speeds, do I create another array like
stepChange, or does the speed change increase as we walk through this
array? If I wanted a high speed set of DIVS, should I do a separate
array?
Your original code specified step sizes individually for each div, which
increased by one at given intervals. The contents of stepChange are used to
indicate the points in the array at which the step size is incremented by 1. The
last element in stepChange is not used, but is there as a simple way of
preventing reading past the end.

If you want to increase the speed further, you could change

howFarLeft-=(ind+1) to howFarLeft-=(ind+1)*2

although having seen the display running, I do not recommend it.
 
D

Dr John Stockton

JRS: In article <[email protected]>,
dated Wed, 1 Sep 2004 12:13:44, seen in
lawrence said:
Also, I notice that changing the time on the setTimeout doesn't seem
to speed things up. When I change the 100 to a 10, things seem nearly
the same. How can that be?


The resolution of setTimeout, setInterval, and new Date() is system-
dependent. It should not be confused with the resolution of the Date
Object itself, which is 1 ms.

In Win98, it is about 55 ms; in later systems, often 10 ms. It appears
that the set... routines are implemented so as to make *each* delay
always at least the requested value (setInterval could be probably
implemented so as to get the average interval correct). In addition,
one must consider the overheads in code execution, which add delays.

The following function, in js-dates.htm, estimates the resolution of
new Date() :-


function Resol() { var J = 0, T0 = XT = T = new Date().getTime()
while (J < 10) {
if (T != XT) { XT = T ; J++ }
T = new Date().getTime() }
document.write(
"about<tt> ", (new Date()-T0)/10, " ms<\/tt>") }



I seek reliable information on resolutions in various systems, in
particular, where not 55 or 10 ms.
 
T

Thomas 'PointedEars' Lahn

lawrence said:
Also, I'm used to PHP syntax, so this surprise me:


Does it work just as well if I go:

if(elem) {
moveDivs();
} else {
alert('Cannot find div called todd'+i+' :-(' );
}
}

Yes, of course. Why do you not just RTFM and/or try it?
Also, I notice that changing the time on the setTimeout doesn't seem
to speed things up. When I change the 100 to a 10, things seem nearly
the same. How can that be?

The maximum resolution for a timeout or interval is restricted to
the system timer's resolution. However, you most certainly stumble
over the fact that the numbers mean *milliseconds* (1/1000 of a
second), not seconds. Human perception usually is too slow to
note the difference between these spans of time.
Sorry for all the dumb questions.

There are no dumb questions, just not thoughtfully enough asked ones.
As for you, many of your questions would have been answered by
reading a decent manual. You have done that when learning PHP, have
you not?
I'm sure 3 months from now I'll look back on this script and wince at
my own stupidity.

Probably.


PointedEars
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top