PDA

View Full Version : Text animation troubles in Opera



Blake
02-28-2007, 04:10 AM
That's the best title I could come up with...

Here's the problem: I'm working on a php contact form for my website. Once the user clicks send, I want to display the text "Sending Message..." with the dots on the end animated. (First no dots, then one, then two, then three, then back to none, etc). Then once the email sends, I want the message to change to "Message Sent."

The following Javascript does that:



var msg = "Sending Message...";
var L = msg.length - 3;
var i=0;
var msgSent = false;
var msg_h;
var newMsg;

var posSet = false;

// sets the position of the text so that it appears centered.
function setPos()
{
posSet = true;
var w = msg_h.offsetWidth;
var l = Math.round((600 - w)/2);
document.getElementById("msg_wrapper").style.left = l + "px";
}

// recursive function to animate text.
function animateMsg()
{
if (!msgSent)
{
newMsg = msg.substring(0, L + i);
}
else
{
newMsg = "Message Sent!";
i = -1;
}

if (document.body.firstChild.nodeValue)
{
msg_h.firstChild.nodeValue = newMsg;
if (!posSet) setPos();
}
else if (document.body.innerHTML)
{
msg_h.innerHTML = newMsg;
if (!posSet) setPos();
}
else if (msgSent)
{
document.write("<div style='font-weight: bold;'>Message Sent!</div>");
i = -1;
}

if (i != -1)
{
i = (i + 1) &#37; 4;
setTimeout("animateMsg()", 333);
}
else
{
setPos();
}
}

// start the animation
function startAn()
{
msg_h = document.getElementById("msg_wrapper");
animateMsg();
}

// stop the animation and display "Message Sent."
function stopAn()
{
msgSent = true;
}


Calling the function startAn() starts the text animation. Calling the function stopAn() stops it. This works in every web browser I've tested.

Now the problem:

The stopAn() function is called by the body's onload event. The startAn() function is called just before the php code that sends the message is executed. Here's that section of the php code:



<?php

$showForm = true;

$msg = "";
$sub = "";
$email = "";

if (isset($_POST['send']))
{
$msg = $_REQUEST['message'];
$sub = $_REQUEST['subject'];
$email = $_REQUEST['email'];

echo '
<div id="msg_wrapper"> </div>
<script type="text/javascript">startAn();</script>
';

$msg = stripslashes($msg);
$msg .= "\r\n\r\nMessage sent via contact form.";
$msg .= "\r\nIP address: $REMOTE_ADDR";

mail( "blake@blake-foster.com", $sub,
$msg, "From: $email" );

}
else
{
echo'
<form name="contact" action="' . $_SERVER['PHP_SELF'] . '" method="post" onsubmit="return validate(this)">
Your Email Address:<br>
<input name="email" size="30" type="text" value=""><br>
Message Subject:<br>
<input name="subject" size="30" type="text"><br>
Message:<br>
<textarea name="message" rows="15" cols="40"> </textarea><br>
<input value="Send!" type="submit" name="send">
</form>
';
}

?>


The problem is that in Opera, while the server is sending the message, the animation doesn't work. While the message is sending, the text "Sending" is displayed. Then once the message is sent the animation works for a split second before the stopAn() function is called.

On top of that, if I call setTimeout('stopAn()', 3000) instead of stopAn() as the onload event, the animation will start working once the email is sent and continue to work for 3 seconds (until stopAn() is called).

I only have this problem in Opera. It works perfectly in every other web browser.

Any ideas?

Here's the url of the page:

http://www.blake-foster.com/contact.php

jscheuer1
02-28-2007, 04:18 AM
My advice would be to first simplify the code down as much as possible while still having it exhibit the problem that you are talking about.

Like, forget about actually sending anything or even loading a page if possible. Once you get to the root of what is causing the trouble it will be much easier to remedy.

Or, in Opera, skip the animation or use a .gif - it sounds as though the rest is working fine in that browser.

Remember that the goal isn't to have your page(s) work and/or look identical in all browsers. It is to have them work and look OK in all browsers.

php-5
02-28-2007, 04:21 AM
Sorry I cant help you but I just want to say that your site is the craziest thing I have seen. Good Job man Blake.

Twey
02-28-2007, 05:19 PM
It is a rather impressive site, although "none" isn't a character encoding:
Content-Type: text/html; charset=noneYou succeeded in confusing the heck out of the validator (http://validator.w3.org/check?uri=http&#37;3a%2f%2fwww%2eblake-foster%2ecom%2f) :D

As for the script, here's a simplified version:
var CyclingDots = {
'dotnodes' : [],
'maxdots' : 3,
'mindots' : 1
};

CyclingDots.init = function() {
for(var i = 0, e = document.getElementsByTagName("*") || document.all; i < e.length; ++i)
if(e[i].className.indexOf("cycling-dots") !== -1)
dotnodes.push(e[i].appendChild(document.createTextNode("")));
CyclingDots.currdots = CyclingDots.mindots;
CyclingDots.cycle();
CyclingDots.currdots = CyclingDots.mindots;
CyclingDots.interval = null;
};

CyclingDots.startCycling = function() {
if(!interval)
interval = setInterval(CyclingDots.cycle, 500);
};

CyclingDots.stopCycling = function() {
if(CyclingDots.interval) {
clearInterval(CyclingDots.interval);
CyclingDots.interval = null;
}
};

CyclingDots.cycle = function() {
var dots = '';
for(var i = 0; i < CyclingDots.currdots; ++i)
dots += '.';

for(var i = 0, e = CyclingDots.dotnodes; i < e.length; ++i)
e[i].nodeValue = dots;

if(CyclingDots.currdots++ > CyclingDots.numdots)
CyclingDots.currdots = CyclingDots.mindots;
};

Blake
02-28-2007, 08:41 PM
Thanks! That helps a lot. I don't know much about using the DOM yet, so I don't follow everything in that code, but I'll figure it out.


It is a rather impressive site, although "none" isn't a character encoding:You succeeded in confusing the heck out of the validator (http://validator.w3.org/check?uri=http&#37;3a%2f%2fwww%2eblake-foster%2ecom%2f) :D


Yep, unfortunately I don't have any control over that. It took me awhile to figure out that the server was the reason my page wouldn't validate.

Twey
02-28-2007, 09:43 PM
Can you use .htaccess files or an equivalent on your server? If so, you can use that to specify a character encoding. Another possibility is using a server-side scripting language of some type, although this can be cumbersome.

The <meta> tag you've got in the pages at the moment is redundant: it's overridden by the "none" the server specifies.

Blake
03-02-2007, 05:58 PM
I finally went with an animated gif, mainly because I got a really cool idea:

http://www.blake-foster.com/wave.gif

It looks better on a dark background. It goes with the theme of my page more than the animated dots, I think.

Now, to handle changing the message to "Message Sent!" in the end:



<div id="msg_wrapper"><div>Sending Message</div> <img src="wave.gif" alt=""></div>
<div id="msg_sent">Message Sent!</div>


I put both messages in divs. In my stylesheet, the first has display: block and the second had display: none.

Finally, the function to switch the message:



function msgSent()
{
document.getElementById("msg_wrapper").style.display = "none";
document.getElementById("msg_sent").style.display = "block";
}

jscheuer1
03-02-2007, 09:19 PM
That's cute and, one of my initial suggestions. Glad it's working out for you!