View Full Version : How do I make 2 scripts run at once?

03-07-2012, 10:53 AM
Hi guys!
I have a situation where 2 scripts run perfectly when run independently
- the first one loads up a "video", running at 30 fps, made up of images,
the second one uses accelerometer data from the iPhone to throw a
blue sphere around the screen, depending on movement of the iPhone.

However, when I put these 2 scripts inside one HTML page, the "video"
runs, but the blue sphere is "frozen" - but the scripts are still the same
(one inside the head, as before, and the other in the body, again as before)

How can I get them to run in a parallel way?
I'd be very pleased indeed if someone could come up with a solution!!
Here's the complete code:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<title>Accelerometer Javascript Test</title>
<link rel="stylesheet" href="app.css" type="text/css">
<meta name=viewport content="width=device-width,user-scalable=yes"/>
<!--<meta name="viewport" content="initial-scale=1.6; maximum-scale=1.0; width=device-width; "/>-->

<meta name="apple-mobile-web-app-capable" content="yes" />

<meta name="apple-mobile-web-app-status-bar-style" content="black" />
body {
#sphere {
position: absolute;
width: 20px;
height: 20px;
border-radius: 50px;
-webkit-radius: 50px;
background-color: blue;
left: 161px;
top: 207px;
<script type="text/javascript">

var frames = new Array();

//load frames into array
for(var i = 0; i < 176; i++){
frames[i] = new Image(480,320);
frames[i].src ="images/track" + (i+1) + ".png";

var currentFrameNumber = 0;
var fps = 30; // frames / second
const speed = 1000 / fps; // milliseconds
//var speed = 33;

function nextFrame( )
document.getElementById("display").src = frames[currentFrameNumber].src;
currentFrameNumber = ( currentFrameNumber + 1 ) % frames.length;
setTimeout( nextFrame, speed );
window.onload = nextFrame;

<script type="text/javascript">

var x = 0, y = 0,
vx = 0, vy = 0,
ax = 0, ay = 0;

var sphere = document.getElementById("sphere");

if (window.DeviceMotionEvent != undefined) {
window.ondevicemotion = function(e) {
ax = event.accelerationIncludingGravity.x * 5;
ay = event.accelerationIncludingGravity.y * 5;
document.getElementById("accelerationX").innerHTML = e.accelerationIncludingGravity.x;
document.getElementById("accelerationY").innerHTML = e.accelerationIncludingGravity.y;
document.getElementById("accelerationZ").innerHTML = e.accelerationIncludingGravity.z;

if ( e.rotationRate ) {
document.getElementById("rotationAlpha").innerHTML = e.rotationRate.alpha;
document.getElementById("rotationBeta").innerHTML = e.rotationRate.beta;
document.getElementById("rotationGamma").innerHTML = e.rotationRate.gamma;

setInterval( function() {
var landscapeOrientation = window.innerWidth/window.innerHeight > 1;
if ( landscapeOrientation) {
vx = vx + ay;
vy = vy + ax;
} else {
vy = vy - ay;
vx = vx + ax;
vx = vx * 0.98;
vy = vy * 0.98;
y = parseInt(y + vy / 50);
x = parseInt(x + vx / 50);


sphere.style.top = y + "px";
sphere.style.left = x + "px";

}, 25);

function boundingBoxCheck(){
if (x<0) { x = 0; vx = -vx; }
if (y<0) { y = 0; vy = -vy; }
if (x>document.documentElement.clientWidth-20) { x = document.documentElement.clientWidth-20; vx = -vx; }
if (y>document.documentElement.clientHeight-20) { y = document.documentElement.clientHeight-20; vy = -vy; }


<img id="display"src="images/track1.png" width="480" height="320">
<div id=content>
<div id="sphere"></div>

03-07-2012, 10:49 PM
The first function starts, I assume, with the onload=nextFrame.
Where is the second function (within the body) started? :confused:

03-07-2012, 11:18 PM
I'm pretty sure functions called with setTimeout() or setInterval() run in parallel streams to the rest of the javascript, so that might be one option.

03-08-2012, 01:44 AM
Thanks, guys, for your replys.
As for the second function starting - this is with ondevicemotion.event ie
when the iPhone accelerometer is moved in any direction, then an event is
triggered. This is checked for about 50 times a second..
I know that 2 scripts aren't supposed to run at once, but I would have thought
there was some way of creating just the one script which loaded the next image, say, then checked the accelerometer readings.
Anyone any ideas as to how this could be achieved??
Thanks again,

03-08-2012, 02:06 AM
The only reason they wouldn't both work on the same page if they both work when separate is if they both try to use the same thing for something and one overwrites what the other needs. You need to figure out what that is in order to change it in one of the scripts - or alternatively reqrite the scripts so that they are unobtrusive and so can't clash with anything else.

03-08-2012, 10:29 AM
Thanks for the advice! Yes, I've just read about the same thing - maybe variables with the same name etc.
Also, I've come across this advice - does anyone think this will work in my
particular situation?

I'm not quite sure if this applies to my page, as I have one script in the Body part, and one in the Head section??
Any thoughts, anyone? I'll have a look again at my page for possible conflicts..

03-08-2012, 10:57 AM
Just to update - I've tried finding any conflicts, but all variables are named
differently, and I've also tried the method mentioned in the link in my last reply, but that just freezes everything up.
So I'm puzzled - especially as one function is called by onload.window ie page re-fresh, and the other by the ondevicemotion ie the movement of the iPhone itself, so they are independent!!
Anyone any other ideas?
Thanks again for the replies.

03-08-2012, 11:45 AM
Right - I've just run it again, using Safari's Debug - and the error what occurs again and again, and again is "TypeError - "null" is not an object".
Is it related to these lines in the code?:
if (window.DeviceMotionEvent != undefined) {
window.ondevicemotion = function(e) {

03-08-2012, 08:54 PM
You said that the 2 scripts run perfectly when run independently?

The 2nd script will not work alone as it is accessing the 'sphere' element when that element has not loaded yet.

<script type="text/javascript">
var sphere = document.getElementById("sphere");
<div id="sphere"></div>
Move the whole script below the 'sphere' element just before the end </body> tag and it will work.

03-09-2012, 02:02 AM
Wow!! That worked!!! I'm amazed - because with the same order before, it definitely ran independently. I'm sure the addition of the "video" script must have shown up this anomaly..

03-09-2012, 06:39 AM
Glad to help. :)

03-09-2012, 08:38 PM
The best place to put all JavaScript is immediately before the </body> tag.

Not only does that ensure that any parts of the page the script tries to reference have already loaded before the script runs, it also helps the page to load faster.

Modern web browsers can load up to eight fines at a time as long as none of them contain JavaScript. When a JavaScript file is to be loaded the browser waits until all the currently loading files finish loading and then loads the JavaScript file by itself. Other files then have to wait for the JavaScript to finish loading before they can start loading. So by letting all the other files finish loading first they can all load eight at a time which loads them a lot faster than if you loaded them one or two at a time.

There is an optional async attribute that can be added to script tags to allow them to be loaded concurrently with other files but most browsers don't yet understand it. Also if you use that attribute then you are confirming that the script does not contain any document.write statements (not that a script written after 2005 ought to contain any of those anyway).