Solved

How can I get my Javascript sound Function to work properly from the onload event in the <body> tag in Firefox and IE?

Posted on 2008-10-16
6
443 Views
Last Modified: 2013-12-07
I'm using a stock Dreamweaver timeline to fire a series of events in sequence (including an animate function and a sound file). The animate function works perfectly but the sound refuses to work in any browser except Apple's Safari. I isolated the sound function, and it works fine in any browser when triggered by an onclick or onmouseover event, but only in Safari from the onload (regardless of whether it's fired from the Timeline array or not). I've asked several people and no-one can come up with anything except a possible timing issue... but their only solution was build the whole thing in Flash (which I'd rather not do).

So the question is: What am I missing, and how do I fix it?

Thanks in advance for any help you folks can give me.
<script type="text/javascript">
<!--
function MM_preloadImages() { //v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}
 
function MM_findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}
 
function MM_swapImage() { //v3.0
  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}
 
function animate(elementID, newLeft, newTop, newWidth, 
      newHeight, time, callback)
{
  var el = document.getElementById(elementID);
  if(el == null)
    return;
 
  var cLeft = parseInt(el.style.left);
  var cTop = parseInt(el.style.top);
  var cWidth = parseInt(el.style.width);
  var cHeight = parseInt(el.style.height);
  
  var totalFrames = 1;
  if(time> 0)
    totalFrames = time/40;
 
  var fLeft = newLeft - cLeft;
  if(fLeft != 0)
    fLeft /= totalFrames;
  
  var fTop = newTop - cTop;
  if(fTop != 0)
    fTop /= totalFrames;
  
  var fWidth = newWidth - cWidth;
  if(fWidth != 0)
    fWidth /= totalFrames;
  
  var fHeight = newHeight - cHeight;
  if(fHeight != 0)
    fHeight /= totalFrames;
    
  doFrame(elementID, cLeft, newLeft, fLeft, 
      cTop, newTop, fTop, cWidth, newWidth, fWidth, 
      cHeight, newHeight, fHeight, callback);
}
 
function doFrame(eID, cLeft, nLeft, fLeft,
      cTop, nTop, fTop, cWidth, nWidth, fWidth, 
      cHeight, nHeight, fHeight, callback)
{
   var el = document.getElementById(eID);
   if(el == null)
     return;
 
  cLeft = moveSingleVal(cLeft, nLeft, fLeft);
  cTop = moveSingleVal(cTop, nTop, fTop);
  cWidth = moveSingleVal(cWidth, nWidth, fWidth);
  cHeight = moveSingleVal(cHeight, nHeight, fHeight);
 
  el.style.left = Math.round(cLeft) + 'px';
  el.style.top = Math.round(cTop) + 'px';
  el.style.width = Math.round(cWidth) + 'px';
  el.style.height = Math.round(cHeight) + 'px';
  
  if(cLeft == nLeft && cTop == nTop && cHeight == nHeight 
    && cWidth == nWidth)
  {
    if(callback != null)
      callback();
    return;
  }
    
  setTimeout( 'doFrame("'+eID+'",'+cLeft+','+nLeft+','+fLeft+','
    +cTop+','+nTop+','+fTop+','+cWidth+','+nWidth+','+fWidth+','
    +cHeight+','+nHeight+','+fHeight+','+callback+')', 40);
}
 
function moveSingleVal(currentVal, finalVal, frameAmt)
{
  if(frameAmt == 0 || currentVal == finalVal)
    return finalVal;
  
  currentVal += frameAmt;
  if((frameAmt> 0 && currentVal>= finalVal) 
    || (frameAmt <0 && currentVal <= finalVal))
  {
    return finalVal;
  }
  return currentVal;
}
 
function EvalSound(soundobj) {
  var thissound=document.getElementById(soundobj);
  thissound.Play();
}
 
function MM_timelinePlay(tmLnName, myID) { //v1.2
  //Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Macromedia, Inc. All rights reserved.
  var i,j,tmLn,props,keyFrm,sprite,numKeyFr,firstKeyFr,propNum,theObj,firstTime=false;
  if (document.MM_Time == null) MM_initTimelines(); //if *very* 1st time
  tmLn = document.MM_Time[tmLnName];
  if (myID == null) { myID = ++tmLn.ID; firstTime=true;}//if new call, incr ID
  if (myID == tmLn.ID) { //if Im newest
    setTimeout('MM_timelinePlay("'+tmLnName+'",'+myID+')',tmLn.delay);
    fNew = ++tmLn.curFrame;
    for (i=0; i<tmLn.length; i++) {
      sprite = tmLn[i];
      if (sprite.charAt(0) == 's') {
        if (sprite.obj) {
          numKeyFr = sprite.keyFrames.length; firstKeyFr = sprite.keyFrames[0];
          if (fNew >= firstKeyFr && fNew <= sprite.keyFrames[numKeyFr-1]) {//in range
            keyFrm=1;
            for (j=0; j<sprite.values.length; j++) {
              props = sprite.values[j]; 
              if (numKeyFr != props.length) {
                if (props.prop2 == null) sprite.obj[props.prop] = props[fNew-firstKeyFr];
                else        sprite.obj[props.prop2][props.prop] = props[fNew-firstKeyFr];
              } else {
                while (keyFrm<numKeyFr && fNew>=sprite.keyFrames[keyFrm]) keyFrm++;
                if (firstTime || fNew==sprite.keyFrames[keyFrm-1]) {
                  if (props.prop2 == null) sprite.obj[props.prop] = props[keyFrm-1];
                  else        sprite.obj[props.prop2][props.prop] = props[keyFrm-1];
        } } } } }
      } else if (sprite.charAt(0)=='b' && fNew == sprite.frame) eval(sprite.value);
      if (fNew > tmLn.lastFrame) tmLn.ID = 0;
  } }
}
 
 
 
function MM_changeProp(objId,x,theProp,theValue) { //v9.0
  var obj = null; with (document){ if (getElementById)
  obj = getElementById(objId); }
  if (obj){
    if (theValue == true || theValue == false)
      eval("obj.style."+theProp+"="+theValue);
    else eval("obj.style."+theProp+"='"+theValue+"'");
  }
}
 
function MM_effectAppearFade(targetElement, duration, from, to, toggle)
{
	Spry.Effect.DoFade(targetElement, {duration: duration, from: from, to: to, toggle: toggle});
}
 
function MM_showHideLayers() { //v9.0
  var i,p,v,obj,args=MM_showHideLayers.arguments;
  for (i=0; i<(args.length-2); i+=3) 
  with (document) if (getElementById && ((obj=getElementById(args[i]))!=null)) { v=args[i+2];
    if (obj.style) { obj=obj.style; v=(v=='show')?'visible':(v=='hide')?'hidden':v; }
    obj.visibility=v; }
}
 
function MM_timelineStop(tmLnName) { //v1.2
  //Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Macromedia, Inc. All rights reserved.
  if (document.MM_Time == null) MM_initTimelines(); //if *very* 1st time
  if (tmLnName == null)  //stop all
    for (var i=0; i<document.MM_Time.length; i++) document.MM_Time[i].ID = null;
  else document.MM_Time[tmLnName].ID = null; //stop one
}
 
function MM_initTimelines() { //v4.0
    //MM_initTimelines() Copyright 1997 Macromedia, Inc. All rights reserved.
    var ns = navigator.appName == "Netscape";
    var ns4 = (ns && parseInt(navigator.appVersion) == 4);
    var ns5 = (ns && parseInt(navigator.appVersion) > 4);
    var macIE5 = (navigator.platform ? (navigator.platform == "MacPPC") : false) && (navigator.appName == "Microsoft Internet Explorer") && (parseInt(navigator.appVersion) >= 4);
    document.MM_Time = new Array(1);
    document.MM_Time[0] = new Array(5);
    document.MM_Time["Timeline1"] = document.MM_Time[0];
    document.MM_Time[0].MM_Name = "Timeline1";
    document.MM_Time[0].fps = 15;
    document.MM_Time[0][0] = new String("sprite");
    document.MM_Time[0][0].slot = 1;
    if (ns4)
        document.MM_Time[0][0].obj = document["LogoFade"] ? document["LogoFade"].document["LogoFadeImage"] : document["LogoFadeImage"];
    else if (ns5)
        document.MM_Time[0][0].obj = document.getElementById("LogoFadeImage");
    else
        document.MM_Time[0][0].obj = document["LogoFadeImage"];
    document.MM_Time[0][0].keyFrames = new Array(1, 91);
    document.MM_Time[0][0].values = new Array(0);
    document.MM_Time[0][1] = new String("behavior");
    document.MM_Time[0][1].frame = 25;
    document.MM_Time[0][1].value = "EvalSound('airLock');animate('LogoFadeImage',179,294,56,69,3000,null)";
    document.MM_Time[0][2] = new String("behavior");
    document.MM_Time[0][2].frame = 75;
    document.MM_Time[0][2].value = "MM_effectAppearFade('LogoFade', 1000, 100, 0, false)";
    document.MM_Time[0][3] = new String("behavior");
    document.MM_Time[0][3].frame = 90;
    document.MM_Time[0][3].value = "MM_showHideLayers('LogoFade','','hide')";
    document.MM_Time[0][4] = new String("behavior");
    document.MM_Time[0][4].frame = 91;
    document.MM_Time[0][4].value = "MM_timelineStop('Timeline1')";
    document.MM_Time[0].lastFrame = 91;
    for (i=0; i<document.MM_Time.length; i++) {
        document.MM_Time[i].ID = null;
        document.MM_Time[i].curFrame = 0;
        document.MM_Time[i].delay = 1000/document.MM_Time[i].fps;
    }
}
//-->
</script>
</head>
 
<body onload="MM_preloadImages('targetshieldInc Graphics/corporatePlaceholder.jpg','targetshieldInc Graphics/businessPlaceholder.jpg','targetshieldInc Graphics/industrialPlaceholder.jpg','targetshieldInc Graphics/commercialPlaceholder.jpg','targetshieldInc Graphics/executivePlaceholder.jpg','targetshieldInc Graphics/personalPlaceholder.jpg','targetshieldInc Graphics/cameraPlaceholder.jpg');MM_timelinePlay('Timeline1')">
<!--  Any section that appears after this series of symbols is a comment, instructions that do not affect the behavior, appearance or structure of the page. All instructions for modifying the content will be contained within these comment blocks   -->
<div id="LogoFade">
	<div id="positionlock">
  <div id="imageContainer"> <img style="position:relative;width:412px;height:520px;top:0px;left:0px;background:black;" src="targetshieldInc Graphics/shieldLogo3.png" alt="main logo" id="LogoFadeImage" />
  
  <embed src="airlock.wav" width="0" height="0" autostart="false" id="airLock" enablejavascript="true"></embed>
  
  </div></div>
</div>

Open in new window

0
Comment
Question by:KTMC
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
6 Comments
 
LVL 44

Expert Comment

by:scrathcyboy
ID: 22737277
don't put it all in flash, it limits your page too much.

To make a sound file run guaranteed in any environment, embed it in the background of a table, page or as part of a DIV -- don't try to do it onLoad -- because any of the page elements that will load it, WILL load it as they are read by the HTML interpreter, in sequence.

www.pageresource.com/html/embed.htm
webdesign.about.com/od/sound/ht/htsound.htm
www.webreference.com/js/column20/embed.html
www.htmlgoodies.com/tutorials/web_graphics/article.php/3479901

So just use the normal EMBED tag, and don't try to sequence it.  If you want it delayed, then create a timer at the END of the page in javascript, to pause so many seconds, and then load the sound file.
0
 
LVL 2

Author Comment

by:KTMC
ID: 22737339
It is embedded in a div, the javascript is just to control it. (the embed is at the bottom of the code snippet I included). As I explained in my question I can get the sound file to run fine in any environment and from any event trigger except from the onload. The problem isn't with the Timeline (which works fine for every other function that I pass through it) the problem seems to be with the audio trigger itself or with the onload event. I could add a timer and fire the animation and sound from there (as they fire at the same time) but there are other items that function from the timeline array later in the sequence (so I'd just be increasing the amount of code and have to fiddle endlessly to get the other events timed right with the timeline that controls the other actions) and there's no guarantee that they wouldn't load in different sequences on different browsers...


0
 
LVL 44

Expert Comment

by:scrathcyboy
ID: 22737391
The <BODY onLoad():>

function generally won't work for sound, because it needs to be loaded after the page is loaded, not before.

I think you may be  missing the simplest and most obvious solution -- put javascript at the END of the page,  to load the sound file.  If this javascript is at the end of the page, it will run when the page has been loaded, as soon as all HTML code is finished
0
To Patch or not to Patch? That is the question!

Don't get caught out like thousands of others around the world in the recent Ransomware Fiasco!
Discuss..
- Why it's not a good idea to wait before Patching
- Sensible approaches to Patching discussed
- Add your feedback, comments and suggestions

 
LVL 2

Author Comment

by:KTMC
ID: 22737477
Ah, so you're suggesting dropping the whole thing in as an inline <script> rather than a call to the <head>. I'm guessing this means that the actual sound itself is loading after the Timeline has already tried to call the function. That makes sense, I suppose I could use window.onload() but that's notoriously unreliable. Sounds like your inline solution is the best option, I'll try it, truthfully I'm so used to leaving the Javascript in the head that I forget it can be inline...

Thanks for the help, I'll let you know if that solves the issue!
0
 
LVL 44

Accepted Solution

by:
scrathcyboy earned 500 total points
ID: 22737571
Not just inline, but at the end of the page, and remember, just javascript, not a function that is called.

last HTML code here
<SCRIPT language="javascript">
<!--
javascript here to run sound
--></SCRIPT>
</BODY>
</HTML>

That is going to run after all the HTML page has loaded.  If you want a 20 second delay, you put a setTimeOut() at that point that calls the JS function to start the sound, so it runs 20 sec after page load.

It is also good to remember to keep all big volumes of JS to the end of the page, it helps SEO to find the read data in your page, indexes quicker and better.
0
 
LVL 2

Author Closing Comment

by:KTMC
ID: 31507008
Thanks again, that solved the issue!
0

Featured Post

Scamming the Scammers!

Have you ever heard of Scam Baiting?
It's a highly entertaining sport that you can participate in.
Introduction to beating scammers at their own game and how you can help
Share your thoughts, ideas and experiences on the topic.
Links to top Anti-Scam resources provided.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

SSL stands for “Secure Sockets Layer” and an SSL certificate is a critical component to keeping your website safe, secured, and compliant. Any ecommerce website must have an SSL certificate to ensure the safe handling of sensitive information like…
Today, the web development industry is booming, and many people consider it to be their vocation. The question you may be asking yourself is – how do I become a web developer?
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

710 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question