Swapping out an array (nested?) for values from an XML doc (client side scripting only)
I'm an absolute newbie with javascript, but I'm just trying to tweak JPlayer to use an XML file for the playlist instead of the hard-coded开发者_运维技巧 playlist. So, here's the bit of code that creates the playlist:
//<![CDATA[
$(document).ready(function(){
var Playlist = function(instance, playlist, options) {
var self = this;
this.instance = instance; // String: To associate specific HTML with this playlist
this.playlist = playlist; // Array of Objects: The playlist
this.options = options; // Object: The jPlayer constructor options for this playlist
this.current = 0;
this.cssId = {
jPlayer: "jquery_jplayer_",
interface: "jp_interface_",
playlist: "jp_playlist_"
};
this.cssSelector = {};
$.each(this.cssId, function(entity, id) {
self.cssSelector[entity] = "#" + id + self.instance;
});
if(!this.options.cssSelectorAncestor) {
this.options.cssSelectorAncestor = this.cssSelector.interface;
}
$(this.cssSelector.jPlayer).jPlayer(this.options);
$(this.cssSelector.interface + " .jp-previous").click(function() {
self.playlistPrev();
$(this).blur();
return false;
});
$(this.cssSelector.interface + " .jp-next").click(function() {
self.playlistNext();
$(this).blur();
return false;
});
};
Playlist.prototype = {
displayPlaylist: function() {
var self = this;
$(this.cssSelector.playlist + " ul").empty();
for (i=0; i < this.playlist.length; i++) {
var listItem = (i === this.playlist.length-1) ? "<li class='jp-playlist-last'>" : "<li>";
listItem += "<a href='#' id='" + this.cssId.playlist + this.instance + "_item_" + i +"' tabindex='1'>"+ this.playlist[i].name +"</a>";
// Create links to free media
if(this.playlist[i].free) {
var first = true;
listItem += "<div class='jp-free-media'>(";
$.each(this.playlist[i], function(property,value) {
if($.jPlayer.prototype.format[property]) { // Check property is a media format.
if(first) {
first = false;
} else {
listItem += " | ";
}
listItem += "<a id='" + self.cssId.playlist + self.instance + "_item_" + i + "_" + property + "' href='" + value + "' tabindex='1'>" + property + "</a>";
}
});
listItem += ")</span>";
}
listItem += "</li>";
// Associate playlist items with their media
$(this.cssSelector.playlist + " ul").append(listItem);
$(this.cssSelector.playlist + "_item_" + i).data("index", i).click(function() {
var index = $(this).data("index");
if(self.current !== index) {
self.playlistChange(index);
} else {
$(self.cssSelector.jPlayer).jPlayer("play");
}
$(this).blur();
return false;
});
// Disable free media links to force access via right click
if(this.playlist[i].free) {
$.each(this.playlist[i], function(property,value) {
if($.jPlayer.prototype.format[property]) { // Check property is a media format.
$(self.cssSelector.playlist + "_item_" + i + "_" + property).data("index", i).click(function() {
var index = $(this).data("index");
$(self.cssSelector.playlist + "_item_" + index).click();
$(this).blur();
return false;
});
}
});
}
}
},
playlistInit: function(autoplay) {
if(autoplay) {
this.playlistChange(this.current);
} else {
this.playlistConfig(this.current);
}
},
playlistConfig: function(index) {
$(this.cssSelector.playlist + "_item_" + this.current).removeClass("jp-playlist-current").parent().removeClass("jp-playlist-current");
$(this.cssSelector.playlist + "_item_" + index).addClass("jp-playlist-current").parent().addClass("jp-playlist-current");
this.current = index;
$(this.cssSelector.jPlayer).jPlayer("setMedia", this.playlist[this.current]);
},
playlistChange: function(index) {
this.playlistConfig(index);
$(this.cssSelector.jPlayer).jPlayer("play");
},
playlistNext: function() {
var index = (this.current + 1 < this.playlist.length) ? this.current + 1 : 0;
this.playlistChange(index);
},
playlistPrev: function() {
var index = (this.current - 1 >= 0) ? this.current - 1 : this.playlist.length - 1;
this.playlistChange(index);
}
};
var mediaPlaylist = new Playlist("1", [
{
name:"song1",
mp3: "song1.mp3",
poster: "http://www.jplayer.org/video/poster/Incredibles_Teaser_640x272.png"
},
{
name:"song2",
mp3: "song2.mp3",
poster: "http://www.jplayer.org/video/poster/Incredibles_Teaser_640x272.png"
},
{
name:"song3",
mp3: "song3.mp3",
poster: "http://www.jplayer.org/video/poster/Incredibles_Teaser_640x272.png"**
}
], {
ready: function() {
mediaPlaylist.displayPlaylist();
mediaPlaylist.playlistInit(false); // Parameter is a boolean for autoplay.
},
ended: function() {
mediaPlaylist.playlistNext();
},
swfPath: "js",
supplied: "ogv, m4v, oga, mp3"
});
});
The part that starts with "var mediaPlaylist" is the only section i need to change. Instead of having the keys/values as name: songname, mp3: mp3, etc., I want it to pull these values from an XML file, or better yet, just push them into the array from an XML that looks like:
<song>songname</song>
<mp3>file.mp3</mp3>
The thing that's mostly confusing me here is how that function/array is set up...too many curly braces and brackets to wrap my head around. How do I get into this without breaking it?
If you have a server side XML playlist file in the form:
<?xml version="1.0" encoding="UTF-8"?>
<playlist>
<entry>
<song>songname</song>
<mp3>file.mp3</mp3>
</entry>
<entry>
<song>songname2</song>
<mp3>file2.mp3</mp3>
</entry>
</playlist>
then you can load this from the client via AJAX and create a JSON array from the XML. The following example uses the jQuery JavaScript framework and also the jquery-json plugin (only to format the Array nicely as JSON). You should be able to run this on Chrome or Firefox as both have a console
(accessed by pressing F12 in the browser) in which I am outputting the JSON array.
Note: You could change console.log(...)
to alert(...)
if you don't use either of those browsers.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript" src="http://jquery-json.googlecode.com/files/jquery.json-2.2.min.js"></script>
<script type="text/javascript">
$(function() {
var Playlist = function(instance, playlist, options) {
var self = this;
this.instance = instance;
this.playlist = playlist;
this.options = options;
};
function getPlaylist(callback) {
var songs = new Array();
$.ajax({
dataType:'xml',
url:'songs.xml',
success : function (xml) {
$(xml).find('entry').each(function() {
songs.push({name: $(this).find('song').text(), mp3: $(this).find('mp3').text()});
});
callback(songs);
}
});
}
getPlaylist(function(songs) {
var playlistFromXML = jQuery.toJSON(songs);
var mediaPlaylist = new Playlist('1', playlistFromXML, null);
console.log(mediaPlaylist);
// etc...
});
});
</script>
</head><body></body></html>
Credit to How to return an array from jQuery ajax success function properly? answer as I used that approach to return a value from the jQuery $.ajax success
method.
You will have to refactor the var mediaPlaylist = new Playlist()
constructor into the callback function though as you cannot return the playlist value from the callback (see How can I catch the return value from the result() callback function that I'm using?)
Hope this helps :-)
精彩评论