views:

121

answers:

3

hi, my code lists items from an rss feed onto an html page. although, the java script is a little finicky. it won't read some xml feeds, usually the feeds containing list items over 25. I just need another set of eyes to take a look at the code and tell me if i'm missing something obvious.

.js file-----------------------------------------------
//XML CODE

var http_request = false;
var dataFileName = new Array();
dataFileName[1] = "http://newsrss.bbc.co.uk/rss/newsonline_world_edition/americas/rss.xml";
//dataFileName[2] = "http://newsrss.bbc.co.uk/rss/newsonline_world_edition/uk_news/magazine/rss.xml";
//dataFileName[3] = "http://newsrss.bbc.co.uk/rss/newsonline_world_edition/business/rss.xml";




function getData(dataFileIndex) {
    if (window.ActiveXObject) { //IE
     http_request = new ActiveXObject("Microsoft.XMLHTTP");
    } else if (window.XMLHttpRequest) { //other
     http_request = new XMLHttpRequest();
    } else {
     alert("your browser does not support AJAX");
    }
    http_request.open("GET",dataFileName[dataFileIndex],true);
    http_request.setRequestHeader("Cache-Control", "no-cache");
    http_request.setRequestHeader("Pragma", "no-cache");
    http_request.onreadystatechange = function() {
     if (http_request.readyState == 4) {
      if (http_request.status == 200) {
       if (http_request.responseText != null) {
        processRSS(http_request.responseXML);
       } else {
        alert("Failed to receive RSS file from the server - file not found.");
        return false;
       }
      }
     }
    }

    http_request.send(null);
}

function processRSS(rssxml) {
    RSS = new RSS2Channel(rssxml);
    outputData(RSS);
}

function RSS2Channel(rssxml) {
    this.items = new Array();
    var itemElements = rssxml.getElementsByTagName("item");

    for (var i=0; i<itemElements.length; i++) {
     Item = new RSS2Item(itemElements[i]);
     this.items.push(Item);
    }
}

function RSS2Item(itemxml) {
    this.title;
    this.link;
    this.description;
    this.pubDate;
    this.guid;

    var properties = new Array("title", "link", "description", "pubDate", "guid");
    var tmpElement = null;
    for (var i=0; i<properties.length; i++) {
        tmpElement = itemxml.getElementsByTagName(properties[i])[0];
        if (tmpElement != null) {
            eval("this."+properties[i]+"=tmpElement.childNodes[0].nodeValue");
     }
    }
}

function outputData(RSS) {
    dataString = "";
    for (var i=0; i<RSS.items.length; i++) {
     dataString += "<div class='itemBlock'>";
     newDate = new Date(RSS.items[i].pubDate);
     dateString = (newDate.getMonth()+1) + "/" + newDate.getDate() + "/" + newDate.getFullYear();
     dataString += "<div class='itemDate'>" + dateString + "</div>";
     dataString += "<div class='itemTitle'><a href='" + RSS.items[i].link + "' target='afps_news'>" + RSS.items[i].title + "</a></div>";
     //dataString += "<div class='itemDescription'>" + RSS.items[i].description + "</div>";
     dataString += "</div>";
    }
    document.getElementById('outputBlock').innerHTML = dataString;
}





//SCROLL BAR CODE

var ie=document.all;
var nn6=document.getElementById&&!document.all;

var isdrag=false;
var x,y;
var dobj;
var scrollPercent;
var boxTop;
var maxHeight;
var toppoint;

function movemouse(e) {
    if (isdrag) {
     //dobj.style.left = nn6 ? tx + e.clientX - x : tx + event.clientX - x;

     toppoint = (nn6) ? ty + e.clientY - y : ty + event.clientY - y;
     boxTop = parseInt(document.getElementById('scrollBarBox').style.top) - scrollBarBoxOffset;
     if (toppoint < boxTop) toppoint = boxTop;

     boxHeight = parseInt(document.getElementById('scrollBarBox').style.height);
     maxHeight = boxTop + boxHeight - parseInt(document.getElementById('scrollBar').style.height);
     if (toppoint > maxHeight) toppoint = maxHeight;

     dobj.style.top = toppoint + "px";

     scrollPercent = toppoint / maxHeight;
     document.getElementById('textWindow').style.top = parseInt(0 - (document.getElementById('textWindow').offsetHeight - parseInt(document.getElementById('scrollBarBox').style.height)) * scrollPercent );

     return false;
    }
}

function selectmouse(e) {
    var fobj = nn6 ? e.target : event.srcElement;
    var topelement = nn6 ? "HTML" : "BODY";
    while (fobj.tagName != topelement && fobj.className != "dragme") {
     fobj = nn6 ? fobj.parentNode : fobj.parentElement;
    }

    if (fobj.className == "dragme") {
     isdrag = true;
     dobj = fobj;
     //tx = parseInt(dobj.style.left + 0);
     ty = parseInt(dobj.style.top + 0);
     //x = nn6 ? e.clientX : event.clientX;
     y = nn6 ? e.clientY : event.clientY;
     document.onmousemove = movemouse;
     return false;
    }
}

document.onmousedown = selectmouse;
document.onmouseup = new Function("isdrag=false;");

html file-------------------------------------------------------------------

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML><HEAD><TITLE>TEST</TITLE>
<META http-equiv=Content-Type content="text/html; charset=windows-1252">
<SCRIPT src="script1.js"></SCRIPT>

<STYLE>BODY {
    MARGIN: 0px; FONT: 8pt arial
}
#widgetBody {
BACKGROUND-Color:gray;  WIDTH: 240px; POSITION: relative; HEIGHT: 299px
}
#textWindowBox {
    LEFT: 63px; OVERFLOW: hidden; WIDTH: 152px; POSITION: absolute; TOP: 70px; HEIGHT: 221px
}
#textWindow {
    PADDING-TOP: 7px; POSITION: relative
}
#scrollBarBox {
    LEFT: 221px; WIDTH: 12px; POSITION: absolute; TOP: 74px; HEIGHT: 216px
}
#scrollBar {
    BACKGROUND: url(images/widget_scroll-handle1.gif) no-repeat; WIDTH: 12px; POSITION: relative; HEIGHT: 40px
}
#defenseLinkLink {
    LEFT: 4px; WIDTH: 20px; CURSOR: pointer; POSITION: absolute; TOP: 155px; HEIGHT: 140px; BACKGROUND-COLOR: transparent
}
#defenseLinkLink A {
    DISPLAY: block; WIDTH: 20px; HEIGHT: 140px
}
.dragme {
    POSITION: relative
}
.itemBlock {
    PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 4px; MARGIN: 0px 0px 3px; PADDING-TOP: 0px; BORDER-BOTTOM: #adafb3 1px dotted
}
.itemDate {
    FONT-SIZE: 0.9em; COLOR: #666; LINE-HEIGHT: 1.1em
}
.itemTitle {
    FONT-WEIGHT: bold; LINE-HEIGHT: 1.1em
}
.itemTitle A {
    COLOR: #254a7d; TEXT-DECORATION: none
}
.itemDescription {

}
</STYLE>

<SCRIPT>
var scrollBarBoxOffset = 74;

function init() {
    document.getElementById('scrollBarBox').style.top = "74px";
    document.getElementById('scrollBarBox').style.height = "216px";
    document.getElementById('scrollBar').style.height = "40px";
}
</SCRIPT>

<META content="MSHTML 6.00.6001.18294" name=GENERATOR></HEAD>
<BODY onload=init()>
<DIV id=widgetBody>
<DIV id=textWindowBox>
<DIV id=textWindow>
<DIV id=outputBlock></DIV></DIV></DIV>
<DIV id=scrollBarBox>
<DIV class=dragme id=scrollBar></DIV></DIV>
<DIV style="CLEAR: both"></DIV></DIV>
<SCRIPT language=javaScript>getData(2)</SCRIPT>
</BODY></HTML>
A: 

Oh man, why are you using XMLHttpRequest directly? Use a library for that, and make your life easier :)

You could be running into cross-site scripting security problems. If the RSS feeds exist on a different domain than the page running the JavaScript, the browser will not let your JavaScript make the requests.

Lance Fisher
A: 

dataFileName[1] = "http://newsrss.bbc.co.uk/rss/newsonline_world_edition/americas/rss.xml";

Unless you are (a) a script running from the BBC, or (b) a browser extension, you cannot make an XMLHttpRequest to that server.

  dataString += "<div class='itemTitle'><a href='" + RSS.items[i].link

HTML/script injection. If you insist on rolling innerHTML instead of using simple DOM methods you must do HTML escaping to turn <&" into &lt;&amp;&quot;.

eval("this."+properties[i]+"=tmpElement.childNodes[0].nodeValue");

Don't use eval, except in the very few unusual cases you need it. This isn't one of them; you can access a JavaScript property by name using:

this[properties[i]]= tmpElement.firstChild.data;

Also, and this is probably where the unreliability is coming in, you can't be sure there will be a single child Text node. If there is no content in that element, firstChild/childNodes[0] will not exist and you will get an exception. If there is complex content in the element (which normally there shouldn't be, but for RSS 0.9 there can be as unencoded HTML), firstChild.nodeValue won't contain the text content of the element. Instead you would have to walk over the Text node descendents gathering their nodeValue/data.

bobince
A: 

Ok, got it working. 2 issues.

  1. army.mil does not resolve! Please use "www.army.mil" instead.

  2. IN RSS2Item replace this line: if (tmpElement != null) {

with this: if (tmpElement != null && tmpElement.childNodes[0]) {

DmitryK
2. Worked like a charm! thanks.
MG