0

How do I use jQuery to read the first item in the contents of an XML file called music.xml, display them in a DIV for five seconds, read the next XML item and display that for five seconds, loop through the XML file and then start again from the beginning?

HTML:

<div id="music">
    <div id="albumcover"></div>
    <div id="songdescription"></div>
</div>

music.xml

<songs>
    <item>
        <image>music_01.jpg</image>
        <description>Description of first song</description>
    </item>
    <item>
        <image>music_02.jpg</image>
        <description>Description of second song</description>
    </item>
    <item>
        <image>music_03.jpg</image>
        <description>Description of third song</description>
    </item>
</songs>
2
  • Where is that music.xml file? Commented Jun 13, 2011 at 0:21
  • it's in the same directory as the HTML file and all the JPGs Commented Jun 13, 2011 at 0:23

2 Answers 2

2

Try something like this:

$.ajax({
  'dataType': 'xml',
  'success': function(xml)
  {
    $(xml).find('item').each(function()
    {
      var image = $(this).find('image').text();
      var description = $(this).find('description').text();

      $('<div id="music" />')
        .append($('<div id="albumcover" />').append($('<img />').attr('src', image)))
        .append($('<div id="songdescription" />').text(description))
        .appendTo('body');
    });

    // Add the code for the carousel here.
  },
  'type': 'get',
  'url': 'music.xml'
});

You'll have to adjust the paths (for the xml file and where the images are located) as well as where you want it added in the document. Currently, it'll append right before the closing BODY element.

Then, I'd recommend looking for a carousel jQuery plugin that will rotate through them rather than you having to deal with that part of it. You should check out jCarousel Lite.

Sign up to request clarification or add additional context in comments.

4 Comments

If the xml file is in the same folder as the HTML file and the images, you shouldn't have to adjust the path from the script above.
Just as one note, jQuery will parse $("<image>text</image>") as [<img>​, "text"]. That is, "text" will not be a child of <img> (not <image>, importantly) but a sibling. So you'd want to replace that, even if it's just something like xml.replace(/image/i, "cover"). The rest works nicely, I think.
@Bryan: I've tested it on my machine here using the code above and it worked fine. jQuery didn't not change the $("<image>text</image>") from the response as you suggested.
Never mind, you're right. I probably shouldn't have assumed that strings and text/xml would be treated the same, and jQuery does actually create a Document object.
1

First off, the way that I know how to parse these using jQuery will give problems with the image tag (edit: only if you parse text; XML turns out to be fine), as once you wrap it in jQuery it will convert <image>text</image> to <img>text. You can deal with that, but it's not pretty. So let's assume you've renamed <image> to <cover>.

Working jsFiddle, minus the $.ajax request part.

var music = [];
var musicIndex = -1;
var delay = 5000;
var intervalId; // in case you want to clearInterval
var $cover = $("#albumcover");
var $desc = $("#songdescription");

function rotateMusic() {
  // Loop back to the beginning if necessary
  if (++musicIndex === music.length) {
    musicIndex = 0;
  }
  console.log(music[musicIndex].cover);

  // Create a new image, tell it to append itself and description
  // once it's loaded, tell it to load
  $("<img>").load(function() {
    $cover.empty().append($(this));
    $desc.text(music[musicIndex].desc);
  }).attr("src", music[musicIndex].cover);
}

$.ajax({
  type: "GET",
  url: "music.xml",
  dataType: "xml",
  success: function(xml) {
             // Parse each item as a node
             $(xml).find('item').each(function() {
               // Add contents of item to music array
               var $item = $(this);
               music.push({
                 cover: $item.find('image').text(),
                 desc: $item.find('description').text()
               });

             });
             // Start rotating music, then set it to a delay
             rotateMusic();
             intervalId = setInterval(rotateMusic, delay);
           }
});

2 Comments

There's a bug somewhere, I've got the entire JS to run under $(document).ready and it stops the rotation on the second image and the third description.
I made a few revisions that should fix things. Notably, I should have moved the call to rotateMusic outside of the $(xml)...each statement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.