animation does not work

P

papa

Hello everyone!

I am trying to create a script that makes a text move first to the
right side of the screen and then back to the left side but I do not
accomplish this. My idea is to kick start the script by calling the
starta() -method witch in turn will start the moveTxt() and moveBack()
methods. If I remove the moveBack() method from the starta() -method
the script works so far as it is moving the text to the right side of
the screen. When I add the moveBack() method to the starta() -method
nothing works.

Do anyone have a solution to this problem? I attach the code below.

Best regards!


<html>
<head>
<title>en enkel animering</title>
<script language="JavaScript">
<!--
function starta()
{
moveTxt();
moveBack();
}

function moveTxt()
{
if(ani1.style.pixelLeft < 250)
{
ani1.style.pixelLeft += 2;
setTimeout("moveTxt()", 25);
}
}

function moveBack()
{
if(ani1.style.pixelLeft >= 10)
{
ani1.style.pixelLeft -= 2;
setTimeout("moveBack()", 25);
}
}
-->
</script>
</head>

<body onLoad="starta()">
<div id="ani1" style="position: absolute; left:10; top:10">
Text ... som flyttas!

</div>
</body>
</html>
 
E

Erwin Moller

papa said:
Hello everyone!

I am trying to create a script that makes a text move first to the
right side of the screen and then back to the left side but I do not
accomplish this. My idea is to kick start the script by calling the
starta() -method witch in turn will start the moveTxt() and moveBack()
methods. If I remove the moveBack() method from the starta() -method
the script works so far as it is moving the text to the right side of
the screen. When I add the moveBack() method to the starta() -method
nothing works.

Do anyone have a solution to this problem? I attach the code below.

Best regards!

A few pointers follow:
<html>
<head>
<title>en enkel animering</title>
<script language="JavaScript">

Change that in

Unless you target a browser from the early stone age, don't use <!-- to
hide javascript.

function starta()
{
moveTxt();
moveBack();
}

function moveTxt()
{
if(ani1.style.pixelLeft < 250)

What is ani1?
I am quite sure Javascript has no clue.
I expect you forgot:
var ani1 = document.getElementById("ani1");

{
ani1.style.pixelLeft += 2;
setTimeout("moveTxt()", 25);

window.setTimeout is better.
}
}

function moveBack()
{

Same ani1 problem

if(ani1.style.pixelLeft >= 10)
{
ani1.style.pixelLeft -= 2;
setTimeout("moveBack()", 25);
}
}
-->

Remove this --> too.
</script>
</head>

<body onLoad="starta()">
<div id="ani1" style="position: absolute; left:10; top:10">
Text ... som flyttas!

</div>
</body>
</html>

A last remark:
1) Download firefox.
2) Use tools-> Error Console

It will list all problems in your script, like unknown ani1.

Regards,
Erwin Moller
 
H

Henry

Hello everyone!

I am trying to create a script that makes a text move first
to the right side of the screen and then back to the left side
but I do not accomplish this. My idea is to kick start the
script by calling the starta() -method witch in turn will start
the moveTxt() and moveBack() methods. If I remove the moveBack()
method from the starta() method the script works so far as it
is moving the text to the right side of the screen. When I
add the moveBack() method to the starta() method nothing works.

Everything you have here is 100% working (exactly as you have
programmed it to work).
<snip<
function starta()
{
moveTxt();

Your - moveTxt - function moves the text 2 pixels to the right and
schedules itself to be re-exeucted in 25 milliseconds (until a
particular value is exceeded).
moveBack();
}
<snip>

Your - moveBack - function moves the text 2 pixels to the left and
schedules itself to be re-exeucted in 25 milliseconds.

So what your code does is set the position of the element 2 pixels to
the right, schedule a function call with setTimeout, then set the
position 2 pixels to the left (leaving it right where it started) and
schedules another function call. The browser then waits 25
milliseconds (or there about), giving it time to update the display
(which shows the element right were it has been set to be, exactly
where it started. Then the first function fires again setting the
element's position 2 pixels to the right, and then the second function
fires again setting it 2 pixels to the left (so back were it started
again). And so this goes on, working precisely as programmed by
continually setting the element's position to exactly where it started
off and so showing no apparent movement.
 
D

Doug Gunnoe

Hello everyone!

I am trying to create a script that makes a text move first to the
right side of the screen and then back to the left side but I do not
accomplish this. My idea is to kick start the script by calling the
starta() -method witch in turn will start the moveTxt() and moveBack()
methods. If I remove the moveBack() method from the  starta() -method
the script works so far as it is moving the text to the right side of
the screen. When I add the moveBack() method to the  starta() -method
nothing works.

Do anyone have a solution to this problem? I attach the code below.

Best  regards!

<html>
<head>
  <title>en enkel animering</title>
  <script language="JavaScript">
  <!--
  function starta()
  {
    moveTxt();
        moveBack();
  }

  function moveTxt()
  {
    if(ani1.style.pixelLeft < 250)
        {
          ani1.style.pixelLeft += 2;
          setTimeout("moveTxt()", 25);
        }
  }

  function moveBack()
  {
    if(ani1.style.pixelLeft >= 10)
        {
          ani1.style.pixelLeft -= 2;
          setTimeout("moveBack()", 25);
        }
  }
   -->
  </script>
</head>

<body onLoad="starta()">
  <div id="ani1" style="position: absolute; left:10; top:10">
    Text ... som flyttas!

  </div>
</body>
</html>

The way you are using setTimeout does not work the way you are
thinking it will, as someone else already did a good job of pointing
out. Try combining it all into one function, something like this:

<script>
function starta()
{
forward = true;
back = false;
moveTxt();
}

function moveTxt()
{
if(forward){
ani1.style.pixelLeft += 2;
if(ani1.style.pixelLeft == 250){forward = false; back =
true;}
setTimeout("moveTxt()",25);
}
else if(back){
ani1.style.pixelLeft -= 2;
if(ani1.style.pixelLeft == 10){back = false;}
setTimeout("moveTxt()",25);
}

}
</script>
 
D

Doug Gunnoe

And then wonder why it doesn't work in non-IE browsers?
ani1.style.pixelLeft += 2;

lol @ me & cut and paste.

and IIRC, someELMObj.style.left += 2 will be an error.

this maybe?

someELMObj = document.getElementVyId('some_id');
someELMObj.style.left = parseInt(someELMObj.style.left) + 2 + "px"
 
D

Doug Gunnoe

And then wonder why it doesn't work in non-IE browsers?
ani1.style.pixelLeft += 2;

lol @ me & cut and paste.

and IIRC, someELMObj.style.left += 2 will be an error.

this maybe?

someELMObj = document.getElementById('some_id');
someELMObj.style.left = parseInt(someELMObj.style.left) + 2 + "px"
 
T

Thomas 'PointedEars' Lahn

Doug said:
lol @ me & cut and paste.

and IIRC, someELMObj.style.left += 2 will be an error.

this maybe?

someELMObj = document.getElementById('some_id');
someELMObj.style.left = parseInt(someELMObj.style.left) + 2 + "px"

No, of course. Because one operand is a string value, first the return
value of parseInt() will be converted to String as well as `2' to "2" and
and then string concatenation will be performed anyway. However, the
following would work:

someELMObj.style.left = (parseInt(someELMObj.style.left, 10) + 2) + "px";

One should even consider

someELMObj.style.left = (parseFloat(someELMObj.style.left) + 2) + "px";

since length values do not need to be whole numbers:

http://www.w3.org/TR/CSS21/syndata.html#length-units

Both solutions are assuming, of course, that the unit of length used for the
`left' property was `px' already.


PointedEars
 
P

papa

Hello again everyone!
I am still trying to create a script that makes a text move first to
the right side of the screen and then back to the left side. I vill
start by saying "thank you all" for helping me. I have summed up your
suggestions in a new script but since I am a beginner in writing
JavaScript I hope that you will correct my new mistakes. When I run
this script it responds with a runtime error.

<html>
<head>
<title>en enkel animering</title>
<script type="text/javascript">
function starta()
{
forward = true;
back = false;
moveTxt();
}
//var ani1 = document.getElementById("ani1"); Do I really need this?
function moveTxt()
{
if(forward){
//ani1.style.pixelLeft += 2;
someELMObj.style.left = (parseInt(someELMObj.style.left, 10) + 2)
+ "px";
if(ani1.style.pixelLeft == 250){forward = false; back =
true;}
setTimeout("moveTxt()",25);
}
else if(back){
//ani1.style.pixelLeft -= 2;
someELMObj.style.left = (parseInt(someELMObj.style.left, 10) + 2) +
"px";
if(ani1.style.pixelLeft == 10){back = false;}
setTimeout("moveTxt()",25);
}
}
</script>
</head>
<body onLoad="starta()">
<div id="ani1" style="position: absolute; left:10; top:10">
Text ... som flyttas!
</div>
</body>
</html>
 
D

David Mark

Hello again everyone!
I am still trying to create a script that makes a text move first to
the right side of the screen and then back to the left side. I vill
start by saying "thank you all" for helping me. I have summed up your
suggestions in a new script but since I am a beginner in writing
JavaScript I hope that you will correct my new mistakes. When I run
this script it responds with a runtime error.

What runtime error? What line?
<html>
<head>
  <title>en enkel animering</title>
  <script type="text/javascript">
  function starta()
  {
        forward = true;
        back = false;

Obviously these flags are mutually exclusive, therefore one variable
would suffice.
        moveTxt();
  }
  //var ani1 = document.getElementById("ani1"); Do I really need this?
Yes.

  function moveTxt()
  {
    if(forward){
          //ani1.style.pixelLeft += 2;
                  someELMObj.style.left = (parseInt(someELMObj.style.left, 10) + 2)
+ "px";

Perhaps you should post a link to the page in question. It would make
it easier to spot your problem.
          if(ani1.style.pixelLeft == 250){forward = false;back =
true;}

Go back and re-read the previous posts in this thread. The pixelLeft
property is proprietary to IE.
 
E

Evertjan.

Thomas 'PointedEars' Lahn wrote on 08 jan 2008 in comp.lang.javascript:
One should even consider

someELMObj.style.left = (parseFloat(someELMObj.style.left) + 2) + "px";

or, for regex lovers:

someELMObj.style.left = (+someELMObj.style.left.replace(/px/,'')+2)+"px";

or even:

var o = someELMObj;
o.style.left =
o.style.left.replace(/([\d\.]+)(px)/,function(a,b,c){return (+b+2)+c});
 
A

Anthony Levensalor

Evertjan. said:
[snip]
or, for regex lovers:

someELMObj.style.left = (+someELMObj.style.left.replace(/px/,'')+2)+"px";

Dude, that's slick. Thanks.

or even:

var o = someELMObj;
o.style.left =
o.style.left.replace(/([\d\.]+)(px)/,function(a,b,c){return (+b+2)+c});

And that made my head hurt a little. I should sleep.

~A!
 
T

Thomas 'PointedEars' Lahn

[Context restored]

Anthony said:
Evertjan. said:


Dude, that's slick. Thanks.

It is more error-prone and more inefficient than my solution:

1. Because of the unary `+', it does not handle pseudo-octals, and
breaks
with MSHTML < 5.01 and other older user agents/script engines.

2. It uses String.prototype.replace() where String.prototype.match()
would have sufficed:

someELMObj.style.left =
(+someELMObj.style.left.match(/[+-]?\d+(\.\d+)?/)[0] + 2) +
"px";

3. It creates a RegExp object where a string value would have
sufficed:

someELMObj.style.left =
(+someELMObj.style.left.replace("px", '') + 2) + "px";

4. It breaks on UAs that implement `left' as a number-type property,
such as earlier Gecko builds.

5. It assigns an invalid value to the stylesheet property (which
means "no change" in MSHTML, and an error message in other UAs)
if the original unit of length was not `px'.


PointedEars
 
A

Anthony Levensalor

Thomas 'PointedEars' Lahn said:
[Context restored]

Anthony said:
Evertjan. said:
Dude, that's slick. Thanks.

It is more error-prone and more inefficient than my solution:

I liked yours too, sorry I didn't mention it, actually. I've struggled
with the PX string on the end of what should be numbers problem a bunch
of times, and always appreciate an easier way.

[snip]
2. It uses String.prototype.replace() where String.prototype.match()
would have sufficed:

someELMObj.style.left =
(+someELMObj.style.left.match(/[+-]?\d+(\.\d+)?/)[0] + 2) +
"px";

IMHO, it's a matter of style, and the performance hit is nil, so I guess
that one's up in the air for me. It's like me with typeof, even when I
don't _need_ to use it, I like the clarification it provides when I go
back and look later, etc. Of course, there's right and wrong too, just
not sure this fits there.

3. It creates a RegExp object where a string value would have
sufficed:

someELMObj.style.left =
(+someELMObj.style.left.replace("px", '') + 2) + "px";

And over several thousand or even hundred repetitions, that could be
ugly. Point firmly grasped in that regard.

[snip]

5. It assigns an invalid value to the stylesheet property (which
means "no change" in MSHTML, and an error message in other UAs)
if the original unit of length was not `px'.

someELMObj.style.left = (parseFloat(someELMObj.style.left) + 2) + "px";

Correct me if I'm wrong (god, if that isn't an unnecessary way to start
a sentence out here ;) ), but wouldn't the above line have the same issue?

All the best,
~A!
 
T

Thomas 'PointedEars' Lahn

Anthony said:
Thomas 'PointedEars' Lahn said:

I liked yours too, sorry I didn't mention it, actually.

Never mind, that was certainly not my point.
[...]
[snip]
2. It uses String.prototype.replace() where String.prototype.match()
would have sufficed:

someELMObj.style.left =
(+someELMObj.style.left.match(/[+-]?\d+(\.\d+)?/)[0] + 2) +
"px";

IMHO, it's a matter of style, and the performance hit is nil, [...]

No offense meant, but how would *you* know?
[...]
3. It creates a RegExp object where a string value would have
sufficed:

someELMObj.style.left =
(+someELMObj.style.left.replace("px", '') + 2) + "px";

And over several thousand or even hundred repetitions, that could be
ugly. Point firmly grasped in that regard.

ECMAScript Edition 3 Final, section 7.8.5 says that the RegExp object would
only be created one time (when the literal is scanned), and the literal
would further serve as a reference to that object. So *that* would probably
not be a memory issue, even with a zillion of iterations. However, the
creation of an object would generally take longer than storing a primitive
value, and considering the greater complexity of a RegExp object it would
probably require more memory than a string value; even if it would only be one.
someELMObj.style.left = (parseFloat(someELMObj.style.left) + 2) + "px";

Correct me if I'm wrong (god, if that isn't an unnecessary way to start
a sentence out here ;) ), but wouldn't the above line have the same issue?

The assigned value would not make much sense in that case (it would be the
displayed equivalent of "2em + 2px" and the like) but it would always be
valid. Both parseInt() and parseFloat() stop parsing where they encounter
a character that cannot be interpreted as a digit (ES3 Final, 15.1.2.2 and
15.1.2.3), so the unit substring string would never be part of the
evaluation result of the first operand and the "px" could be safely appended.

On the other hand, if you only try to replace "px" and there is no "px" in
the value string, then you could end up with e.g. "NaNpx" because +"4em"
would evaluate to `NaN' and the result of the addition would be `NaN' as
well. And since the properties of style objects if referred this way would
either reflect the value of the style element or could not contain a unit
substring, I don't think it would suffice to replace all specified units of
length, however inefficient that would be.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Thomas 'PointedEars' Lahn said:
Anthony said:
[...]
[snip]
2. It uses String.prototype.replace() where String.prototype.match()
would have sufficed:

someELMObj.style.left =
(+someELMObj.style.left.match(/[+-]?\d+(\.\d+)?/)[0] + 2) +
"px";
IMHO, it's a matter of style, and the performance hit is nil, [...]

No offense meant, but how would *you* know?

[agitated rant]

I did say no offense was meant with the question, did I not?
Javascript, up until Christmas of this year, was an aside for me.

However, that was exactly my point. It is not logical, however
desirable, for an absolute beginner in a field to make bold and
*correct* statements about exactly that field.
Benchmarking, performance tuning, refactoring, logic, and programming in
general have not been new to me in 20 years. If you open up Firebug or
the very inferior IE Developer Toolbar, you will see why the performance
hit is nil over a thousand iterations of instantiating brand new RegExp
objects/entities/flibbledorfs [...]

That the RegExp object is only created *once* when the literal syntax
is used and so the number of iterations would not matter at all was
exactly my following point. (So much for your reading.) However,
that does not have anything to do with the performance difference of
String.prototype.replace() vs. String.prototype.match(). Hence my
question.

And in *my* benchmarks the performance difference is a considerable
one.

Test case
----------

var start = new Date();
for (var i = 0; i < 100000; i++)
{
var x = "2px".match(/[+-]?\d+(\.\d+)?/)[0];
}
console.log("String.prototype.match: ", new Date() - start, " ms");

var start = new Date();
for (var i = 0; i < 100000; i++)
{
var y = "2px".replace(/px/);
}
console.log("String.prototype.replace: ", new Date() - start, " ms");

Results (2 repetitions, formatted)
-----------------------------------

String.prototype.match: 15297 ms
String.prototype.replace: 2219 ms

String.prototype.match: 17859 ms
String.prototype.replace: 3532 ms

String.prototype.match: 14360 ms
String.prototype.replace: 3532 ms

UA: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/
20071127 Firefox/2.0.0.11
(Firebug 1.05)

So it would seem we were both wrong regarding performance. However,
the issue with String.prototype.replace() and the no-"px" values
remains, so it is not merely a matter of style what to use, in that
regard as well.
[...]
3. It creates a RegExp object where a string value would have
sufficed:

someELMObj.style.left =
(+someELMObj.style.left.replace("px", '') + 2) + "px";
And over several thousand or even hundred repetitions, that could be
ugly. Point firmly grasped in that regard.

ECMAScript Edition 3 Final, section 7.8.5 says that the RegExp object would
only be created one time (when the literal is scanned), and the literal
would further serve as a reference to that object. So *that* would probably
not be a memory issue, even with a zillion of iterations. However, the
creation of an object would generally take longer than storing a primitive
value, and considering the greater complexity of a RegExp object it would
probably require more memory than a string value; even if it would only be one.

Wow, you think? Objects take up more memory than primitive values? Holy
smack, want a cookie?

You just made the same logical leap my four year old can make.
Congratulations.

You missed the point.
I didn't snip anything, and I did it because. I know you hate it.

That would make you a troll.
You're really starting to irritate me,
[flame]

Get a life.


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

Forum statistics

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

Latest Threads

Top