View Full Version : Array value has no properties
1212jtraceur
11-23-2006, 01:34 PM
I'm trying to make a interactive music player. When the user mouses over an image (album art), the content of another div is changed to a span containing information about the respective song. Upon click, the song should play, via an embed tag in another div. Information/URLs about/of these songs are contained in objects in an array, songs.
However, when I mouse over or click, I get
Error: songs[ind] has no properties
Line: 88
and
Warning: reference to undefined property songs[ind]
Line: 88
When I manually call the methods that reference songs using
javascript:showSongInfo(i);
or
javascript:playMusic(i);
with i being 0-13 (inclusive), it works. This leads me to believe that, during dynamic generation of the images, they are being set to use a higher value of i when calling those 2 functions.
The function that does this is:
function fillImagesDiv()
{
var images = document.getElementById('images');
for (var i = 0; i < songs.length; i++)
{
var id = songs[i].id;
var url = songs[i].albumArtUrl;
var info = songs[i].info;
var image = createTextElement('object', info);
image.id = id + 'Image';
image.data = url;
image.onmouseover = function()
{
showSongInfo(i);
};
image.onclick = function()
{
playMusic(i);
};
image.onmouseout = function()
{
showDefaultInfo();
};
var klass = getImageClass(i%width, Math.floor(i/width));
image.className = klass + ' image';
images.appendChild(image);
}
}
I don't see how this could be happening, but hopefully someone else can. My complete code is:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<?xml version="1.0" encoding="utf-8"?>
<!-- This page is designed so that only 'songs', 'width', 'height' must be modified.
---- initialize() dynamically generates HTML based on those 3 variables. -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<title>Music Player</title>
<!-- controls interactive effects (info-display-on-hover's, music-play-on-click's) -->
<script type="text/javascript">
/* <![CDATA[ */
function fillImagesDiv()
{
var images = document.getElementById('images');
for (var i = 0; i < songs.length; i++)
{
var id = songs[i].id;
var url = songs[i].albumArtUrl;
var info = songs[i].info;
var image = createTextElement('object', info);
image.id = id + 'Image';
image.data = url;
image.onmouseover = function()
{
showSongInfo(i);
};
image.onclick = function()
{
playMusic(i);
};
image.onmouseout = function()
{
showDefaultInfo();
};
var klass = getImageClass(i%width, Math.floor(i/width));
image.className = klass + ' image';
images.appendChild(image);
}
}
var width = 4;
var height = 4;
function getImageClass(x, y)
{
var klass = '';
if (x === 0)
{
klass += 'left';
}
else if (x === (width - 1))
{
klass += 'right';
}
if (y === 0)
{
klass += ' top';
}
else if (y === (height - 1))
{
klass += ' bottom';
}
return klass;
}
function createTextElement(name, text)
{
var e = document.createElement(name);
var t = document.createTextNode(text);
e.appendChild(t);
return e;
}
function showSongInfo(ind)
{
var info = createTextElement('span', songs[ind].info);
var infoContainer = document.getElementById('infoContainer');
setFirstChild(infoContainer, info);
}
function showDefaultInfo()
{
var info = createTextElement('span', 'Mouse over album art for song info, click to play music.');
var infoContainer = document.getElementById('infoContainer');
setFirstChild(infoContainer, info);
}
function playMusic(ind)
{
var player = songs[ind].player;
var playerContainer = document.getElementById('playerContainer');
setFirstChild(playerContainer, player);
}
function setFirstChild(parent, child)
{
if (parent.firstChild)
{
parent.replaceChild(child, parent.firstChild);
}
else
{
parent.appendChild(child);
}
}
function Song(id, title, artist, album, url, albumArtUrl)
{
this.id = id;
this.title = title;
this.artist = artist;
this.album = album;
this.url = url;
this.albumArtUrl = albumArtUrl;
this.info = title + ' - ' + artist + ' - ' + album;
var embed = document.createElement('embed');
embed.type = 'audio/mpeg';
embed.src = url;
embed.id = id + 'Player';
embed.className = 'player';
this.player = embed;
// for debugging
this.toString = function()
{
return this.id + '\n' + this.info + '\n' + this.url + '\n' + this.albumArtUrl;
};
}
function getSong(id)
{
for (var i = 0; i < songs.length; i++)
{
if (songs[i].id === id)
{
return songs[i];
}
}
return null;
}
var songs = new Array();
// Initializes songs
var chinaWhite = new Song('chinaWhite', 'He Is Legend', 'China White', 'I Am Hollywood',
'http://www.mydatabus.com/public/1212jtraceur/z/China_White-He_Is_Legend-I_Am_Hollywood.mp3',
'http://passzio.hu/kepek/kristof/he_is_legend.jpg');
songs[0] = chinaWhite;
var mouthMagazine = new Song('mouthMagazine', 'Mouth Like A Magazine', 'Showbread', 'No Sir, Nihilism Is Not Practical',
'http://www.mydatabus.com/public/1212jtraceur/z/Mouth_Like_A_Magazine-Showbread-No_Sir_Nihilism_Is_Not_Practical.mp3',
'http://www.smartpunk.com/product_images/12654.gif');
songs[1] = mouthMagazine;
var myDarkness = new Song('myDarkness', 'My Darkness', 'Destroy The Runner', 'Saints',
'http://www.mydatabus.com/public/1212jtraceur/z/My_Darkness-Destroy_The_Runner-Saints.mp3',
'http://graphics.christianbook.com/g/thumbnail/c/cd38621t.gif');
songs[2] = myDarkness;
var oneManParade = new Song('oneManParade', 'One Man Parade', 'Becoming The Archetype', 'Terminate Damnation',
'http://www.mydatabus.com/public/1212jtraceur/z/One_Man_Parade-Becoming_The_Archetype-Terminate_Damnation.mp3',
'http://www.decoymusic.com/vb/gas/images/5/becomingthearchetype_damnation.jpg');
songs[3] = oneManParade;
var sandstorm = new Song('sandstorm', 'Sandstorm', 'Darude', 'Before The Storm',
'http://www.mydatabus.com/public/1212jtraceur/z/Sandstorm-Darude-Before_The_Storm.mp3',
'http://www.eurodancehits.com/darude_storm.jpg');
songs[4] = sandstorm;
var ichabod = new Song('ichabod', 'Sincerely, Ichabod', 'Project 86', '...And The Rest Will Follow',
'http://www.mydatabus.com/public/1212jtraceur/z/Sincerely_Ichabod-Project_86-And_The_Rest_Will_Follow.mp3',
'http://us.ent1.yimg.com/images.launch.yahoo.com/000/027/365/27365652.jpg');
songs[5] = ichabod;
var coldestHeart = new Song('coldestHeart', 'The Coldest Heart', 'The Classic Crime', 'Albatross',
'http://www.mydatabus.com/public/1212jtraceur/z/The_Coldest_Heart-The_Classic_Crime-Albatross.mp3',
'http://images.emidigitalmedia.com/cover/thumb/094633553620.jpg');
songs[6] = coldestHeart;
var tunak = new Song('tunak', 'Tunak Tunak Tun', 'Daler Mehndi', 'Tunak Tunak Tun...',
'http://www.mydatabus.com/public/1212jtraceur/z/Tunak_Tunak_Tun-Daler_Mehndi-Tunak_Tunak_Tun.mp3',
'http://www.zibamusic.com/images/mojaanlaendo.jpg');
songs[7] = tunak;
var undying = new Song('undying', 'Undying', 'Demon Hunter', 'The Triptych',
'http://www.mydatabus.com/public/1212jtraceur/z/Undying-Demon_Hunter-The_Triptych.mp3',
'http://cover6.cduniverse.com/MuzeAudioArt/600/601933.jpg');
songs[8] = undying;
var walls = new Song('walls', 'Walls', 'Emery', 'The Weak\'s End',
'http://www.mydatabus.com/public/1212jtraceur/z/Walls-Emery-The_Weaks_End.mp3',
'http://www.lyricsmusicsongs.com/images/albums/emery-the-weak-s-end.jpg');
songs[9] = walls;
var whiteNerdy = new Song('whiteNerdy', 'White and Nerdy', 'Weird Al Yankovic', 'Straight Outta Lynwood',
'http://www.mydatabus.com/public/1212jtraceur/z/White_and_Nerdy-Weird_Al_Yankovic-Straight_Outta_Lynwood.mp3',
'http://weirdal.com/images/solcdsm.jpg');
songs[10] = whiteNerdy;
var writingWalls = new Song('writingWalls', 'Writing On The Walls', 'UnderOath', 'Define The Great Line',
'http://www.mydatabus.com/public/1212jtraceur/z/Writing_On_The_Walls-UnderOath-Define_The_Great_Line.mp3',
'http://www.avopolis.gr/core/reviews/underoath%20define%20the%20great%20line.jpeg');
songs[11] = writingWalls;
var suburbiaRuins = new Song('suburbiaRuins', 'Your Little Suburbia is in Ruins', 'August Burns Red', 'Thrill Seeker',
'http://www.mydatabus.com/public/1212jtraceur/z/Your_Little_Surburbia_Is_In_Ruins-August_Burns_Red-Thrill_Seeker.mp3',
'http://www.avopolis.gr/core/reviews/august%20burns%20red%20cover.jpg');
songs[12] = suburbiaRuins;
var liarsenic = new Song('liarsenic', 'Liarsenic', 'Norma Jean', 'O God, The Aftermath',
'http://www.mydatabus.com/public/1212jtraceur/z/Liarsenic-Norma_Jean-O_God_The_Aftermath.mp3',
'http://www.lyricsforall.com/images/albums/1594467844NormaJean_OGodAftermath.jpg');
songs[13] = liarsenic;
/* ]]> */
</script>
<style type="text/css">
/* kill default browser margins and padding */
html, body {margin: 0; padding: 0;}
body
{
color: rgb(255, 255, 255);
background: rgb(0, 0, 0);
}
/* for debugging */
div
{
border: 1px solid rgb(255, 255, 255);
padding: 5px;
}
div#container
{
position: absolute;
top: 10px;
right: 10px;
}
div#images
{
position: absolute;
top: 10px;
left: 10px;
}
div#infoContainer
{
margin-top: 25px;
}
div#playerContainer, embed
{
width: 250px;
}
object.image
{
height: 90px;
width: 90px;
float: left;
margin: 10px;
overflow: hidden;
}
/* no unnecessary margins between outer edges of outer images and inner edge of div#images */
object.left
{
margin-left: 0;
/* ensures that image will be below previous row */
clear: left;
}
object.right {margin-right: 0;}
object.top {margin-top: 0;}
object.bottom {margin-bottom: 0;}
</style>
<script type="text/javascript">
function onload()
{
fillImagesDiv();
showDefaultInfo();
}
document.body.onload = onload();
</script>
</head>
<body>
<!-- basic structure that supports scripting -->
<div id="images"></div>
<div id="container">
<div id="playerContainer"></div>
<div id="infoContainer"></div>
</div>
<noscript>
<p>
Since your user agent (browser) appears to not support JavaScript, or you've disabled it,
you will not be able to view this page as its maker intended for it to be viewed.
This page, like many others, relies on JavaScript for interactivity.
You can either catch up with the rest of the world and get a real browser like
<a href="http://www.mozilla.org/firefox/">Mozilla Firefox</a>,
or you can start trusting people and your common sense and re-enable JavaScript through your user agent preferences.
The maker apologizes for sounding harsh if you currently happen to have little control over how you browse the Internet.
</p>
</noscript>
</body>
</html>
Thanks for your help,
1212jtraceur
1212jtraceur
11-25-2006, 08:49 PM
Never mind, I've solved the problem. However, this seems like the sort of error many people may run into, so I'll post my solution.
I found that when I set onmouseover and onclick, the then-current value of i is not used. Instead, the event finds the current value of i (which is 14, with the loop having finished its iterations). So I had to 'immortalize' the then-current value of i by using another function, so that the current value of i isn't relevant to onmouseover and onclick. Here is what I did:
function fillImagesDiv()
{
var imageContainer = document.getElementById('images');
var images = new Array();
var max = songs.length
for (var i = 0; i < max; i++)
{
var id = songs[i].id;
var url = songs[i].albumArtUrl;
var info = songs[i].info;
var i = i;
images[i] = createTextElement('object', info);
images[i].id = id + 'Image';
images[i].data = url;
var klass = getImageClass(i%width, Math.floor(i/width));
images[i].className = klass + ' image';
imageContainer.appendChild(images[i]);
setInteractivity(i);
}
}
function setInteractivity(index)
{
var info = songs[index].id;
var id = info + 'Image';
var element = document.getElementById(id);
element.onmouseover = function()
{
showSelectedInfo(index);
}
element.onclick = function()
{
selectSong(index);
}
element.onmouseout = function()
{
showDefaultInfo();
}
}
So now my entire code is:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<?xml version="1.0" encoding="utf-8"?>
<!-- This page is designed so that only 'songs', 'width', 'height' must be modified.
---- initialize() dynamically generates HTML based on those 3 variables. -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<title>Music Player</title>
<!-- controls interactive effects (info-display-on-hover's, music-play-on-click's) -->
<script type="text/javascript">
/* <![CDATA[ */
function fillImagesDiv()
{
var imageContainer = document.getElementById('images');
var images = new Array();
var max = songs.length
for (var i = 0; i < max; i++)
{
var id = songs[i].id;
var url = songs[i].albumArtUrl;
var info = songs[i].info;
var i = i;
images[i] = createTextElement('object', info);
images[i].id = id + 'Image';
images[i].data = url;
var klass = getImageClass(i%width, Math.floor(i/width));
images[i].className = klass + ' image';
imageContainer.appendChild(images[i]);
setInteractivity(i);
}
}
function setInteractivity(index)
{
var info = songs[index].id;
var id = info + 'Image';
var element = document.getElementById(id);
element.onmouseover = function()
{
showSelectedInfo(index);
}
element.onclick = function()
{
selectSong(index);
}
element.onmouseout = function()
{
showDefaultInfo();
}
}
var width = 4;
var height = 4;
function getImageClass(x, y)
{
var klass = '';
if (x === 0)
{
klass += 'left';
}
else if (x === (width - 1))
{
klass += 'right';
}
if (y === 0)
{
klass += ' top';
}
else if (y === (height - 1))
{
klass += ' bottom';
}
return klass;
}
function createTextElement(name, text)
{
var e = document.createElement(name);
var t = document.createTextNode(text);
e.appendChild(t);
return e;
}
function showSelectedInfo(index)
{
var info = createTextElement('span', songs[index].info);
var selectInfo = document.getElementById('selectInfo');
setFirstChild(selectInfo, info);
}
function showDefaultInfo()
{
var info = createTextElement('span', 'Mouse over album art for song info, click to play music.');
var selectInfo = document.getElementById('selectInfo');
setFirstChild(selectInfo, info);
}
function selectSong(index)
{
playMusic(index);
showNowPlayingInfo(index);
}
function playMusic(index)
{
var player = songs[index].player;
var playerContainer = document.getElementById('player');
setFirstChild(playerContainer, player);
}
function showNowPlayingInfo(index)
{
var info = createTextElement('span', songs[index].info);
var nowPlayingInfo = document.getElementById('nowPlayingInfo');
setFirstChild(nowPlayingInfo, info);
}
function setFirstChild(parent, child)
{
if (parent.firstChild)
{
parent.replaceChild(child, parent.firstChild);
}
else
{
parent.appendChild(child);
}
}
function Song(id, title, artist, album, url, albumArtUrl, index)
{
this.id = id;
this.title = title;
this.artist = artist;
this.album = album;
this.url = url;
this.albumArtUrl = albumArtUrl;
this.info = title + ' - ' + artist + ' - ' + album;
var embed = document.createElement('embed');
embed.type = 'audio/mpeg';
embed.src = url;
embed.id = id + 'Player';
embed.className = 'player';
this.player = embed;
// for debugging
this.toString = function()
{
return this.id + '\n' + this.info + '\n' + this.url + '\n' + this.albumArtUrl;
};
}
function getSong(id)
{
for (var i = 0; i < songs.length; i++)
{
if (songs[i].id === id)
{
return songs[i];
}
}
return null;
}
var songs = new Array();
// Initializes songs
var chinaWhite = new Song('chinaWhite', 'He Is Legend', 'China White', 'I Am Hollywood', 'http://www.mydatabus.com/public/1212jtraceur/z/China_White-He_Is_Legend-I_Am_Hollywood.mp3', 'http://passzio.hu/kepek/kristof/he_is_legend.jpg');
songs[0] = chinaWhite;
var mouthMagazine = new Song('mouthMagazine', 'Mouth Like A Magazine', 'Showbread', 'No Sir, Nihilism Is Not Practical', 'http://www.mydatabus.com/public/1212jtraceur/z/Mouth_Like_A_Magazine-Showbread-No_Sir_Nihilism_Is_Not_Practical.mp3', 'http://www.smartpunk.com/product_images/12654.gif');
songs[1] = mouthMagazine;
var myDarkness = new Song('myDarkness', 'My Darkness', 'Destroy The Runner', 'Saints', 'http://www.mydatabus.com/public/1212jtraceur/z/My_Darkness-Destroy_The_Runner-Saints.mp3', 'http://graphics.christianbook.com/g/thumbnail/c/cd38621t.gif');
songs[2] = myDarkness;
var oneManParade = new Song('oneManParade', 'One Man Parade', 'Becoming The Archetype', 'Terminate Damnation', 'http://www.mydatabus.com/public/1212jtraceur/z/One_Man_Parade-Becoming_The_Archetype-Terminate_Damnation.mp3', 'http://www.decoymusic.com/vb/gas/images/5/becomingthearchetype_damnation.jpg');
songs[3] = oneManParade;
var sandstorm = new Song('sandstorm', 'Sandstorm', 'Darude', 'Before The Storm', 'http://www.mydatabus.com/public/1212jtraceur/z/Sandstorm-Darude-Before_The_Storm.mp3', 'http://www.eurodancehits.com/darude_storm.jpg');
songs[4] = sandstorm;
var ichabod = new Song('ichabod', 'Sincerely, Ichabod', 'Project 86', '...And The Rest Will Follow', 'http://www.mydatabus.com/public/1212jtraceur/z/Sincerely_Ichabod-Project_86-And_The_Rest_Will_Follow.mp3', 'http://us.ent1.yimg.com/images.launch.yahoo.com/000/027/365/27365652.jpg');
songs[5] = ichabod;
var coldestHeart = new Song('coldestHeart', 'The Coldest Heart', 'The Classic Crime', 'Albatross', 'http://www.mydatabus.com/public/1212jtraceur/z/The_Coldest_Heart-The_Classic_Crime-Albatross.mp3', 'http://images.emidigitalmedia.com/cover/thumb/094633553620.jpg');
songs[6] = coldestHeart;
var tunak = new Song('tunak', 'Tunak Tunak Tun', 'Daler Mehndi', 'Tunak Tunak Tun...', 'http://www.mydatabus.com/public/1212jtraceur/z/Tunak_Tunak_Tun-Daler_Mehndi-Tunak_Tunak_Tun.mp3', 'http://www.zibamusic.com/images/mojaanlaendo.jpg');
songs[7] = tunak;
var undying = new Song('undying', 'Undying', 'Demon Hunter', 'The Triptych', 'http://www.mydatabus.com/public/1212jtraceur/z/Undying-Demon_Hunter-The_Triptych.mp3', 'http://cover6.cduniverse.com/MuzeAudioArt/600/601933.jpg');
songs[8] = undying;
var walls = new Song('walls', 'Walls', 'Emery', 'The Weak\'s End', 'http://www.mydatabus.com/public/1212jtraceur/z/Walls-Emery-The_Weaks_End.mp3', 'http://www.lyricsmusicsongs.com/images/albums/emery-the-weak-s-end.jpg');
songs[9] = walls;
var whiteNerdy = new Song('whiteNerdy', 'White and Nerdy', 'Weird Al Yankovic', 'Straight Outta Lynwood', 'http://www.mydatabus.com/public/1212jtraceur/z/White_and_Nerdy-Weird_Al_Yankovic-Straight_Outta_Lynwood.mp3', 'http://weirdal.com/images/solcdsm.jpg');
songs[10] = whiteNerdy;
var writingWalls = new Song('writingWalls', 'Writing On The Walls', 'UnderOath', 'Define The Great Line', 'http://www.mydatabus.com/public/1212jtraceur/z/Writing_On_The_Walls-UnderOath-Define_The_Great_Line.mp3', 'http://www.avopolis.gr/core/reviews/underoath%20define%20the%20great%20line.jpeg');
songs[11] = writingWalls;
var suburbiaRuins = new Song('suburbiaRuins', 'Your Little Suburbia is in Ruins', 'August Burns Red', 'Thrill Seeker', 'http://www.mydatabus.com/public/1212jtraceur/z/Your_Little_Surburbia_Is_In_Ruins-August_Burns_Red-Thrill_Seeker.mp3', 'http://www.avopolis.gr/core/reviews/august%20burns%20red%20cover.jpg');
songs[12] = suburbiaRuins;
var liarsenic = new Song('liarsenic', 'Liarsenic', 'Norma Jean', 'O God, The Aftermath', 'http://www.mydatabus.com/public/1212jtraceur/z/Liarsenic-Norma_Jean-O_God_The_Aftermath.mp3', 'http://www.lyricsforall.com/images/albums/1594467844NormaJean_OGodAftermath.jpg');
songs[13] = liarsenic;
/* ]]> */
</script>
<style type="text/css">
/* kill default browser margins and padding */
html, body {margin: 0; padding: 0;}
body
{
color: rgb(255, 255, 255);
background: rgb(0, 0, 0);
}
/* for debugging
div
{
border: 1px solid rgb(255, 255, 255);
padding: 5px;
}
*/
div#playContainer
{
float: right;
margin-right: 10px;
margin-top: 10px;
max-width: 250px;
}
embed
{
width: 250px;
}
div#selectContainer
{
float: left;
margin-left: 10px;
margin-top: 10px;
}
div#images
{
float: left;
margin-bottom: 10px;
}
div#selectInfo
{
clear: left;
}
object.image
{
height: 90px;
width: 90px;
float: left;
margin: 10px;
overflow: hidden;
}
/* no unnecessary margins between outer edges of outer images and inner edge of div#images */
object.left
{
margin-left: 0;
/* ensures that image will be below previous row */
clear: left;
}
object.right {margin-right: 0;}
object.top {margin-top: 0;}
object.bottom {margin-bottom: 0;}
</style>
<script type="text/javascript">
function onload()
{
fillImagesDiv();
showDefaultInfo();
}
document.body.onload = onload();
</script>
</head>
<body>
<!-- basic structure that supports scripting -->
<div id="selectContainer">
<div id="images"></div>
<div id="selectInfo"></div>
</div>
<div id="playContainer">
<div id="player"></div>
<span>Now Playing:</span>
<div id="nowPlayingInfo"></div>
</div>
<noscript>
<p>
Since your user agent (browser) appears to not support JavaScript, or you've disabled it,
you will not be able to view this page as its maker intended for it to be viewed.
This page, like many others, relies on JavaScript for interactivity.
You can either catch up with the rest of the world and get a real browser like
<a href="http://www.mozilla.org/firefox/">Mozilla Firefox</a>,
or you can start trusting people and your common sense and re-enable JavaScript through your user agent preferences.
The maker apologizes for sounding harsh if you currently happen to have little control over how you browse the Internet.
</p>
</noscript>
</body>
</html>
and it works as intended!
1212jtraceur
Here's a simplier way to "immortalize the then-current value of i", as you said. Treat your element as an OBJECT, and attach it a new custom PROPERTY (name it whichever you want, but avoid javascript reserved words), and give this proerty the value of i.
Here's a basic example:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script type="text/javascript">
function showIndex(){
var allDivs=document.getElementById('container').getElementsByTagName('div');
for(var i=0;i<allDivs.length;i++){
allDivs[i].ind=i;//attaches a new property, I named it ind, to the object
allDivs[i].onclick=function(){alert(this.ind)}
}
}
onload=showIndex
</script>
</head>
<body>
<div id="container">
<div>click here DIV 0</div>
<div>click here DIV 1</div>
<div>click here DIV 2</div>
</div>
</body>
</html>
1212jtraceur
11-26-2006, 11:00 PM
Wow, that's a lot easier. Why didn't I think of that...?
Thanks,
1212jtraceur
1212jtraceur
11-27-2006, 01:18 AM
I now have a different problem, but the thread title still applies, so I'll post it here.
I'm trying to use css menus (http://meyerweb.com/eric/css/edge/menus/demo.html) to select a song. This is far more open to expansion than is having a 90*90 image for each album. I think I have almost gotten it completed, but I'm getting a pesky error:
Error: array has no properties
Line: 18
The function in question is:
function CSSmenuFromArray(array)
{
// If array is an array of songs, branch to fillElementWithSongLinks(), which creates anchors to play music, rather than creating a sub-menu.
if(array[2] == 'artist')
{
return songLinksFromArray(array);
}
else
{
var ul = document.createElement('ul');
var max = array.length;
for (var i = 0; i < max; i++)
{
var child = array[i];
var li = document.createElement('li');
var anchor = createTextElement('a', child[1]);
anchor.id = child[0];
anchor.class = child[2];
li.appendChild(anchor);
li.appendChild(CSSmenuFromArray(child[3]));
ul.appendChild(li);
}
return ul;
}
}
When the user loads the page, genreList (an array containing arrays representing genres, which contain arrays representing subGenres, which contain arrays representing artists, which contain an array of Songs) is passed to this function.
<!-- Sets document.body.onload -->
<script type="text/javascript">
function onload()
{
///*
document.getElementById('selectContainer').setFirstChild(CSSmenuFromArray(genreList));
anchors();
//*/
/*
for (var i = 0; i < genreList.length; i++)
{
alert(genreList[i]);
}
*/
}
document.body.onload = function()
{
onload();
};
</script>
And that's where I get the error. If I un-comment the commented section and re-comment the un-commented section in the above code, I get the proper information. This, to me, implies that genreList does indeed have properties.
I'm thinking that I'm missing something obvious, as has happened so many times before, but I just cannot see it. My complete code is below, why is this not working?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<?xml version="1.0" encoding="utf-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<title>Music Player</title>
<!-- Used for interactivity. -->
<script type="text/javascript">
function CSSmenuFromArray(array)
{
// If array is an array of songs, branch to fillElementWithSongLinks(), which creates anchors to play music, rather than creating a sub-menu.
if(array[2] == 'artist')
{
return songLinksFromArray(array);
}
else
{
var ul = document.createElement('ul');
ul.id = array[0];
var max = array.length;
for (var i = 0; i < max; i++)
{
var child = array[i];
var li = document.createElement('li');
var anchor = createTextElement('a', child[1]);
anchor.id = child[0];
anchor.class = child[2];
li.appendChild(anchor);
li.appendChild(CSSmenuFromArray(child[3]));
ul.appendChild(li);
}
return ul;
}
}
function songLinksFromArray(array)
{
var ul = document.createElement('ul');
ul.id = array[0];
var max = array.length;
for (var i = 0; i < max; i++)
{
var child = array[i];
var li = document.createElement('li');
var anchor = createTextElement('a', child.title);
anchor.id = child.id
anchor.class = 'songLink';
anchor.href = 'javascript:selectSong(' + child + ');';
li.appendChild(anchor);
ul.appendChild(li);
}
return ul;
}
{
<ul>
<li>
<a>
<ul>
</ul>
</a>
</li>
<li>
<a>
<ul>
</ul>
</a>
</li>
</ul>
}
// wrapper function to play a song and change nowPlayingInfo.
function selectSong(song)
{
playMusic(song);
showNowPlayingInfo(song);
}
// Plays the music file of song by setting the first child of div#player.
function playMusic(song)
{
var player = song.player;
var playerContainer = document.getElementById('player');
setFirstChild(playerContainer, player);
}
function showNowPlayingInfo(song)
{
var info = createTextElement('span', song.info);
var nowPlayingInfoDiv = document.getElementById('nowPlayingInfo');
setFirstChild(nowPlayingInfoDiv, info);
}
// Sets the first child element of parent to be child. If parent has a first child, it is replaced with child.
function setFirstChild(parent, child)
{
if (parent.firstChild)
{
parent.replaceChild(child, parent.firstChild);
}
else
{
parent.appendChild(child);
}
}
// Creates an element of type type and appends a text node with text text.
function createTextElement(type, text)
{
var e = document.createElement(type);
var t = document.createTextNode(text);
e.appendChild(t);
return e;
}
function anchors()
{
var anchors = document.getElementsByTagName('a');
var max = anchors.length;
for (var i = 0; i < max; i++)
{
var a = anchors[i];
if (a.className.indexOf('songLink') == -1)
{
var innerText = a.firstChild.nodeValue;
a.target = '_blank';
a.title = innerText;
a.href = 'http://en.wikipedia.org/wiki/Special:Search?search=' + innerText;
}
}
}
</script>
<!-- Defines the constructors for various objects needed for nested ul generation. -->
<script type="text/javascript">
/* A Song has an id, title, artist, album, and a url of the music file. An info string (this.info) is constructed form title, artist, and album strings. An embed element (this.player) is constructed from the url of the music file. */
function Song(id, title, artist, album, musicFileUrl)
{
this.id = id;
this.title = title;
this.artist = artist;
this.album = album;
this.musicFileUrl = musicFileUrl;
this.info = title + ' - ' + artist + ' - ' + album;
var embed = document.createElement('embed');
embed.type = 'audio/mpeg';
embed.src = musicFileUrl;
embed.id = id + 'Player';
embed.className = 'player';
this.player = embed;
// for debugging
this.toString = function()
{
return this.id + '\n' + this.info + '\n' + this.musicFileUrl;
};
}
</script>
<!-- Constructs the objects needed for nested ul generation -->
<script type="text/javascript">
// Start Song initialization
var chinaWhite = new Song('chinaWhite', 'He Is Legend', 'China White', 'I Am Hollywood', 'http://www.mydatabus.com/public/1212jtraceur/z/China_White-He_Is_Legend-I_Am_Hollywood.mp3');
var mouthMagazine = new Song('mouthMagazine', 'Mouth Like A Magazine', 'Showbread', 'No Sir, Nihilism Is Not Practical', 'http://www.mydatabus.com/public/1212jtraceur/z/Mouth_Like_A_Magazine-Showbread-No_Sir_Nihilism_Is_Not_Practical.mp3');
var myDarkness = new Song('myDarkness', 'My Darkness', 'Destroy The Runner', 'Saints', 'http://www.mydatabus.com/public/1212jtraceur/z/My_Darkness-Destroy_The_Runner-Saints.mp3');
var oneManParade = new Song('oneManParade', 'One Man Parade', 'Becoming The Archetype', 'Terminate Damnation', 'http://www.mydatabus.com/public/1212jtraceur/z/One_Man_Parade-Becoming_The_Archetype-Terminate_Damnation.mp3');
var sandstorm = new Song('sandstorm', 'Sandstorm', 'Darude', 'Before The Storm', 'http://www.mydatabus.com/public/1212jtraceur/z/Sandstorm-Darude-Before_The_Storm.mp3');
var sincerelyIchabod = new Song('sincerelyIchabod', 'Sincerely, Ichabod', 'Project 86', '...And The Rest Will Follow', 'http://www.mydatabus.com/public/1212jtraceur/z/Sincerely_Ichabod-Project_86-And_The_Rest_Will_Follow.mp3');
var coldestHeart = new Song('coldestHeart', 'The Coldest Heart', 'The Classic Crime', 'Albatross', 'http://www.mydatabus.com/public/1212jtraceur/z/The_Coldest_Heart-The_Classic_Crime-Albatross.mp3');
var tunak = new Song('tunak', 'Tunak Tunak Tun', 'Daler Mehndi', 'Tunak Tunak Tun...', 'http://www.mydatabus.com/public/1212jtraceur/z/Tunak_Tunak_Tun-Daler_Mehndi-Tunak_Tunak_Tun.mp3');
var undying = new Song('undying', 'Undying', 'Demon Hunter', 'The Triptych', 'http://www.mydatabus.com/public/1212jtraceur/z/Undying-Demon_Hunter-The_Triptych.mp3');
var walls = new Song('walls', 'Walls', 'Emery', 'The Weak\'s End', 'http://www.mydatabus.com/public/1212jtraceur/z/Walls-Emery-The_Weaks_End.mp3');
var whiteNerdy = new Song('whiteNerdy', 'White and Nerdy', 'Weird Al Yankovic', 'Straight Outta Lynwood', 'http://www.mydatabus.com/public/1212jtraceur/z/White_and_Nerdy-Weird_Al_Yankovic-Straight_Outta_Lynwood.mp3');
var writingWalls = new Song('writingWalls', 'Writing On The Walls', 'UnderOath', 'Define The Great Line', 'http://www.mydatabus.com/public/1212jtraceur/z/Writing_On_The_Walls-UnderOath-Define_The_Great_Line.mp3');
var suburbiaRuins = new Song('suburbiaRuins', 'Your Little Suburbia is in Ruins', 'August Burns Red', 'Thrill Seeker', 'http://www.mydatabus.com/public/1212jtraceur/z/Your_Little_Surburbia_Is_In_Ruins-August_Burns_Red-Thrill_Seeker.mp3');
var liarsenic = new Song('liarsenic', 'Liarsenic', 'Norma Jean', 'O God, The Aftermath', 'http://www.mydatabus.com/public/1212jtraceur/z/Liarsenic-Norma_Jean-O_God_The_Aftermath.mp3');
// End Song initialization
// Start artist initialization
var heIsLegend = ['heIsLegend', 'He Is Legend', 'artist', [liarsenic]];
var showbread = ['showbread', 'Showbread', 'artist', [mouthMagazine]];
var destroyTheRunner = ['destroyTheRunner', 'Destroy The Runner', 'artist', [myDarkness]];
var becomingTheArchetype = ['becomingTheArchetype', 'Becoming The Archetype', 'artist', [oneManParade]];
var darude = ['darude', 'Darude', 'artist', [sandstorm]];
var project86 = ['project86', 'Project 86', 'artist', [sincerelyIchabod]];
var classicCrime = ['classicCrime', 'The Classic Crime', 'artist', [coldestHeart]];
var dalerMehndi = ['dalerMehndi', 'Daler Mehndi', 'artist', [tunak]];
var demonHunter = ['demonHunter', 'Demon Hunter', 'artist', [undying]];
var emery = ['emery', 'Emery', 'artist', [walls]];
var weirdAl = ['weirdAl', 'Weird Al Yankovic', 'artist', [whiteNerdy]];
var underOath = ['underOath', 'UnderOath', 'artist', [writingWalls]];
var augustBurnsRed = ['augustBurnsRed', 'August Burns Red', 'artist', [suburbiaRuins]];
var normaJean = ['normaJean', 'Norma Jean', 'artist', [liarsenic]];
// End artist initialization
// Start subGenre initialization
var dance = ['dance', 'Dance', 'subGenre', [darude]];
var parody = ['parody', 'Parody', 'subGenre', [weirdAl]];
// End subGenre intialization
// Start genre initialization
var electronic = ['electronic', 'Electronic', 'genre', [dance]];
var rap = ['rap', 'Rap', 'genre', [parody]];
var rock = ['rock', 'Rock', 'genre', []];
// End genre initialization
// Initializes genreList, an array of genres.
var genreList = ['genreList', 'Select a genre', 'genreList', [electronic, rap, rock]];
</script>
<style type="text/css">
/* kill browser defaults */
html, body
{
margin: 0;
padding: 0;
background: rgb(0, 0, 0);
color: rgb(192, 255, 0);
}
/* Embed and song info go on the right. */
div#playContainer
{
float: right;
max-width: 250px;
margin: 10px 10px 0 0;
}
/* embed horizantally fills div#playContainer */
div#playContainer > embed
{
width: 100%;
}
/* Menu goes on the left. */
div#selectContainer
{
float: left;
margin: 10px 0 0 10px;
}
/*
Begin interactive menu styling;
Base code from http://meyerweb.com/eric/css/edge/menus/demo.html
*/
/* get rid of spacing and define font */
ul
{
padding: 0;
margin: 0;
font: 1em sans-serif;
}
/* no bullets; green background, black bold text, black border of 1px width, no spacing */
ul li
{
list-style-type: none;
background: rgb(192, 255, 0);
color: rgb(0, 0, 0);
border: 1px solid rgb(0, 0, 0);
border-width: 1px 2px;
font-weight: bold;
width: 11ex;
height: 1.5em;
position: relative;
margin: 0;
padding: 0;
}
/* Nested menus don't display by default. */
ul ul
{
display: none;
}
/* However, they do when the corresponding li is hovered over. */
ul li:hover > ul
{
display: block;
position: absolute;
top: -1px;
left: 100%;
}
ul#genreList li:hover > ul
{
top: 100%;
left: 2px;
}
/* The li itself 'inverts' colors upon hover. */
ul li:hover
{
color: rgb(192, 255, 0);
background: rgb(0, 0, 0);
border: 1px solid rgb(192, 255, 0);
border-width: 1px 2px;
}
/* Anchors are block level, with no text decoration, no overflowing text, and text is centered. */
li a
{
display: block;
text-decoration: none;
text-align: center;
color: inherit;
overflow: hidden;
}
/* End interactive menu styling */
</style>
<!-- Sets document.body.onload -->
<script type="text/javascript">
function onload()
{
///*
document.getElementById('selectContainer').setFirstChild(CSSmenuFromArray(genreList));
anchors();
//*/
/*
for (var i = 0; i < genreList.length; i++)
{
alert(genreList[i]);
}
*/
}
document.body.onload = function()
{
onload();
};
</script>
</head>
<body>
<div id="selectContainer"></div>
<div id="playContainer">
<div id="player"></div>
<span>Now Playing:</span>
<div id="nowPlayingInfo"></div>
</div>
</body>
</html>
david_kw
11-27-2006, 03:15 AM
You have a lot going on there, but just quickly do you mean this?
li.appendChild(CSSmenuFromArray(child[3]));
or should it be array[3]? Or something else?
What seems to happening is child is set to array[0] on the first pass through the CSSmenu... function. array[0] is "genreList" so when it hits the line I put in above it sends "r" in to the function since child = "genreList" then child[3] = "r". Of course that doesn't have any properties which is your error.
Just something to check.
david_kw
david_kw
11-27-2006, 03:32 AM
Looking at it more I think I was wrong. Instead this might be the problem. You are searching through the array passed in instead of the array located in the array passed in. Perhaps this in CSSMenu... should be:
var max = array[3].length;
for (var i = 0; i < max; i++)
{
var child = array[3][i];
At least that would make more sense to me. :)
david_kw
david_kw
11-27-2006, 05:18 AM
It gets further but still runs in to problems.
Basically it looks like you have
function CSSmenuFromArray(array)
where it expects array to be of the form:
[ string, string, string, array ]
But when it goes through once with child[3] it is an array with [ array, array, array ]
I think child is supposed to be recursed in not child[3].
function CSSmenuFromArray(array)
{
// If array is an array of songs, branch to fillElementWithSongLinks(), which creates anchors to play music, rather than creating a sub-menu.
if(array[2] == 'artist')
{
return songLinksFromArray(array);
}
else
{
var ul = document.createElement('ul');
ul.id = array[0];
var max = array[3].length;
for (var i = 0; i < max; i++)
{
var child = array[3][i];
var li = document.createElement('li');
var anchor = createTextElement('a', child[1]);
anchor.id = child[0];
anchor.class = child[2];
li.appendChild(anchor);
li.appendChild(CSSmenuFromArray(child));
ul.appendChild(li);
}
return ul;
}
}
Unfortunately it still dies eventually but it gets further! :)
david_kw
a general note: I see you have an XHTML doctype. Well, XML (thus the XHTML as well) has strict rules of coding. For XML some characters have literal meaning (like < > & ). Unfortunately, Javascript uses those characters as operators, thus you must escape a javascript code inside a CDATA island:
<script type="text/javascript">
/*<![CDATA[*/
... your code here ...
/*]]>*/
</script>
...or, more practical, use an external JS file
david_kw
11-27-2006, 06:47 AM
The only other problems I found were
document.getElementById('selectContainer').setFirstChild(CSSmenuFromArray(genreList));
needs to be turned in to
setFirstChild(document.getElementById('selectContainer'), CSSmenuFromArray(genreList));
since setFirstChild is a stand alone function and not a method of Element.
Plus the document.body.onload thing wasn't working for me so I changed it to window.onload and changed the function name from onload to xonload that it calls.
That will make it load without errors and do something in FF1.5 at least. My copy is below.
Good luck.
david_kw
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<?xml version="1.0" encoding="utf-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<title>Music Player</title>
<!-- Used for interactivity. -->
<script type="text/javascript">
function CSSmenuFromArray(array)
{
// If array is an array of songs, branch to fillElementWithSongLinks(), which creates anchors to play music, rather than creating a sub-menu.
if(array[2] == 'artist')
{
return songLinksFromArray(array);
}
else
{
var ul = document.createElement('ul');
ul.id = array[0];
var max = array[3].length;
for (var i = 0; i < max; i++)
{
var child = array[3][i];
var li = document.createElement('li');
var anchor = createTextElement('a', child[1]);
anchor.id = child[0];
anchor.class = child[2];
li.appendChild(anchor);
li.appendChild(CSSmenuFromArray(child));
ul.appendChild(li);
}
return ul;
}
}
function songLinksFromArray(array)
{
var ul = document.createElement('ul');
ul.id = array[0];
var max = array.length;
for (var i = 0; i < max; i++)
{
var child = array[i];
var li = document.createElement('li');
var anchor = createTextElement('a', child.title);
anchor.id = child.id
anchor.class = 'songLink';
anchor.href = 'javascript:selectSong(' + child + ');';
li.appendChild(anchor);
ul.appendChild(li);
}
return ul;
}
{
<ul>
<li>
<a>
<ul>
</ul>
</a>
</li>
<li>
<a>
<ul>
</ul>
</a>
</li>
</ul>
}
// wrapper function to play a song and change nowPlayingInfo.
function selectSong(song)
{
playMusic(song);
showNowPlayingInfo(song);
}
// Plays the music file of song by setting the first child of div#player.
function playMusic(song)
{
var player = song.player;
var playerContainer = document.getElementById('player');
setFirstChild(playerContainer, player);
}
function showNowPlayingInfo(song)
{
var info = createTextElement('span', song.info);
var nowPlayingInfoDiv = document.getElementById('nowPlayingInfo');
setFirstChild(nowPlayingInfoDiv, info);
}
// Sets the first child element of parent to be child. If parent has a first child, it is replaced with child.
function setFirstChild(parent, child)
{
if (parent.firstChild)
{
parent.replaceChild(child, parent.firstChild);
}
else
{
parent.appendChild(child);
}
}
// Creates an element of type type and appends a text node with text text.
function createTextElement(type, text)
{
var e = document.createElement(type);
var t = document.createTextNode(text);
e.appendChild(t);
return e;
}
function anchors()
{
var anchors = document.getElementsByTagName('a');
var max = anchors.length;
for (var i = 0; i < max; i++)
{
var a = anchors[i];
if (a.className.indexOf('songLink') == -1)
{
var innerText = a.firstChild.nodeValue;
a.target = '_blank';
a.title = innerText;
a.href = 'http://en.wikipedia.org/wiki/Special:Search?search=' + innerText;
}
}
}
</script>
<!-- Defines the constructors for various objects needed for nested ul generation. -->
<script type="text/javascript">
/* A Song has an id, title, artist, album, and a url of the music file. An info string (this.info) is constructed form title, artist, and album strings. An embed element (this.player) is constructed from the url of the music file. */
function Song(id, title, artist, album, musicFileUrl)
{
this.id = id;
this.title = title;
this.artist = artist;
this.album = album;
this.musicFileUrl = musicFileUrl;
this.info = title + ' - ' + artist + ' - ' + album;
var embed = document.createElement('embed');
embed.type = 'audio/mpeg';
embed.src = musicFileUrl;
embed.id = id + 'Player';
embed.className = 'player';
this.player = embed;
// for debugging
this.toString = function()
{
return this.id + '\n' + this.info + '\n' + this.musicFileUrl;
};
}
</script>
<!-- Constructs the objects needed for nested ul generation -->
<script type="text/javascript">
// Start Song initialization
var chinaWhite = new Song('chinaWhite', 'He Is Legend', 'China White', 'I Am Hollywood', 'http://www.mydatabus.com/public/1212jtraceur/z/China_White-He_Is_Legend-I_Am_Hollywood.mp3');
var mouthMagazine = new Song('mouthMagazine', 'Mouth Like A Magazine', 'Showbread', 'No Sir, Nihilism Is Not Practical', 'http://www.mydatabus.com/public/1212jtraceur/z/Mouth_Like_A_Magazine-Showbread-No_Sir_Nihilism_Is_Not_Practical.mp3');
var myDarkness = new Song('myDarkness', 'My Darkness', 'Destroy The Runner', 'Saints', 'http://www.mydatabus.com/public/1212jtraceur/z/My_Darkness-Destroy_The_Runner-Saints.mp3');
var oneManParade = new Song('oneManParade', 'One Man Parade', 'Becoming The Archetype', 'Terminate Damnation', 'http://www.mydatabus.com/public/1212jtraceur/z/One_Man_Parade-Becoming_The_Archetype-Terminate_Damnation.mp3');
var sandstorm = new Song('sandstorm', 'Sandstorm', 'Darude', 'Before The Storm', 'http://www.mydatabus.com/public/1212jtraceur/z/Sandstorm-Darude-Before_The_Storm.mp3');
var sincerelyIchabod = new Song('sincerelyIchabod', 'Sincerely, Ichabod', 'Project 86', '...And The Rest Will Follow', 'http://www.mydatabus.com/public/1212jtraceur/z/Sincerely_Ichabod-Project_86-And_The_Rest_Will_Follow.mp3');
var coldestHeart = new Song('coldestHeart', 'The Coldest Heart', 'The Classic Crime', 'Albatross', 'http://www.mydatabus.com/public/1212jtraceur/z/The_Coldest_Heart-The_Classic_Crime-Albatross.mp3');
var tunak = new Song('tunak', 'Tunak Tunak Tun', 'Daler Mehndi', 'Tunak Tunak Tun...', 'http://www.mydatabus.com/public/1212jtraceur/z/Tunak_Tunak_Tun-Daler_Mehndi-Tunak_Tunak_Tun.mp3');
var undying = new Song('undying', 'Undying', 'Demon Hunter', 'The Triptych', 'http://www.mydatabus.com/public/1212jtraceur/z/Undying-Demon_Hunter-The_Triptych.mp3');
var walls = new Song('walls', 'Walls', 'Emery', 'The Weak\'s End', 'http://www.mydatabus.com/public/1212jtraceur/z/Walls-Emery-The_Weaks_End.mp3');
var whiteNerdy = new Song('whiteNerdy', 'White and Nerdy', 'Weird Al Yankovic', 'Straight Outta Lynwood', 'http://www.mydatabus.com/public/1212jtraceur/z/White_and_Nerdy-Weird_Al_Yankovic-Straight_Outta_Lynwood.mp3');
var writingWalls = new Song('writingWalls', 'Writing On The Walls', 'UnderOath', 'Define The Great Line', 'http://www.mydatabus.com/public/1212jtraceur/z/Writing_On_The_Walls-UnderOath-Define_The_Great_Line.mp3');
var suburbiaRuins = new Song('suburbiaRuins', 'Your Little Suburbia is in Ruins', 'August Burns Red', 'Thrill Seeker', 'http://www.mydatabus.com/public/1212jtraceur/z/Your_Little_Surburbia_Is_In_Ruins-August_Burns_Red-Thrill_Seeker.mp3');
var liarsenic = new Song('liarsenic', 'Liarsenic', 'Norma Jean', 'O God, The Aftermath', 'http://www.mydatabus.com/public/1212jtraceur/z/Liarsenic-Norma_Jean-O_God_The_Aftermath.mp3');
// End Song initialization
// Start artist initialization
var heIsLegend = ['heIsLegend', 'He Is Legend', 'artist', [liarsenic]];
var showbread = ['showbread', 'Showbread', 'artist', [mouthMagazine]];
var destroyTheRunner = ['destroyTheRunner', 'Destroy The Runner', 'artist', [myDarkness]];
var becomingTheArchetype = ['becomingTheArchetype', 'Becoming The Archetype', 'artist', [oneManParade]];
var darude = ['darude', 'Darude', 'artist', [sandstorm]];
var project86 = ['project86', 'Project 86', 'artist', [sincerelyIchabod]];
var classicCrime = ['classicCrime', 'The Classic Crime', 'artist', [coldestHeart]];
var dalerMehndi = ['dalerMehndi', 'Daler Mehndi', 'artist', [tunak]];
var demonHunter = ['demonHunter', 'Demon Hunter', 'artist', [undying]];
var emery = ['emery', 'Emery', 'artist', [walls]];
var weirdAl = ['weirdAl', 'Weird Al Yankovic', 'artist', [whiteNerdy]];
var underOath = ['underOath', 'UnderOath', 'artist', [writingWalls]];
var augustBurnsRed = ['augustBurnsRed', 'August Burns Red', 'artist', [suburbiaRuins]];
var normaJean = ['normaJean', 'Norma Jean', 'artist', [liarsenic]];
// End artist initialization
// Start subGenre initialization
var dance = ['dance', 'Dance', 'subGenre', [darude]];
var parody = ['parody', 'Parody', 'subGenre', [weirdAl]];
// End subGenre intialization
// Start genre initialization
var electronic = ['electronic', 'Electronic', 'genre', [dance]];
var rap = ['rap', 'Rap', 'genre', [parody]];
var rock = ['rock', 'Rock', 'genre', []];
// End genre initialization
// Initializes genreList, an array of genres.
var genreList = ['genreList', 'Select a genre', 'genreList', [electronic, rap, rock]];
</script>
<style type="text/css">
/* kill browser defaults */
html, body
{
margin: 0;
padding: 0;
background: rgb(0, 0, 0);
color: rgb(192, 255, 0);
}
/* Embed and song info go on the right. */
div#playContainer
{
float: right;
max-width: 250px;
margin: 10px 10px 0 0;
}
/* embed horizantally fills div#playContainer */
div#playContainer > embed
{
width: 100%;
}
/* Menu goes on the left. */
div#selectContainer
{
float: left;
margin: 10px 0 0 10px;
}
/*
Begin interactive menu styling;
Base code from http://meyerweb.com/eric/css/edge/menus/demo.html
*/
/* get rid of spacing and define font */
ul
{
padding: 0;
margin: 0;
font: 1em sans-serif;
}
/* no bullets; green background, black bold text, black border of 1px width, no spacing */
ul li
{
list-style-type: none;
background: rgb(192, 255, 0);
color: rgb(0, 0, 0);
border: 1px solid rgb(0, 0, 0);
border-width: 1px 2px;
font-weight: bold;
width: 11ex;
height: 1.5em;
position: relative;
margin: 0;
padding: 0;
}
/* Nested menus don't display by default. */
ul ul
{
display: none;
}
/* However, they do when the corresponding li is hovered over. */
ul li:hover > ul
{
display: block;
position: absolute;
top: -1px;
left: 100%;
}
ul#genreList li:hover > ul
{
top: 100%;
left: 2px;
}
/* The li itself 'inverts' colors upon hover. */
ul li:hover
{
color: rgb(192, 255, 0);
background: rgb(0, 0, 0);
border: 1px solid rgb(192, 255, 0);
border-width: 1px 2px;
}
/* Anchors are block level, with no text decoration, no overflowing text, and text is centered. */
li a
{
display: block;
text-decoration: none;
text-align: center;
color: inherit;
overflow: hidden;
}
/* End interactive menu styling */
</style>
<!-- Sets document.body.onload -->
<script type="text/javascript">
function xonload()
{
setFirstChild(document.getElementById('selectContainer'), CSSmenuFromArray(genreList));
anchors();
/*
for (var i = 0; i < genreList.length; i++)
{
alert(genreList[i]);
}
*/
}
// document.body.onload = function()
window.onload = function()
{
xonload();
};
</script>
</head>
<body>
<div id="selectContainer"></div>
<div id="playContainer">
<div id="player"></div>
<span>Now Playing:</span>
<div id="nowPlayingInfo"></div>
</div>
</body>
</html>
1212jtraceur
11-29-2006, 02:37 AM
Ok, I've implemented both suggestions and improved my code a lot. One improvement is the existence of Category objects, instead of my [string, string, string, array] arrays. The other improvements are far better functions (ListFromCategory, ListItemFromCategory, SongListFromArray) to handle menu list generation.
I'm getting a new type of error
Error: uncaught exception: [Exception... "Component returned failure code: 0x80004003 (NS_ERROR_INVALID_POINTER) [nsIDOMHTMLDivElement.appendChild]" nsresult: "0x80004003 (NS_ERROR_INVALID_POINTER)" location: "JS frame :: (FULL FILE NAME) setFirstChild :: line 172" data: no]
('(FULL FILE NAME)' is the location of my html file)
I have very little knowledge of what this means or of how to fix it. What does it mean, and how do I fix it?
Thanks,
1212jtraceur
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<?xml version="1.0" encoding="utf-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<title>Music Player</title>
<!-- Used for interactivity. -->
<script type="text/javascript">
/* <![CDATA[ */
// Used to debug with conditional alert statements.
function debug(text)
{
var debugp = true;
if (debugp)
{
alert(text);
}
return;
}
/*
Takes a Category and returns a ul element containing the contents of the Category.
*/
function ListFromCategory(category)
{
var docFrag = document.createDocumentFragment();
var unorderedList = document.createElement('ul');
unorderedList.id = category.id;
unorderedList.className = category.className;
docFrag.appendChild(unorderedList);
var child = category.subCategory;
var max = child.length;
for (var i = 0; i < max; i++)
{
unorderedList.appendChild(ListItemFromCategory(child[i]));
}
return unorderedList;
}
/*
Takes a Category and returns an li element representing the Category and containing its contents in a ul element.
*/
function ListItemFromCategory(category)
{
var docFrag = document.createDocumentFragment();
var listItem = document.createElement('li');
listItem.id = category.id;
listItem.className = category.className;
listItem.title = category.title;
docFrag.appendChild(listItem);
var anchor = createTextElement('a', category.title);
var child = category.subCategory;
var isSubCategory = child[0].isSubCategory;
listItem.appendChild(isSubCategory ? ListFromCategory(child) : SongListFromArray(child));
}
/*
Takes an array of Songs and returns an unordered list of anchors, each with its href a function to play the respective music file.
*/
function SongListFromArray(array)
{
var docFrag = document.createDocumentFragment();
var unorderedList = document.createElement('ul');
docFrag.appendChild(unorderedList);
var max = array.length;
for (var i = 0; i < max; i++)
{
var child = array[i];
var listItem = document.createElement('li');
listItem.id = child.id;
listItem.className = 'noWiki';
unorderedList.appendChild(listItem);
var span = createTextElement('span', child.title);
span.onclick = selectSong(child.id);
listItem.appendChild(span);
}
return unorderedList;
}
/* A Song has an id, title, artist, album, and a url of the music file. An info string (this.info) is constructed form title, artist, and album strings. An embed element (this.player) is constructed from the url of the music file. */
function Song(id, title, artist, album, musicFileUrl)
{
this.id = id;
this.title = title;
this.artist = artist;
this.album = album;
this.musicFileUrl = musicFileUrl;
this.info = title + ' - ' + artist + ' - ' + album;
// Used to differentiate between a Song and a Category.
this.isSubCategory = false;
var embed = document.createElement('embed');
embed.type = 'audio/mpeg';
embed.src = musicFileUrl;
embed.id = id + 'Player';
embed.className = 'player';
// for debugging
this.toString = function()
{
return this.id + '\n' + this.info + '\n' + this.musicFileUrl;
};
}
/*
A Category is the basic object representing a genre, sub-genre, artist, or album.
It has an id (corresponds to the HTML attribute id of the li generated by ListFromCategory(),
a title (corresponding to the text of the anchor),
a className (corresponding to the className of the li and anchor),
and a subCategory (a Category or array contained in the Category).
*/
function Category(id, title, className, subCategory)
{
this.id = id;
this.title = title;
this.className = className;
this.subCategory = subCategory;
// Used to differentiate between an Array and a Category.
this.isSubCategory = true;
this.toString = 'id: ' + this.id + '\n' +
'title: ' + this.title + '\n' +
'className: ' + this.className;
}
// wrapper function to play a song and change nowPlayingInfo.
function selectSong(song)
{
playMusic(song);
showNowPlayingInfo(song);
}
// Plays the music file of song by setting the first child of div#player.
function playMusic(song)
{
var player = song.player;
var playerContainer = document.getElementById('player');
setFirstChild(playerContainer, player);
}
// Changes innerText of nowPlayingInfoDiv to represent information about the currently playing song.
function showNowPlayingInfo(song)
{
var info = createTextElement('span', song.info);
var nowPlayingInfoDiv = document.getElementById('nowPlayingInfo');
setFirstChild(nowPlayingInfoDiv, info);
}
// Sets the first child element of parent to be child. If parent has a first child, it is replaced with child.
function setFirstChild(parent, child)
{
if (parent.firstChild)
{
parent.replaceChild(child, parent.firstChild);
}
else
{
parent.appendChild(child);
}
}
// Creates an element of type type and appends a text node with text text.
function createTextElement(type, text)
{
var e = document.createElement(type);
var t = document.createTextNode(text);
e.appendChild(t);
return e;
}
// Finds each anchor element without the class 'noWiki' and sets its href to a wikipedia search on the innerText
function anchorsToSearch()
{
var searchURL = 'http://en.wikipedia.org/wiki/Special:Search?search=';
var listItems = document.getElementsByTagName('li');
var anchors = new Array();
var max = listItems.length;
for (var i = 0; i < max; i++)
{
var li = listItems[i];
if (li.className.indexOf('noWiki') == -1)
{
anchors[anchors.length] = li.getElementsByTagName('a');
}
}
max = anchors.length;
for (var j = 0; i < max; i++)
{
var a = anchors[j];
a.href = searchURL + a.firstChild.nodeValue;
}
}
/* ]]> */
</script>
<!-- Constructs the objects needed for nested ul generation -->
<script type="text/javascript">
/* <![CDATA[ */
// Start Song initialization
var chinaWhite = new Song('chinaWhite', 'China White', 'He Is Legend', 'I Am Hollywood', 'http://www.mydatabus.com/public/1212jtraceur/z/China_White-He_Is_Legend-I_Am_Hollywood.mp3');
var mouthMagazine = new Song('mouthMagazine', 'Mouth Like A Magazine', 'Showbread', 'No Sir, Nihilism Is Not Practical', 'http://www.mydatabus.com/public/1212jtraceur/z/Mouth_Like_A_Magazine-Showbread-No_Sir_Nihilism_Is_Not_Practical.mp3');
var myDarkness = new Song('myDarkness', 'My Darkness', 'Destroy The Runner', 'Saints', 'http://www.mydatabus.com/public/1212jtraceur/z/My_Darkness-Destroy_The_Runner-Saints.mp3');
var oneManParade = new Song('oneManParade', 'One Man Parade', 'Becoming The Archetype', 'Terminate Damnation', 'http://www.mydatabus.com/public/1212jtraceur/z/One_Man_Parade-Becoming_The_Archetype-Terminate_Damnation.mp3');
var sandstorm = new Song('sandstorm', 'Sandstorm', 'Darude', 'Before The Storm', 'http://www.mydatabus.com/public/1212jtraceur/z/Sandstorm-Darude-Before_The_Storm.mp3');
var sincerelyIchabod = new Song('sincerelyIchabod', 'Sincerely, Ichabod', 'Project 86', '...And The Rest Will Follow', 'http://www.mydatabus.com/public/1212jtraceur/z/Sincerely_Ichabod-Project_86-And_The_Rest_Will_Follow.mp3');
var coldestHeart = new Song('coldestHeart', 'The Coldest Heart', 'The Classic Crime', 'Albatross', 'http://www.mydatabus.com/public/1212jtraceur/z/The_Coldest_Heart-The_Classic_Crime-Albatross.mp3');
var tunak = new Song('tunak', 'Tunak Tunak Tun', 'Daler Mehndi', 'Tunak Tunak Tun...', 'http://www.mydatabus.com/public/1212jtraceur/z/Tunak_Tunak_Tun-Daler_Mehndi-Tunak_Tunak_Tun.mp3');
var undying = new Song('undying', 'Undying', 'Demon Hunter', 'The Triptych', 'http://www.mydatabus.com/public/1212jtraceur/z/Undying-Demon_Hunter-The_Triptych.mp3');
var walls = new Song('walls', 'Walls', 'Emery', 'The Weak\'s End', 'http://www.mydatabus.com/public/1212jtraceur/z/Walls-Emery-The_Weaks_End.mp3');
var whiteNerdy = new Song('whiteNerdy', 'White and Nerdy', 'Weird Al Yankovic', 'Straight Outta Lynwood', 'http://www.mydatabus.com/public/1212jtraceur/z/White_and_Nerdy-Weird_Al_Yankovic-Straight_Outta_Lynwood.mp3');
var writingWalls = new Song('writingWalls', 'Writing On The Walls', 'UnderOath', 'Define The Great Line', 'http://www.mydatabus.com/public/1212jtraceur/z/Writing_On_The_Walls-UnderOath-Define_The_Great_Line.mp3');
var suburbiaRuins = new Song('suburbiaRuins', 'Your Little Suburbia is in Ruins', 'August Burns Red', 'Thrill Seeker', 'http://www.mydatabus.com/public/1212jtraceur/z/Your_Little_Surburbia_Is_In_Ruins-August_Burns_Red-Thrill_Seeker.mp3');
var liarsenic = new Song('liarsenic', 'Liarsenic', 'Norma Jean', 'O God, The Aftermath', 'http://www.mydatabus.com/public/1212jtraceur/z/Liarsenic-Norma_Jean-O_God_The_Aftermath.mp3');
// End Song initialization
// Start artist initialization
var heIsLegend = new Category('heIsLegend', 'He Is Legend', 'artist', [chinaWhite]);
var showbread = new Category('showbread', 'Showbread', 'artist', [mouthMagazine]);
var destroyTheRunner = new Category('destroyTheRunner', 'Destroy The Runner', 'artist', [myDarkness]);
var becomingTheArchetype = new Category('becomingTheArchetype', 'Becoming The Archetype', 'artist', [oneManParade]);
var project86 = new Category('project86', 'Project 86', 'artist', [sincerelyIchabod]);
var classicCrime = new Category('classicCrime', 'The Classic Crime', 'artist', [coldestHeart]);
var dalerMehndi = new Category('dalerMehndi', 'Daler Mehndi', 'artist', [tunak]);
var demonHunter = new Category('demonHunter', 'Demon Hunter', 'artist', [undying]);
var emery = new Category('emery', 'Emery', 'artist', [walls]);
var underOath = new Category('underOath', 'UnderOath', 'artist', [writingWalls]);
var augustBurnsRed = new Category('augustBurnsRed', 'August Burns Red', 'artist', [suburbiaRuins]);
var normaJean = new Category('normaJean', 'Norma Jean', 'artist', [liarsenic]);
// End artist initialization
// Start subGenre initialization
// End subGenre intialization
// Start genre initialization
var electronic = new Category('electronic', 'Electronic', 'genre', [sandstorm]);
var rap = new Category('rap', 'Rap', 'genre', [whiteNerdy]);
var rock = new Category('rock', 'Rock', 'genre', []);
// End genre initialization
// Initializes genreList, an array of genres.
var genreList = new Category('genreList', 'Select a genre', 'genreList', [electronic, rap]);
/* ]]> */
</script>
<style type="text/css">
/* <![CDATA[ */
/* kill browser defaults */
html, body
{
margin: 0;
padding: 0;
background: rgb(0, 0, 0);
color: rgb(192, 255, 0);
}
/* Embed and song info go on the right. */
div#playContainer
{
float: right;
max-width: 250px;
margin: 10px 10px 0 0;
}
/* embed horizantally fills div#playContainer */
div#playContainer > embed
{
width: 100%;
}
/* Menu goes on the left. */
div#selectContainer
{
float: left;
margin: 10px 0 0 10px;
}
/*
Begin interactive menu styling;
Base code from http://meyerweb.com/eric/css/edge/menus/demo.html
*/
/* get rid of spacing and define font */
ul
{
padding: 0;
margin: 0;
font: 1em sans-serif;
}
/* no bullets; green background, black bold text, black border of 1px width, no spacing */
ul li
{
list-style-type: none;
background: rgb(192, 255, 0);
color: rgb(0, 0, 0);
border: 1px solid rgb(0, 0, 0);
border-width: 1px 2px;
font-weight: bold;
width: 11ex;
height: 1.5em;
position: relative;
margin: 0;
padding: 0;
}
/* Nested menus don't display by default. */
ul ul
{
display: none;
}
/* However, they do when the corresponding li is hovered over. */
ul li:hover > ul
{
display: block;
position: absolute;
top: -1px;
left: 100%;
}
ul li#genreList:hover > ul
{
top: 100%;
left: 2px;
}
/* The li itself 'inverts' colors upon hover. */
ul li:hover
{
color: rgb(192, 255, 0);
background: rgb(0, 0, 0);
border: 1px solid rgb(192, 255, 0);
border-width: 1px 2px;
}
/* Anchors are block level, with no text decoration, no overflowing text, and text is centered. */
li a
{
display: block;
text-decoration: none;
text-align: center;
color: inherit;
overflow: hidden;
}
/* End interactive menu styling */
/* ]]> */
</style>
<!-- Sets document.body.onload -->
<script type="text/javascript">
/* <![CDATA[ */
function xonload()
{
setFirstChild(document.getElementById('selectContainer'), ListFromCategory(genreList));
anchorsToSearch();
}
window.onload = function()
{
xonload();
};
/* ]]> */
</script>
</head>
<body>
<!-- Basic structure needed for scripting. -->
<div id="selectContainer"></div>
<div id="playContainer">
<div id="player"></div>
<span>Now Playing:</span>
<div id="nowPlayingInfo"></div>
</div>
</body>
</html>
1212jtraceur
12-01-2006, 05:43 PM
Code update...I still get the same error:
Error: uncaught exception: [Exception... "Component returned failure code: 0x80004003 (NS_ERROR_INVALID_POINTER) [nsIDOMHTMLDivElement.appendChild]" nsresult: "0x80004003 (NS_ERROR_INVALID_POINTER)" location: "JS frame :: (FILE LOCATION) :: setFirstChild :: line 164" data: no]
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<title>Music Player</title>
<!-- Used for interactivity. -->
<script type="text/javascript">
/* <![CDATA[ */
// Used to debug with conditional alert statements.
function debug(text)
{
// Change this to determine whether or not text is alerted.
var debugp = true;
if (debugp)
{
alert(text);
}
return;
}
/*
Takes a Category and returns a ul element containing the contents of the Category.
*/
function ListFromArray(array)
{
var docFrag = document.createDocumentFragment();
var unorderedList = document.createElement('ul');
docFrag.appendChild(unorderedList);
var max = array.length;
for (var i = 0; i < max; ++i)
{
var child = array[i];
unorderedList.appendChild(child.isCategory ?
ListItemFromCategory(child) :
ListItemFromSong(child));
}
return unorderedList;
}
/*
Takes a Category and returns an li element representing the Category and containing its contents in a ul element.
*/
function ListItemFromCategory(category)
{
var docFrag = document.createDocumentFragment();
var listItem = document.createElement('li');
listItem.className = 'parentListItem';
docFrag.appendChild(listItem);
var anchor = createTextElement('a', category.title);
var unorderedList = ListFromArray(category.children);
unorderedList.id = category.id;
unorderedList.className = category.className;
listItem.appendChild(unorderedList);
return listItem;
}
/*
Takes an array of Songs and returns an unordered list of anchors, each with its href a function to play the respective music file.
*/
function ListItemFromSong(song)
{
var docFrag = document.createDocumentFragment();
var listItem = document.createElement('li');
listItem.id = song.id;
listItem.className = 'song';
docFrag.appendChild(listItem);
var span = createTextElement('span', song.title);
span.onclick = selectSong(song.id);
listItem.appendChild(span);
return listItem;
}
/* A Song has an id, title, artist, album, and a url of the music file. An info string (this.info) is constructed form title, artist, and album strings. An embed element (this.player) is constructed from the url of the music file. */
function Song(id, title, artist, album, musicFileUrl)
{
this.id = id;
this.title = title;
this.artist = artist;
this.album = album;
this.musicFileUrl = musicFileUrl;
this.info = title + ' - ' + artist + ' - ' + album;
// Used to differentiate between a Song and a Category.
this.isCategory = false;
var embed = document.createElement('embed');
embed.type = 'audio/mpeg';
embed.src = musicFileUrl;
embed.id = id + 'Player';
embed.className = 'player';
// for debugging
this.toString = function()
{
return this.id + '\n' + this.info + '\n' + this.musicFileUrl;
};
}
/*
A Category is the basic object representing a genre, sub-genre, artist, or album.
It has an id (corresponds to the HTML attribute id of the li generated by ListFromCategory(),
a title (corresponding to the text of the anchor),
a className (corresponding to the className of the li and anchor),
and children (an array of Categories and/or Songs).
*/
function Category(id, title, className, children)
{
this.id = id;
this.title = title;
this.className = className;
this.children = children
// Used to differentiate between an Array and a Category.
this.isCategory = true;
this.toString = 'id: ' + this.id + '\n' +
'title: ' + this.title + '\n' +
'className: ' + this.className;
}
// wrapper function to play a song and change nowPlayingInfo.
function selectSong(song)
{
playMusic(song);
showNowPlayingInfo(song);
}
// Plays the music file of song by setting the first child of div#player.
function playMusic(song)
{
var player = song.player;
var playerContainer = document.getElementById('player');
setFirstChild(playerContainer, player);
}
// Changes innerText of nowPlayingInfoDiv to represent information about the currently playing song.
function showNowPlayingInfo(song)
{
var info = createTextElement('span', song.info);
var nowPlayingInfoDiv = document.getElementById('nowPlayingInfo');
setFirstChild(nowPlayingInfoDiv, info);
}
// Sets the first child element of parent to be child. If parent has a first child, it is replaced with child.
function setFirstChild(parent, child)
{
if (parent.firstChild)
{
parent.replaceChild(child, parent.firstChild);
}
else
{
parent.appendChild(child);
}
}
// Creates an element of type type and appends a text node with text text.
function createTextElement(type, text)
{
var e = document.createElement(type);
var t = document.createTextNode(text);
e.appendChild(t);
return e;
}
/* ]]> */
</script>
<!-- Constructs the objects needed for nested ul generation -->
<script type="text/javascript">
/* <![CDATA[ */
// Start Song initialization
var chinaWhite = new Song('chinaWhite', 'China White', 'He Is Legend', 'I Am Hollywood', 'http://www.mydatabus.com/public/1212jtraceur/z/China_White-He_Is_Legend-I_Am_Hollywood.mp3');
var mouthMagazine = new Song('mouthMagazine', 'Mouth Like A Magazine', 'Showbread', 'No Sir, Nihilism Is Not Practical', 'http://www.mydatabus.com/public/1212jtraceur/z/Mouth_Like_A_Magazine-Showbread-No_Sir_Nihilism_Is_Not_Practical.mp3');
var myDarkness = new Song('myDarkness', 'My Darkness', 'Destroy The Runner', 'Saints', 'http://www.mydatabus.com/public/1212jtraceur/z/My_Darkness-Destroy_The_Runner-Saints.mp3');
var oneManParade = new Song('oneManParade', 'One Man Parade', 'Becoming The Archetype', 'Terminate Damnation', 'http://www.mydatabus.com/public/1212jtraceur/z/One_Man_Parade-Becoming_The_Archetype-Terminate_Damnation.mp3');
var sandstorm = new Song('sandstorm', 'Sandstorm', 'Darude', 'Before The Storm', 'http://www.mydatabus.com/public/1212jtraceur/z/Sandstorm-Darude-Before_The_Storm.mp3');
var sincerelyIchabod = new Song('sincerelyIchabod', 'Sincerely, Ichabod', 'Project 86', '...And The Rest Will Follow', 'http://www.mydatabus.com/public/1212jtraceur/z/Sincerely_Ichabod-Project_86-And_The_Rest_Will_Follow.mp3');
var coldestHeart = new Song('coldestHeart', 'The Coldest Heart', 'The Classic Crime', 'Albatross', 'http://www.mydatabus.com/public/1212jtraceur/z/The_Coldest_Heart-The_Classic_Crime-Albatross.mp3');
var tunak = new Song('tunak', 'Tunak Tunak Tun', 'Daler Mehndi', 'Tunak Tunak Tun...', 'http://www.mydatabus.com/public/1212jtraceur/z/Tunak_Tunak_Tun-Daler_Mehndi-Tunak_Tunak_Tun.mp3');
var undying = new Song('undying', 'Undying', 'Demon Hunter', 'The Triptych', 'http://www.mydatabus.com/public/1212jtraceur/z/Undying-Demon_Hunter-The_Triptych.mp3');
var walls = new Song('walls', 'Walls', 'Emery', 'The Weak\'s End', 'http://www.mydatabus.com/public/1212jtraceur/z/Walls-Emery-The_Weaks_End.mp3');
var whiteNerdy = new Song('whiteNerdy', 'White and Nerdy', 'Weird Al Yankovic', 'Straight Outta Lynwood', 'http://www.mydatabus.com/public/1212jtraceur/z/White_and_Nerdy-Weird_Al_Yankovic-Straight_Outta_Lynwood.mp3');
var writingWalls = new Song('writingWalls', 'Writing On The Walls', 'UnderOath', 'Define The Great Line', 'http://www.mydatabus.com/public/1212jtraceur/z/Writing_On_The_Walls-UnderOath-Define_The_Great_Line.mp3');
var suburbiaRuins = new Song('suburbiaRuins', 'Your Little Suburbia is in Ruins', 'August Burns Red', 'Thrill Seeker', 'http://www.mydatabus.com/public/1212jtraceur/z/Your_Little_Surburbia_Is_In_Ruins-August_Burns_Red-Thrill_Seeker.mp3');
var liarsenic = new Song('liarsenic', 'Liarsenic', 'Norma Jean', 'O God, The Aftermath', 'http://www.mydatabus.com/public/1212jtraceur/z/Liarsenic-Norma_Jean-O_God_The_Aftermath.mp3');
// End Song initialization
// Start artist initialization
var heIsLegend = new Category('heIsLegend', 'He Is Legend', 'artist', [chinaWhite]);
var showbread = new Category('showbread', 'Showbread', 'artist', [mouthMagazine]);
var destroyTheRunner = new Category('destroyTheRunner', 'Destroy The Runner', 'artist', [myDarkness]);
var becomingTheArchetype = new Category('becomingTheArchetype', 'Becoming The Archetype', 'artist', [oneManParade]);
var project86 = new Category('project86', 'Project 86', 'artist', [sincerelyIchabod]);
var classicCrime = new Category('classicCrime', 'The Classic Crime', 'artist', [coldestHeart]);
var dalerMehndi = new Category('dalerMehndi', 'Daler Mehndi', 'artist', [tunak]);
var demonHunter = new Category('demonHunter', 'Demon Hunter', 'artist', [undying]);
var emery = new Category('emery', 'Emery', 'artist', [walls]);
var underOath = new Category('underOath', 'UnderOath', 'artist', [writingWalls]);
var augustBurnsRed = new Category('augustBurnsRed', 'August Burns Red', 'artist', [suburbiaRuins]);
var normaJean = new Category('normaJean', 'Norma Jean', 'artist', [liarsenic]);
// End artist initialization
// Start subGenre initialization
// End subGenre intialization
// Start genre initialization
var electronic = new Category('electronic', 'Electronic', 'genre', [sandstorm]);
var rap = new Category('rap', 'Rap', 'genre', [whiteNerdy]);
var rock = new Category('rock', 'Rock', 'genre', []);
// End genre initialization
// Initializes genreList, an array of genres.
var genreList = [electronic, rap];
/* ]]> */
</script>
<style type="text/css">
/* <![CDATA[ */
/* kill browser defaults */
*
{
margin: 0;
padding: 0;
background: rgb(0, 0, 0);
color: rgb(192, 255, 0);
}
/* Embed and song info go on the right. */
div#playContainer
{
float: right;
max-width: 250px;
margin: 10px 10px 0 0;
}
/* embed horizantally fills div#playContainer */
div#playContainer > embed
{
width: 100%;
}
/* Menu goes on the left. */
div#selectContainer
{
float: left;
margin: 10px 0 0 10px;
}
/*
Begin interactive menu styling;
Base code from http://meyerweb.com/eric/css/edge/menus/demo.html
*/
ul
{
font: 1em sans-serif;
}
/* no bullets; green background, black bold text, black border of 1px width, no spacing */
ul li
{
list-style-type: none;
background: rgb(192, 255, 0);
color: rgb(0, 0, 0);
border: 1px solid rgb(0, 0, 0);
border-width: 1px 2px;
font-weight: bold;
width: 11ex;
height: 1.5em;
position: relative;
margin: 0;
padding: 0;
}
/* Nested menus don't display by default. */
ul ul
{
display: none;
}
/* However, they do when the corresponding li is hovered over. */
ul li:hover > ul
{
display: block;
position: absolute;
top: -1px;
left: 100%;
}
/* The li itself 'inverts' colors upon hover. */
ul li:hover
{
color: rgb(192, 255, 0);
background: rgb(0, 0, 0);
border: 1px solid rgb(192, 255, 0);
border-width: 1px 2px;
}
/* Anchors and spans are block level, with no text decoration, no overflowing text, and text is centered. */
li a, li span
{
display: block;
text-decoration: none;
text-align: center;
color: inherit;
overflow: hidden;
}
/* End interactive menu styling */
/* ]]> */
</style>
<!-- Sets document.body.onload -->
<script type="text/javascript">
/* <![CDATA[ */
function xonload()
{
//debug(document.getElementById('selectContainer'));
setFirstChild(document.getElementById('selectContainer'), ListFromArray(genreList));
anchorsToSearch();
}
window.onload = function()
{
xonload();
};
/* ]]> */
</script>
</head>
<body>
<!-- Basic structure needed for scripting. -->
<div id="selectContainer"></div>
<div id="playContainer">
<div id="player"></div>
<span>Now Playing:</span>
<div id="nowPlayingInfo"></div>
</div>
</body>
</html>
Will someone tell me why this happens, and how to fix it?
Thanks,
1212jtraceur
1212jtraceur
12-02-2006, 12:45 AM
I've put together another page which I want my page to be equal to after window.onload
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<title>Music Player</title>
<!-- Used for interactivity. -->
<script type="text/javascript">
/* <![CDATA[ */
// Used to debug with conditional alert statements.
function debug(text)
{
// Change this to determine whether or not text is alerted.
var debugp = true;
if (debugp)
{
alert(text);
}
return;
}
/*
Takes an Array, and returns a ul containing li's generated from array[i].
*/
function ListFromArray(array)
{
var docFrag = document.createDocumentFragment();
var unorderedList = document.createElement('ul');
docFrag.appendChild(unorderedList);
var max = array.length;
for (var i = 0; i < max; ++i)
{
var child = array[i];
unorderedList.appendChild(child.isCategory ?
ListItemFromCategory(child) :
ListItemFromSong(child));
}
return unorderedList;
}
/*
Takes a Category and returns an li element representing the Category and containing its contents in a ul element.
*/
function ListItemFromCategory(category)
{
var docFrag = document.createDocumentFragment();
var listItem = document.createElement('li');
listItem.id = category.id;
listItem.className = category.className;
docFrag.appendChild(listItem);
var anchor = createTextElement('a', category.title);
listItem.appendChild(anchor);
var unorderedList = ListFromArray(category.children);
listItem.appendChild(unorderedList);
return listItem;
}
/*
Takes an array of Songs and returns an unordered list of anchors, each with its href a function to play the respective music file.
*/
function ListItemFromSong(song)
{
var docFrag = document.createDocumentFragment();
var listItem = document.createElement('li');
listItem.id = song.id;
listItem.className = 'song';
listItem.onclick = selectSong(song.id);
docFrag.appendChild(listItem);
var span = createTextElement('span', song.title);
listItem.appendChild(span);
return listItem;
}
/* A Song has an id, title, artist, album, and a url of the music file. An info string (this.info) is constructed form title, artist, and album strings. An embed element (this.player) is constructed from the url of the music file. */
function Song(id, title, artist, album, musicFileUrl)
{
this.id = id;
this.title = title;
this.artist = artist;
this.album = album;
this.musicFileUrl = musicFileUrl;
this.info = title + ' - ' + artist + ' - ' + album;
// Used to differentiate between a Song and a Category.
this.isCategory = false;
var embed = document.createElement('embed');
embed.type = 'audio/mpeg';
embed.src = musicFileUrl;
embed.id = id + 'Player';
embed.className = 'player';
// for debugging
this.toString = function()
{
return this.id + '\n' + this.info + '\n' + this.musicFileUrl;
};
}
/*
A Category is the basic object representing a genre, sub-genre, artist, or album.
It has an id (corresponds to the HTML attribute id of the li generated by ListFromCategory(),
a title (corresponding to the text of the anchor),
a className (corresponding to the className of the li and anchor),
and children (an array of Categories and/or Songs).
*/
function Category(id, title, className, children)
{
this.id = id;
this.title = title;
this.className = className;
this.children = children
// Used to differentiate between an Array and a Category.
this.isCategory = true;
this.toString = 'id: ' + this.id + '\n' +
'title: ' + this.title + '\n' +
'className: ' + this.className;
}
// wrapper function to play a song and change nowPlayingInfo.
function selectSong(song)
{
playMusic(song);
showNowPlayingInfo(song);
}
// Plays the music file of song by setting the first child of div#player.
function playMusic(song)
{
var player = song.player;
var playerContainer = document.getElementById('player');
setFirstChild(playerContainer, player);
}
// Changes innerText of nowPlayingInfoDiv to represent information about the currently playing song.
function showNowPlayingInfo(song)
{
var info = createTextElement('span', song.info);
var nowPlayingInfoDiv = document.getElementById('nowPlayingInfo');
setFirstChild(nowPlayingInfoDiv, info);
}
// Sets the first child element of parent to be child. If parent has a first child, it is replaced with child.
function setFirstChild(parentElement, childElement)
{
if (parentElement.firstChild)
{
parentElement.replaceChild(childElement, parentElement.firstChild);
}
else
{
parentElement.appendChild(childElement);
}
}
// Creates an element of type type and appends a text node with text text.
function createTextElement(type, text)
{
var e = document.createElement(type);
var t = document.createTextNode(text);
e.appendChild(t);
return e;
}
function getSearchString(searchTerm)
{
var search1 = 'http://en.wikipedia.org/wiki/Special:Search?search=';
var search2 = '&go=Go';
var searchURL = search1 + searchTerm + search2;
return searchURL;
}
function anchorsToSearch()
{
var anchors = document.getElementsByTagName('a');
var max = anchors.length;
for (var i = 0; i < max; ++i)
{
var anchor = anchors[i];
var searchTerm = anchor.firstChild.nodeValue;
anchor.href = getSearchString(searchTerm);
anchor.target = '_blank';
}
}
/* ]]> */
</script>
<!-- Constructs the objects needed for nested ul generation -->
<script type="text/javascript">
/* <![CDATA[ */
// Start Song initialization
var chinaWhite = new Song('chinaWhite', 'China White', 'He Is Legend', 'I Am Hollywood', 'http://www.mydatabus.com/public/1212jtraceur/z/China_White-He_Is_Legend-I_Am_Hollywood.mp3');
var mouthMagazine = new Song('mouthMagazine', 'Mouth Like A Magazine', 'Showbread', 'No Sir, Nihilism Is Not Practical', 'http://www.mydatabus.com/public/1212jtraceur/z/Mouth_Like_A_Magazine-Showbread-No_Sir_Nihilism_Is_Not_Practical.mp3');
var myDarkness = new Song('myDarkness', 'My Darkness', 'Destroy The Runner', 'Saints', 'http://www.mydatabus.com/public/1212jtraceur/z/My_Darkness-Destroy_The_Runner-Saints.mp3');
var oneManParade = new Song('oneManParade', 'One Man Parade', 'Becoming The Archetype', 'Terminate Damnation', 'http://www.mydatabus.com/public/1212jtraceur/z/One_Man_Parade-Becoming_The_Archetype-Terminate_Damnation.mp3');
var sandstorm = new Song('sandstorm', 'Sandstorm', 'Darude', 'Before The Storm', 'http://www.mydatabus.com/public/1212jtraceur/z/Sandstorm-Darude-Before_The_Storm.mp3');
var sincerelyIchabod = new Song('sincerelyIchabod', 'Sincerely, Ichabod', 'Project 86', '...And The Rest Will Follow', 'http://www.mydatabus.com/public/1212jtraceur/z/Sincerely_Ichabod-Project_86-And_The_Rest_Will_Follow.mp3');
var coldestHeart = new Song('coldestHeart', 'The Coldest Heart', 'The Classic Crime', 'Albatross', 'http://www.mydatabus.com/public/1212jtraceur/z/The_Coldest_Heart-The_Classic_Crime-Albatross.mp3');
var tunak = new Song('tunak', 'Tunak Tunak Tun', 'Daler Mehndi', 'Tunak Tunak Tun...', 'http://www.mydatabus.com/public/1212jtraceur/z/Tunak_Tunak_Tun-Daler_Mehndi-Tunak_Tunak_Tun.mp3');
var undying = new Song('undying', 'Undying', 'Demon Hunter', 'The Triptych', 'http://www.mydatabus.com/public/1212jtraceur/z/Undying-Demon_Hunter-The_Triptych.mp3');
var walls = new Song('walls', 'Walls', 'Emery', 'The Weak\'s End', 'http://www.mydatabus.com/public/1212jtraceur/z/Walls-Emery-The_Weaks_End.mp3');
var whiteNerdy = new Song('whiteNerdy', 'White and Nerdy', 'Weird Al Yankovic', 'Straight Outta Lynwood', 'http://www.mydatabus.com/public/1212jtraceur/z/White_and_Nerdy-Weird_Al_Yankovic-Straight_Outta_Lynwood.mp3');
var writingWalls = new Song('writingWalls', 'Writing On The Walls', 'UnderOath', 'Define The Great Line', 'http://www.mydatabus.com/public/1212jtraceur/z/Writing_On_The_Walls-UnderOath-Define_The_Great_Line.mp3');
var suburbiaRuins = new Song('suburbiaRuins', 'Your Little Suburbia is in Ruins', 'August Burns Red', 'Thrill Seeker', 'http://www.mydatabus.com/public/1212jtraceur/z/Your_Little_Surburbia_Is_In_Ruins-August_Burns_Red-Thrill_Seeker.mp3');
var liarsenic = new Song('liarsenic', 'Liarsenic', 'Norma Jean', 'O God, The Aftermath', 'http://www.mydatabus.com/public/1212jtraceur/z/Liarsenic-Norma_Jean-O_God_The_Aftermath.mp3');
// End Song initialization
// Start artist initialization
var heIsLegend = new Category('heIsLegend', 'He Is Legend', 'artist', [chinaWhite]);
var showbread = new Category('showbread', 'Showbread', 'artist', [mouthMagazine]);
var destroyTheRunner = new Category('destroyTheRunner', 'Destroy The Runner', 'artist', [myDarkness]);
var becomingTheArchetype = new Category('becomingTheArchetype', 'Becoming The Archetype', 'artist', [oneManParade]);
var project86 = new Category('project86', 'Project 86', 'artist', [sincerelyIchabod]);
var classicCrime = new Category('classicCrime', 'The Classic Crime', 'artist', [coldestHeart]);
var dalerMehndi = new Category('dalerMehndi', 'Daler Mehndi', 'artist', [tunak]);
var demonHunter = new Category('demonHunter', 'Demon Hunter', 'artist', [undying]);
var emery = new Category('emery', 'Emery', 'artist', [walls]);
var underOath = new Category('underOath', 'UnderOath', 'artist', [writingWalls]);
var augustBurnsRed = new Category('augustBurnsRed', 'August Burns Red', 'artist', [suburbiaRuins]);
var normaJean = new Category('normaJean', 'Norma Jean', 'artist', [liarsenic]);
// End artist initialization
// Start subGenre initialization
// End subGenre intialization
// Start genre initialization
var electronic = new Category('electronic', 'Electronic', 'genre', [sandstorm]);
var rap = new Category('rap', 'Rap', 'genre', [whiteNerdy]);
var rock = new Category('rock', 'Rock', 'genre', []);
// End genre initialization
// Initializes genreList, an array of genres.
var genreList = [electronic, rap];
/* ]]> */
</script>
<style type="text/css">
/* <![CDATA[ */
/* kill browser defaults */
*
{
margin: 0;
padding: 0;
background: rgb(0, 0, 0);
color: rgb(192, 255, 0);
}
/* Embed and song info go on the right. */
div#playContainer
{
float: right;
max-width: 250px;
margin: 10px 10px 0 0;
}
/* embed horizantally fills div#playContainer */
div#playContainer > embed
{
width: 100%;
}
/* Menu goes on the left. */
div#selectContainer
{
float: left;
margin: 10px 0 0 10px;
}
/*
Begin interactive menu styling;
Base code from http://meyerweb.com/eric/css/edge/menus/demo.html
*/
ul
{
font: 1em sans-serif;
}
/* no bullets; green background, black bold text, black border of 1px width, no spacing */
ul li
{
list-style-type: none;
background: rgb(192, 255, 0);
color: rgb(0, 0, 0);
border: 1px solid rgb(0, 0, 0);
border-width: 1px 2px;
font-weight: bold;
width: 11ex;
height: 1.5em;
position: relative;
}
/* Nested menus don't display by default. */
ul ul
{
display: none;
}
/* However, they do when the corresponding li is hovered over. */
ul li:hover > ul
{
display: block;
position: absolute;
top: -1px;
left: 100%;
}
/* The li itself 'inverts' colors upon hover. */
ul li:hover
{
color: rgb(192, 255, 0);
background: rgb(0, 0, 0);
border: 1px solid rgb(192, 255, 0);
border-width: 1px 2px;
cursor: pointer;
}
/* Anchors and spans are block level, with no text decoration, no overflowing text, and text is centered. */
li a, li span
{
display: block;
text-decoration: none;
text-align: center;
margin: auto 0;
height: 100%;
width: 100%;
color: inherit;
background: inherit;
overflow: hidden;
}
/* End interactive menu styling */
/* ]]> */
</style>
<!-- Sets document.body.onload -->
<script type="text/javascript">
/* <![CDATA[ */
function xonload()
{
//debug(document.getElementById('selectContainer'));
//setFirstChild(document.getElementById('selectContainer'), ListFromArray(genreList));
anchorsToSearch();
}
window.onload = function()
{
xonload();
};
/* ]]> */
</script>
</head>
<body>
<!-- Basic structure needed for scripting. -->
<div id="selectContainer">
<ul>
<li id="electronic" class="genre">
<a>Electronic</a>
<ul>
<li id="sandstorm" class="song" onclick="selectSong(sandstorm);">
<span>
Sandstorm
</span>
</li>
</ul>
</li>
<li id="rap" class="genre">
<a>Rap</a>
<ul>
<li id="whiteNerdy" class="song" onclick="selectSong(whiteNerdy);">
<span>
White and Nerdy
</span>
</li>
</ul>
</li>
</ul>
</div>
<div id="playContainer">
<div id="player"></div>
<span>Now Playing:</span>
<div id="nowPlayingInfo"></div>
</div>
</body>
</html>
Even with this page, I get the same error:
Error: uncaught exception: [Exception... "Component returned failure code: 0x80004003 (NS_ERROR_INVALID_POINTER) [nsIDOMHTMLDivElement.appendChild]" nsresult: "0x80004003 (NS_ERROR_INVALID_POINTER)" location: "JS frame :: fileloc :: setFirstChild :: line 165" data: no]
Something is obviously wrong with my setFirstChild function:
// Sets the first child element of parentElement to be childElement. If parentElement has a first child, it is replaced with childElement.
function setFirstChild(parentElement, childElement)
{
if (parentElement.firstChild)
{
parentElement.replaceChild(childElement, parentElement.firstChild);
}
else
{
parentElement.appendChild(childElement); //This is line 165...
}
}
Hopefully, this will help narrow down the problem and make it easier to solve. I think I'm really close to completion of this project, and would love to solve this problem. Thanks for any help,
1212jtraceur
david_kw
12-02-2006, 02:24 AM
You are calling:
span.onclick = selectSong(child.id); // which is a string
then in selectSong(song)
playMusic(song);
then in playMusic(song)
setFirstChild(playerContainer, song.player);
But song was a string so unless you are trying to subclass it there is a problem there. If you are trying to subclass then you have a different problem in that song.player is null.
Near as I can tell that is the problem. I'm using FireBug for debugging and it still has some oddness with it. I can't wait for the next version.
What are you using to debug?
david_kw
1212jtraceur
12-03-2006, 03:07 AM
Up to now, I haven't really been doing any sophisticated debugging (various alert statements...).
I've heard about Firebug before, but didn't get it.
Now I have it, have inserted loads of debug() statements (my debug function calls console.log()), and found what was happening.
It turns out that Song.player didn't exist (quite stupid of me...).
So I defined it for Song(), and now my page works!
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<title>Music Player</title>
<!-- Used for interactivity. -->
<script type="text/javascript">
/* <![CDATA[ */
// Used to debug with conditional alert statements.
function debug(text)
{
// Change this to determine whether or not text is alerted.
var debugp = true;
if (debugp && console)
{
console.log(text);
}
return;
}
/*
Takes an Array, and returns a ul containing li's generated from array[i].
*/
function ListFromArray(array)
{
debug('ListFromArray();');
var docFrag = document.createDocumentFragment();
var unorderedList = document.createElement('ul');
docFrag.appendChild(unorderedList);
var max = array.length;
for (var i = 0; i < max; ++i)
{
var child = array[i];
unorderedList.appendChild(child.isCategory ?
ListItemFromCategory(child) :
ListItemFromSong(child));
}
return unorderedList;
}
/*
Takes a Category and returns an li element representing the Category and containing its contents in a ul element.
*/
function ListItemFromCategory(category)
{
debug('ListItemFromCategory(' + category.id + ');');
var docFrag = document.createDocumentFragment();
var listItem = document.createElement('li');
listItem.id = category.id;
listItem.className = category.className;
docFrag.appendChild(listItem);
var anchor = createTextElement('a', category.title);
listItem.appendChild(anchor);
var unorderedList = ListFromArray(category.children);
listItem.appendChild(unorderedList);
return listItem;
}
/*
Takes an array of Songs and returns an unordered list of spans, each with its onclick a function to play the respective music file.
*/
function ListItemFromSong(song)
{
debug('ListItemFromSong(' + song.id + ');');
var docFrag = document.createDocumentFragment();
var listItem = document.createElement('li');
listItem.id = song.id;
listItem.title = song.info;
listItem.className = 'song';
listItem.onclick = function()
{
selectSong(song);
}
docFrag.appendChild(listItem);
var span = createTextElement('span', song.title);
listItem.appendChild(span);
return listItem;
}
/* A Song has an id, title, artist, album, and a url of the music file. An info string (this.info) is constructed form title, artist, and album strings. An embed element (this.player) is constructed from the url of the music file. */
function Song(id, title, artist, album, musicFileUrl)
{
this.id = id;
this.title = title;
this.artist = artist;
this.album = album;
this.musicFileUrl = musicFileUrl;
this.info = title + ' - ' + artist + ' - ' + album;
// Used to differentiate between a Song and a Category.
this.isCategory = false;
var embed = document.createElement('embed');
embed.type = 'audio/mpeg';
embed.src = musicFileUrl;
embed.id = id + 'Player';
embed.className = 'player';
this.player = embed;
// for debugging
this.toString = function()
{
return this.id + '\n' + this.info + '\n' + this.musicFileUrl;
};
}
/*
A Category is the basic object representing a genre, sub-genre, artist, or album.
It has an id (corresponds to the HTML attribute id of the li generated by ListFromCategory(),
a title (corresponding to the text of the anchor),
a className (corresponding to the className of the li and anchor),
and children (an array of Categories and/or Songs).
*/
function Category(id, title, className, children)
{
this.id = id;
this.title = title;
this.className = className;
this.children = children
// Used to differentiate between an Array and a Category.
this.isCategory = true;
this.toString = 'id: ' + this.id + '\n' +
'title: ' + this.title + '\n' +
'className: ' + this.className;
}
// wrapper function to play a song and change nowPlayingInfo.
function selectSong(song)
{
debug('selectSong(' + song.id + ');');
playMusic(song);
showNowPlayingInfo(song);
}
// Plays the music file of song by setting the first child of div#player.
function playMusic(song)
{
debug('playMusic(' + song.id + ');');
var player = song.player;
var playerContainer = document.getElementById('playerContainer');
setFirstChild(playerContainer, player);
}
// Changes innerText of nowPlayingInfoDiv to represent information about the currently playing song.
function showNowPlayingInfo(song)
{
debug('showNowPlayingInfo(' + song.id + ');');
var info = createTextElement('span', song.info);
var nowPlayingInfoDiv = document.getElementById('nowPlayingInfo');
setFirstChild(nowPlayingInfoDiv, info);
}
// Sets the first child element of parentElement to be childElement. If parentElement has a first child, it is replaced with childElement.
function setFirstChild(parentElement, childElement)
{
debug('setFirstChild(' + parentElement.id + ', ' + childElement + ');');
if (parentElement.firstChild)
{
var firstChild = parentElement.firstChild;
parentElement.replaceChild(childElement, firstChild);
// This function 'should' work properly without the following code, but it doesn't...
/*
var secondChild = parentElement.childNodes[1];
parentElement.removeChild(secondChild);
*/
}
else
{
parentElement.appendChild(childElement);
}
}
// Creates an element of type type and appends a text node with text text.
function createTextElement(type, text)
{
debug('createTextElement(' + type + ', ' + text + ');');
var e = document.createElement(type);
var t = document.createTextNode(text);
e.appendChild(t);
return e;
}
function getSearchString(searchTerm)
{
debug('getSearchString(' + searchTerm + ');');
var search1 = 'http://en.wikipedia.org/wiki/Special:Search?search=';
var search2 = '&go=Go';
var searchURL = search1 + searchTerm + search2;
return searchURL;
}
function anchorsToSearch()
{
debug('anchorsToSearch()');
var anchors = document.getElementsByTagName('a');
var max = anchors.length;
for (var i = 0; i < max; ++i)
{
var anchor = anchors[i];
var searchTerm = anchor.firstChild.nodeValue;
anchor.title = searchTerm;
anchor.href = getSearchString(searchTerm);
anchor.target = '_blank';
}
}
/* ]]> */
</script>
<!-- Constructs the objects needed for nested ul generation -->
<script type="text/javascript">
/* <![CDATA[ */
// Start Song initialization
var chinaWhite = new Song('chinaWhite', 'China White', 'He Is Legend', 'I Am Hollywood', 'http://www.mydatabus.com/public/1212jtraceur/z/China_White-He_Is_Legend-I_Am_Hollywood.mp3');
var mouthMagazine = new Song('mouthMagazine', 'Mouth Like A Magazine', 'Showbread', 'No Sir, Nihilism Is Not Practical', 'http://www.mydatabus.com/public/1212jtraceur/z/Mouth_Like_A_Magazine-Showbread-No_Sir_Nihilism_Is_Not_Practical.mp3');
var myDarkness = new Song('myDarkness', 'My Darkness', 'Destroy The Runner', 'Saints', 'http://www.mydatabus.com/public/1212jtraceur/z/My_Darkness-Destroy_The_Runner-Saints.mp3');
var oneManParade = new Song('oneManParade', 'One Man Parade', 'Becoming The Archetype', 'Terminate Damnation', 'http://www.mydatabus.com/public/1212jtraceur/z/One_Man_Parade-Becoming_The_Archetype-Terminate_Damnation.mp3');
var sandstorm = new Song('sandstorm', 'Sandstorm', 'Darude', 'Before The Storm', 'http://www.mydatabus.com/public/1212jtraceur/z/Sandstorm-Darude-Before_The_Storm.mp3');
var sincerelyIchabod = new Song('sincerelyIchabod', 'Sincerely, Ichabod', 'Project 86', '...And The Rest Will Follow', 'http://www.mydatabus.com/public/1212jtraceur/z/Sincerely_Ichabod-Project_86-And_The_Rest_Will_Follow.mp3');
var coldestHeart = new Song('coldestHeart', 'The Coldest Heart', 'The Classic Crime', 'Albatross', 'http://www.mydatabus.com/public/1212jtraceur/z/The_Coldest_Heart-The_Classic_Crime-Albatross.mp3');
var tunak = new Song('tunak', 'Tunak Tunak Tun', 'Daler Mehndi', 'Tunak Tunak Tun...', 'http://www.mydatabus.com/public/1212jtraceur/z/Tunak_Tunak_Tun-Daler_Mehndi-Tunak_Tunak_Tun.mp3');
var undying = new Song('undying', 'Undying', 'Demon Hunter', 'The Triptych', 'http://www.mydatabus.com/public/1212jtraceur/z/Undying-Demon_Hunter-The_Triptych.mp3');
var walls = new Song('walls', 'Walls', 'Emery', 'The Weak\'s End', 'http://www.mydatabus.com/public/1212jtraceur/z/Walls-Emery-The_Weaks_End.mp3');
var whiteNerdy = new Song('whiteNerdy', 'White and Nerdy', 'Weird Al Yankovic', 'Straight Outta Lynwood', 'http://www.mydatabus.com/public/1212jtraceur/z/White_and_Nerdy-Weird_Al_Yankovic-Straight_Outta_Lynwood.mp3');
var writingWalls = new Song('writingWalls', 'Writing On The Walls', 'UnderOath', 'Define The Great Line', 'http://www.mydatabus.com/public/1212jtraceur/z/Writing_On_The_Walls-UnderOath-Define_The_Great_Line.mp3');
var suburbiaRuins = new Song('suburbiaRuins', 'Your Little Suburbia is in Ruins', 'August Burns Red', 'Thrill Seeker', 'http://www.mydatabus.com/public/1212jtraceur/z/Your_Little_Surburbia_Is_In_Ruins-August_Burns_Red-Thrill_Seeker.mp3');
var liarsenic = new Song('liarsenic', 'Liarsenic', 'Norma Jean', 'O God, The Aftermath', 'http://www.mydatabus.com/public/1212jtraceur/z/Liarsenic-Norma_Jean-O_God_The_Aftermath.mp3');
// End Song initialization
// Start artist initialization
var heIsLegend = new Category('heIsLegend', 'He Is Legend', 'artist', [chinaWhite]);
var showbread = new Category('showbread', 'Showbread', 'artist', [mouthMagazine]);
var destroyTheRunner = new Category('destroyTheRunner', 'Destroy The Runner', 'artist', [myDarkness]);
var becomingTheArchetype = new Category('becomingTheArchetype', 'Becoming The Archetype', 'artist', [oneManParade]);
var project86 = new Category('project86', 'Project 86', 'artist', [sincerelyIchabod]);
var classicCrime = new Category('classicCrime', 'The Classic Crime', 'artist', [coldestHeart]);
var dalerMehndi = new Category('dalerMehndi', 'Daler Mehndi', 'artist', [tunak]);
var demonHunter = new Category('demonHunter', 'Demon Hunter', 'artist', [undying]);
var emery = new Category('emery', 'Emery', 'artist', [walls]);
var underOath = new Category('underOath', 'UnderOath', 'artist', [writingWalls]);
var augustBurnsRed = new Category('augustBurnsRed', 'August Burns Red', 'artist', [suburbiaRuins]);
var normaJean = new Category('normaJean', 'Norma Jean', 'artist', [liarsenic]);
// End artist initialization
// Start subGenre initialization
// End subGenre intialization
// Start genre initialization
var electronic = new Category('electronic', 'Electronic', 'genre', [sandstorm]);
var rap = new Category('rap', 'Rap', 'genre', [whiteNerdy]);
var rock = new Category('rock', 'Rock', 'genre', []);
// End genre initialization
// Initializes genreList, an array of genres.
var genreList = [electronic, rap, rock];
/* ]]> */
</script>
<style type="text/css">
/* <![CDATA[ */
/* kill browser defaults */
*
{
margin: 0;
padding: 0;
background: rgb(0, 0, 0);
color: rgb(192, 255, 0);
}
/* Embed and song info go on the right. */
div#playContainer
{
float: right;
max-width: 250px;
margin: 10px 10px 0 0;
}
/* embed horizantally fills div#playContainer */
div#playContainer > embed
{
width: 100%;
}
/* Menu goes on the left. */
div#selectContainer
{
float: left;
margin: 10px 0 0 10px;
}
/*
Begin interactive menu styling;
Base code from http://meyerweb.com/eric/css/edge/menus/demo.html
*/
ul
{
font: 1em sans-serif;
}
/* no bullets; green background, black bold text, black border, no spacing */
ul li
{
list-style-type: none;
background: rgb(192, 255, 0);
color: rgb(0, 0, 0);
border: 1px solid rgb(0, 0, 0);
border-width: 1px 2px;
font-weight: bold;
width: 11ex;
height: 1.5em;
position: relative;
}
/* Nested menus don't display by default. */
ul ul
{
display: none;
}
/* However, they do when the corresponding li is hovered over. */
ul li:hover > ul
{
display: block;
position: absolute;
top: -1px; /* Should be the negative of (ul li border-top-width). */
left: 100%;
margin-left: 2px; /* Should equal (ul li border-left-width). */
}
/* The li itself 'inverts' colors upon hover. */
ul li:hover
{
color: rgb(192, 255, 0);
background: rgb(0, 0, 0);
border: 1px solid rgb(192, 255, 0);
border-width: 1px 2px;
cursor: pointer;
}
/* Anchors and spans are block level, with no text decoration, no overflowing text, and text is centered. */
li a, li span
{
display: block;
text-decoration: none;
text-align: center;
height: 100%;
width: 100%;
color: inherit;
background: inherit;
overflow: hidden;
}
/* End interactive menu styling */
/* ]]> */
</style>
<!-- Sets document.body.onload -->
<script type="text/javascript">
/* <![CDATA[ */
function xonload()
{
debug('xonload();');
setFirstChild(document.getElementById('selectContainer'), ListFromArray(genreList));
//document.getElementById('selectContainer').appendChild(ListFromArray(genreList));
anchorsToSearch();
}
window.onload = function()
{
xonload();
};
/* ]]> */
</script>
</head>
<body>
<!-- Basic structure needed for scripting. -->
<div id="selectContainer"></div>
<div id="playContainer">
<div id="playerContainer"></div>
<span>Now Playing:</span>
<div id="nowPlayingInfo"></div>
</div>
</body>
</html>
At first, I thought it was my setFirstChild function, so I looked in detail at that and found that it doesn't work as intended in this situation:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<title>
setFirstChild() Test
</title>
<script type="text/javascript">
/* <![CDATA[ */
// Sets the first child element of parentElement to be childElement. If parentElement has a first child, it is replaced with childElement.
function setFirstChild(parentElement, childElement)
{
if (parentElement.firstChild)
{
var firstChild = parentElement.firstChild;
parentElement.replaceChild(childElement, firstChild);
// This function 'should' work properly without the following code, but it doesn't...
/*
var secondChild = parentElement.childNodes[1];
parentElement.removeChild(secondChild);
*/
}
else
{
parentElement.appendChild(childElement);
}
}
// Creates an element of type type and appends a text node with text text.
function createTextElement(type, text)
{
var e = document.createElement(type);
var t = document.createTextNode(text);
e.appendChild(t);
return e;
}
function xonload()
{
var span = createTextElement('span', 'this should be the first child of div#parentElement');
span.style['background'] = 'rgb(0, 255, 0);';
setFirstChild(document.getElementById('parentElement'), span);
}
window.onload = function()
{
xonload();
}
/* ]]> */
</script>
</head>
<body>
<div id="parentElement">
<span style="background: rgb(255, 0, 0);">
this shouldn't be visible...
</span>
</div>
</body>
</html>
I know I'm kinda dragging this thread on and on (mods: if I shouldn't, let me know...),
but you guys already know where it is and have been helping for a while. Thanks loads!
1212jtraceur
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.