PDA

View Full Version : setTimeout & Event Handling



coredumped
06-14-2005, 10:34 PM
I've written a small DHTML test script that uses setTimeout to call some function in a specific interval. Right now all it does is add 1 to the previous number in a textbox on the page, then refreshes that value of the textbox with the new number. It does this every 100ms.
At the same time, I have an event handling function assigned to various events (onmousemove, onmousedown, etc.) on that same page.



<html>
<head>
<script language="javascript">


mouseXPos = 0;
mouseYPos = 0;
m1 = '';
keyCode = 0;

execThread = null
threadDelay = 100;



function updateData(formFieldID)
{
if (document.getElementById(formFieldID).value)
document.getElementById(formFieldID).value = parseInt(document.getElementById(formFieldID).value) + 1;
else
document.getElementById(formFieldID).value = 1;
}


function runThread(formFieldID)
{
if (execThread)
clearTimeout(execThread);

updateData(formFieldID);

execThread = setTimeout("runThread('" + formFieldID + "')",threadDelay);
}




function refreshForm()
{
document.getElementById('MouseXPos').value = mouseXPos;
document.getElementById('MouseYPos').value = mouseYPos;
document.getElementById('MouseButton').value = m1;
document.getElementById('KeyButton').value = keyCode;
}

function handleMouseMove(e)
{
mouseXPos = e.pageX;
mouseYPos = e.pageY;
}

function handleMouseDown(e)
{
m1 = "#";
}

function handleMouseUp(e)
{
m1 = "";
}

function handleKeyDown(e)
{
keyCode = e.which;
}

function handleKeyUp(e)
{
keyCode = '';
}


function handle(e)
{
if (e.type == 'mousemove')
handleMouseMove(e);
else if (e.type == 'mousedown')
handleMouseDown(e);
else if (e.type == 'mouseup')
handleMouseUp(e);
else if (e.type == 'keydown')
handleKeyDown(e);
else if (e.type == 'keyup')
handleKeyUp(e);

refreshForm();
}


function main()
{
runThread('threadValue');
}


document.onmousemove = handle;
document.onmousedown = handle;
document.onmouseup = handle;
document.onkeydown = handle;
document.onkeyup = handle;

</script>
</head>
<body onLoad="main()">

X Pos: <input type="text" id="MouseXPos" size="5"/><br/>
Y Pos: <input type="text" id="MouseYPos" size="5"/><br/>
Button: <input type="text" id="MouseButton" size="3"/><br/>
Key: <input type="text" id="KeyButton" size="3"/><br/><br/>

Thread: <input type="text" id="threadValue" size="5"/>

</body>
</html>


Yes, there is a reason I have a seperate function to refresh the form fields as opposed to updating it directly in 'handleMouseMove' (or any other event handler function).

The problem is that the 'thread' seems to work fine... until you move the mouse. I've even tried this with mouse clicks and constant keypresses on the keyboard and it doesn't seem the have the same problem... only when you move the mouse (and I mean MOVE the mouse... drag it all over the place for 5 seconds kind-of-thing). The thread that updates the value in the textbox field stops completely until the mousemove event is handled.

Anyone have any ideas why this happens and what might be able to be done to remedy it? I appreciate it.

- coredumped.

mwinter
06-16-2005, 01:19 AM
<script language="javascript">The language attribute has long been deprecated in favour of type:


<script type="text/javascript">


function updateData(formFieldID)
{
&#160;&#160;if (document.getElementById(formFieldID).value)
&#160;&#160;&#160;&#160;document.getElementById(formFieldID).value = parseInt(document.getElementById(formFieldID).value) + 1;
&#160;&#160;else
&#160;&#160;&#160;&#160;document.getElementById(formFieldID).value = 1;
}You should seriously consider saving references to objects. It's far more efficient:


function updateData(formFieldId) {
var formField = document.getElementById(formFieldId);

formField.value = +formField.value + 1;
}The unary plus (+) operator is an efficient string-to-number converter. If a string always represents a number (and an empty string is equivalent to zero), then it's a better choice. If you're trying to parse out text (such as units from style sheet properties), then parseInt is better. However, parseInt should always be called with its second radix argument, unless you really want it to determine the radix of the number itself.


function runThread(formFieldID)
{
&#160;&#160;if (execThread)
&#160;&#160;&#160;&#160;clearTimeout(execThread);I really don't see the point in that as timeouts are one-shot events that are automatically cleared when fired.

Be aware that introducing the concept of threads is inappropriate: scripts are not threaded, even to the point of running in the GUI thread of browsers. Timeouts and intervals simply interrupt whatever's executing at the time.


The problem is that the 'thread' seems to work fine... until you move the mouse.Other than efficiency problems, I can't see any particular issues with the code, and nor do I experience any.

If efficiency isn't the issue, then I doubt I can help you as it's next to impossible to solve something one can't see.

Mike

coredumped
06-16-2005, 03:54 PM
Thanks for your input Mike.

Last night I went back and ran the exact same code and it didn't seem to have any problems whatsoever, so perhaps the problem I was experiencing was a hiccup with the browser at the time (Firefox 1.0.4). Not entirely out of the question since I've been having a lot of problems with Firefox crashing and whatnot on my system.

I know this isn't really 'threading' per se, but for lack of a better word, I just called it as such.

If anyone else has anything else to add, please feel free. :)

- coredumped.



[UPDATE: 06/16/2005]:
Turns out I'm STILL having problems with the 'thread' stopping whenever I move the mouse. I tried removing the clearTimeout() call as Mike outlined above, and while it hasn't made it any worse, it hasn't made anything better either.
But I *do* know that I used it last night and it seemed to work fine (and I believe that was in a Windows environment... believe it or not), but today under Linux it still has that problem.

Anyone else encounter this with the original code posted above?

- coredumped.