Wednesday, 2 April 2008

Javascript: How to preload audio by Windows Media Player with code sample

In my last article I explained how to preload images by HTML IMG element and javascript. Now I am going to show you the way to preload the audio.

This skill is used for one of our client. In the SCORM course we created for this client there are lots of background audio clips. Our client want the audio could be playing automatically without any delay when user go into the particular page, which means we have to preload all the audio clips at the very beginning for further using. In this case, I am using Windows Media Player to preload all the audios.

To do so, obviously we have to create a WMP object, hide it, set its autostart parameter to ture and set its mute to true. And then in the HTML page onload event, we transfer all the audio clip files one by one to the media player, and monitor the downloaded percentage and current status values of media player to refresh the progress bar. If the media player downloaded 100% I will send another audio to it.

There are two things I have to say. One is the media player downloading and buffering only happened after the HTML page onload event, because before that there is no WMP object at all. This thing is different with image preload rule because the IMG element is a internal HTML object but WMP is not. Another thing is there are two confusing events in WMP, buffering and downloading. In sample way, buffering could be fired more than once but downloading only be fired once and it will stop when WMP downloaded 100% of current file. So downloading is exactly the event we should take care of.

The link followed is a full function sample to preload images and a audio clip (singing in the rain) to your local machine by javascript and WMP, which is my personal album. Please click my album to try it. It is fully tested on IE7 and Firefox2.

The coding below is the key function to monitor media player running status.

var _currPrecent = 0;
function mediaDetector()
{ 
  var oWMP = document.getElementById("WMP"); 
  if (oWMP.playState == 10) {// state Ready means current URL is unavailable 
    window.clearInterval(_tId); 
    _tId = 0; 
    if (_currMedia >= _totalMedia) { 
      document.getElementById("icontext").innerHTML = _sProgress+"Media Loading... 100%"; 
      window.setTimeout("reLocateHTML()",1000); 
      return; 
    } 
    else { 
      reloadMedia(); 
    } 
  } 
  if (_mediaBuffering && oWMP.network.downloadProgress == 100) { 
    window.clearInterval(_tId); 
    _tId = 0; 
    _mediaBuffering = 0; 
    if (_currMedia >= _totalMedia) { 
      document.getElementById("icontext").innerHTML = _sProgress+"Media Loading... 100%"; 
      window.setTimeout("reLocateHTML()",1000); 
      return; 
    } 
    else { 
      reloadMedia(); 
    } 
  } 
  if (_currPrecent <= oWMP.network.downloadProgress || _currPrecent == 100) { 
    _currPrecent = oWMP.network.downloadProgress; 
    document.getElementById("icontext").innerHTML = _sProgress+"Media Loading... " 
      +Math.round(((_currMedia-1)/_totalMedia)*100)+"%<br/>" 
      +"--Media file "+_currMedia
      +"(total "+_totalMedia+")... "+oWMP.network.downloadProgress+"%";    
  }
}

Thursday, 6 March 2008

Javascript: How to preload images

The first thing you should know is, the body onload event will fire immediately after the browser loads all the html object, or we say html element. This is the key point we use to create the image preload widget.

So first of all, we declare a image array which included all the paths of the images we want to preload. And then we user javascript to create image elements (<img />) for every single image path in the array, and in the image onload event, we insert a function to refresh loading counter. Finally, we insert auto jump function to body onload event to jump to the actually page we want, in this case, it is google.com.

* Please remember the image path has to be an available path, or the image onload event will not fire and the counter will not show the correct percentage. 

The simple code below create a loader page, which will preload 4 images first and then auto jump to google.com. The code was tested on IE7 and FIrefox2.

<html>
<head>
<script type="text/javascript">

var _currImg = 0;
var _totalImg = 0;
var _sURL = "htt"+"p://www.google.com";

var _arrImg = new Array(
  "img_1.jpg",
  "img_2.jpg",
  "img_3.jpg",
  "img_4.jpg"
)

function createHTMLEl()
{
  _totalImg = _arrImg.length;

  h = "<div id='icon' style='position:absolute;left:0px;top:0px;"
    +"width:220px;height:120px;'>"
    +"<div style='width:100%;height:90px;'>"
    +"<span id='icontext' style='font-family:tahoma,arial;font-size:8pt;"
    +"font-weight:bold;'>Graphic Loading... 0%</span>"
    +"<span>&nbsp;&nbsp;&nbsp;</span>"
    +"<img src='load.gif' align='absmiddle'/>"
    +"</div>"
    +"<div style='text-align:center;'>"
    +"<input type='button' value='Skip' onclick='NextPage();'/>"
    +"</div>"
    +"</div>";

  for (var i = 0; i < _arrImg.length; i++)
  {
    h += "<img src='"+_arrImg[i]+"'"
      +"style='visibility:hidden;width:0px;height:0px;'"
      +"onload='refreshProgressBar();'/>";
  }
  document.body.innerHTML += h;
}

function refreshProgressBar()
{
  _currImg += 1;
  if (_currImg < _totalImg) {
    document.getElementById("icontext").innerHTML = "Graphic Loading... "
      +Math.round((_currImg/_totalImg)*100)+"%";
  }
  else {
    document.getElementById("icontext").innerHTML = "Graphic Loading... 99.9%";
  }
}

function resetIconPos()
{
  var o = document.getElementById("icon");
  o.style.left = Math.round((document.body.clientWidth - o.offsetWidth)/2)+"px";
  o.style.top = Math.round((document.body.clientHeight - o.offsetHeight)/2)+"px";
}

function reLocateHTML()
{
  document.getElementById("icontext").innerHTML = "Graphic Loading... 100%";
  window.location.href = _sURL;
}
</script>
</head>
<body onload="reLocateHTML();">
<script type="text/javascript">
createHTMLEl();
resetIconPos();
</script>
</body>
</html>

Saturday, 1 March 2008

Enjoy: Independence Day

Good morning. !@#$% - Good morning.
In less than an hour, aircraft from here will join others from around the world. And you will be launching the largest aerial battle in the history of mankind. Mankind - that ~ word should have new meaning for all of us today. We can't be consumed by our petty differences anymore. We will be united in our common interests. Perhaps its fate that today is the 4th of July, and you will once again be fighting for our freedom, not from tyranny, oppression, or persecution - but from annihilation. We're fighting for our right to live, to exist. And should we win the day, the 4th of July will no longer be known as an American holiday, but as the day when the world declared in one voice: "We will not go quietly into the night! We will not vanish without a fight! We're going to live on! We're going to survive!" Today, we celebrate our Independence Day!

Thursday, 28 February 2008

Enjoy: 2008 Beijing Olympic Games (8th~24th, Aug, 2008)

2008 Beijing Olympic Games start at 8th Aug 2008, there are total 35 sports in the Olympic Games. By the flash shows below, you can see all of these 35 sports icons. If you click any one of these icons, it will link you to the related sport page in 2008 Beijing Olympic Games official website. Enjoy it. :)

Wednesday, 27 February 2008

Javascript: 2 ways to insert new function dynamically

The coding below help you to create and insert new javascript function into a loaded html page. Which is very useful for dynamic external js libs binding. I personally recommend the first way:
function addFunc()
{
var sFunc = ""
+"function myOnUnLoad()"
+"{"
+"alert('unload...');"
+"};"
+"window.document.body.onunload = myOnUnLoad;";

window.eval(sFunc);
}
Second way, by this way you have to write down all your code in a external js file, in this case, let us say myjs.js file:
function addFunc()
{
var o = window.document.createElement("script");
o.type="text/javascript";
o.src="myjs.js";

//if you use o.innerHTML="..." or o.innerText="..." here, you will get a
//runtime error. That is why you have to use a external js file, and use
//o.scr="myjs.js" to insert function code


window.document.getElementsByTagName("head")[0].appendChild(o);
}

//-- code in myjs.js file
window.document.body.onunload = function ()
{
alert("unload...");
}

Javascript: tricky window.open() on IE6

If you write javascript regularly, you must be very familiar with function window.open(), which open an external browser window with particular features (size, position, scroll bars, status bar etc.) This function is supported by almost all the popular browsers (IE6/7, Firefox, Opera and Safari), but I found in one particular case it doesn't work properly on IE6, which is when you try to show a menu bar on the browser window. Followed is the code.
//page1.htm source code <html>
<head>
<title></title>
<script type="text/javascript">
function popup()
{
var style = "width=300,height=300,left=0,top=0,"
+"toolbar=yes,scrollbars=no,resizable=no,menubar=yes,status=yes,location=yes";
var o = window.open("page2.htm","page2",style);
}
</script>
</head>
<body>
click <a href="javascript:void(0);" onclick="popup();">here</a>.
</body>
</html>
////page2.htm source code
<html>
<head>
<title>page two</title>
</head>
<body>
<div style="position:absolute;left:0px;top:0px;
width:300px;height:300px;background-color:yellow;"></div>
</body>
</html>
When I launch page1.htm by all the other browser except IE6, and click the link in the page, it will open page2.htm in a pop-up window with correct clientHeight and clientWidth value, in this case they are 300 and 300. But when I do the same thing by IE6, I got a pop-up window with 19px more height space in the window. And if I switch off the menubar from the javascript code, it works ok. Below is the screenshot of this bug?

Javascript: basic XML object searching

In this case, let's suggest we have already declared a xml node object oXml, the most popular search xPaths are:
//search by attribute
oXml.selectNodes("//tag1/tag2[@id='1' and type='1']");
//search by tag text value
oXml.selectNodes("//tag1/tag2[text='text']");

Javascript: the first dodgy, execute javascript function in browser address bar

In Browser addess bar, type in javascript: and then followed by the javascript function you wanna execute, press enter key. Below is a example.
javascript:alert(document.getElementById("id").outerHTML);