基於web的RSS閱讀器,盜用AJAX之名

終於有時間做一下總結了……
這是我在WC培訓的第一個項目,內容如題。
盜用AJAX之名是何解呢?
其實項目中只是用了XMLHttpRequest請求RSS feed,並沒有實現什麼與服務器的異步交互,用這個名字,胖子說是爲了以後項目組來看人的時候有賣點。
唉,浮躁~~
項目之後就說,自己懂HTML/XML,CSS,DOM,AJAX,javascipt,挺能忽悠人的。
需求分析倒是沒有什麼好說的了,畢竟地球人都用過RSS。
只是我們的胖子比較變態,要我們用CSS的濾鏡實現摘要內容的漸變效果。
呵呵,如果你以爲三行代碼就搞定那種就錯了,他指定用Alpha濾鏡,暈吧!
主要的難處就是用javascript修改CSS、設置改變的時間間隔,從而控制alpha濾鏡,實現漸變效果。
l
l把處於透明狀態的層置於不透明的層之上,這時依然能看到下層(不透明的層)的內容,通過透明的層;
l然後,逐漸讓上層不透明、下層透明,達到漸變的效果
lsetInterval()控制漸變的速度
l注意,setInterval()時間參數與setTimeout()時間參數要保持一定比例,確保clearInterval()執行時,漸變已完成

看看代碼吧
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>Kam's Rss Reader</title>
<!--樣式表部分-->
<!--絕對定位、alpha濾鏡、zIndex層次、overflow的使用,或用blendTrans(duration=2)、revealTrans(Transition=12,Duration=2)-->
<style type="text/css">
<!--
#divNews1
{
filter
:alpha(Opacity=100);
position
:absolute;
margin-top
:auto;
z-index
:2;
height
:400px;
width
:500px;
overflow
:scroll;
}

#divNews2
{
filter
:alpha(Opacity=0);
position
:absolute;
margin-top
:auto;
z-index
:1;
height
:400px;
width
:500px;
overflow
:scroll;
}

#divAd
{
height
:400px;
width
:500px;
}

body
{
border
:groove;
width
:500px;
height
:400px;
}

-->
</style>
</head>

<body onload="loadXML()">
<script type="text/javascript">
//由於不善於利用JS,也懶得傳參數,所以濫用了一些全局變量
 var running;            //用於判斷是否在自動播放,ruuning==1時爲自動播放,running==0時手動
 var items;                //記錄RSS feed中item節點的數組
 var channel_title;        //記錄當前頻道名稱
 var x;
 
var i;
 
var j;                    //x,i,j均爲setInterval()的返回參數
 var count;                //記錄當前項目的變量
 var URL;                //記錄當前feed地址的變量
 
 
//對xml文件的請求,判斷使用何種瀏覽器
 function makeRequest()
    

        xmlhttp 
= false;
        
if(window.XMLHttpRequest)//Mozilla,Sofari
             
                xmlhttp 
= new XMLHttpRequest();
                   
if (xmlhttp.overrideMimeType)
                    
{xmlhttp.overrideMimeType('text/xml');}
             }

         
else if(window.ActiveXObject)//IE
                  {
                       
try{xmlhttp=new ActiveXObject("Msxml2.XMLHTTP");}
                       
catch(e){
                                
try{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
                                
catch(e){}
                                }

                   }

    }

    
//請求並獲取xml文件
function loadXML()
    
{
         makeRequest();
         
if(!xmlhttp)
         
{
              spanCount.innerHTML 
= "sorry, there is something wrong!";
              
return false;
          }

          
else
           
{
            xmlhttp.onreadystatechange 
= readXML;//當xmlhttp發生更改時,執行readXML()函數
            y = document.getElementById("menu");//從下拉列表獲取URL,即feed的地址
            URL = y.options[y.selectedIndex].value;
            xmlhttp.open(
"Get",URL,true);//open(string method, string url, boolean asynch, string username, string password)
            xmlhttp.send(null);
            
//向服務器發送 HTTP 請求並接收響應。使用 send() 方法發送的數據可以是字符串、無符號字節數組或 XML DOM 對象。使用 send()             方法發送的數據是可選的,並且可能爲空。根據 open() 方法中的 asynch 參數值,send()             方法爲同步或異步。如果爲同步,則在檢索整個響應之前該方法將不返回。如果爲異步,則該方法將立即返回 
        }

     }

function readXML()
    
{//調用 send() 方法之後,readyState 屬性將設置爲 2。當請求完成加載時,readyState 屬性將設置爲 4
         if(xmlhttp.readyState==4)
         
{
              
if(xmlhttp.status==200)
              
{
                   spanCount.innerHTML
="Finished!";//測試語句  
                   var xmlDoc = xmlhttp.responseXML;//從服務器中檢索 XML DOM 對象形式的響應
                count = 0;//初始化計數器
                   items = xmlDoc.getElementsByTagName("item");//獲取xml文件中所有item節點並存儲到items數組中
                var tmp = new Array();
                tmp 
= xmlDoc.getElementsByTagName("channel");
                
//這裏爲什麼是.data而不是.nodevalue????????????????
                channel_title = tmp[0].getElementsByTagName("title")[0]
                .firstChild.data;
//獲取頻道名稱信息
                running = 1;//設置running狀態,令一啓動即自動播放
                next_m(count);//開始播放item節點的內容
              }

         }

           
else
           
{
            spanCount.innerHTML
="loading...!";  
        }

    }

function play()//自動播放函數
    {    
        
if( running == 0 )//若在自動播放狀態
        {
            x 
= setInterval("next_m()",3000);//每隔3秒執行播放下一個item節點的內容
            running = 1;
            document.Form1.stand.value 
= "暫停";//改變按鈕上的提示字
        }

        
else if( running == 1 )//若在手動播放狀態
        {
            clearInterval(x);
//停止計時器,根據setInterval()的返回值確定
            running = 0;
            document.Form1.stand.value 
= "開始";
        }

    }

function change()//產生漸變效果函數
    {    //具體思想:
        //把處於透明狀態的層置於不透明的層之上,這時依然能看到下層(不透明的層)的內容,通過透明的層;
        //然後,逐漸讓上層不透明、下層透明,達到漸變的效果
        //由setInterval()控制漸變的速度
        //注意,setInterval()時間參數與setTimeout()時間參數要保持一定比例,確保clearInterval()執行時,漸變已完成
        if(divNews1.filters.alpha.Opacity == 100 && divNews2.filters.alpha.Opacity == 0)
        
{    //alert(divNews1.filters.alpha.Opacity);
            divNews1.style.zIndex = 1;
            divNews2.style.zIndex 
= 2;
            i 
= setInterval("see2()",5);
            setTimeout(
"clearInterval(i)",2000);
        }

        
else //if(divNews2.filters.alpha.Opacity==100 && divNews1.filters.alpha.Opacity==0)
        {
            divNews1.style.zIndex 
= 2;
            divNews2.style.zIndex 
= 1;
            j 
= setInterval("see1()",5);
            setTimeout(
"clearInterval(j)",2000);
        }

    }

function see2(m,n)
    
{
        divNews1.filters.item(
"alpha").Opacity -= 5;//每次變化10的性能比較好,但畫面有點卡
        divNews2.filters.item("alpha").Opacity += 5;//5可能比較慢
    }

function see1(m,n)
    
{
        divNews1.filters.item(
"alpha").Opacity += 5;
        divNews2.filters.item(
"alpha").Opacity -= 5;
    }

function next_m()
    
{
        
if(running == 1)//防止漸變的計數器與播放的計數器重疊,影響播放效果,所以讓其重新計數
        {
            clearInterval(x);
            x 
= setInterval("next_m()",3000);
        }

        count
++;
        
if(count > items.length)//令items數組能實現循環
            count = 1;
        
if( divNews1.style.zIndex == 1)//把下一個要顯示的items的內容顯示在下方且透明的層上
            {
            divNews1.innerHTML 
= display_m(count);
            change();
            }

        
else //if( divNews2.style.zIndex == 1)
                {
                divNews2.innerHTML 
= display_m(count);
                change();    
                }

    }

function pre_m()//同next_m()
    {
        
if(running == 1)
        
{
            clearInterval(x);
            x 
= setInterval("next_m()",3000);
        }

        count
--;
        
if(count < 1)
            count 
= items.length;
        
if( divNews1.style.zIndex == 1)
            
{
            divNews1.innerHTML 
= display_m(count);
            change();
            }

        
else //if( divNews2.style.zIndex == 1)
                {
                divNews2.innerHTML 
= display_m(count);
                change();    
                }

    }

//把next_m和pre_m變爲一個函數,可以實現的,可縮短代碼量
function display_m( m )//提取items內容並顯示的函數
    {
        m
--;//數組下標從0開始,而count從1開始,-1以匹配
        try//異常捕獲,當出現節點爲空、編碼不兼容等問題時,保證網頁不會崩潰
            {
            title_D 
= items[m].getElementsByTagName("title")[0].firstChild.nodeValue;
            url_D 
= items[m].getElementsByTagName("link")[0].firstChild.nodeValue;
            desc_D 
= items[m].getElementsByTagName("description")[0].firstChild.nodeValue;
            date_D 
= items[m].getElementsByTagName("pubDate")[0].firstChild.nodeValue;
            }

        
catch(e){}
        spanCount.innerText 
= "Message " + (++m) + " of " + items.length;//更新在右上角的計數欄
        return "<b>"+channel_title+": </b><a href="+url_D+">"+title_D+"</a><hr/>"+date_D+"<hr/>"+desc_D;
        
//返回頁面要顯示的其他內容
    }

function add_s()//給下拉選擇單添加新的feed,並自動開始播放新添加的feed
    {
        url_n 
= prompt("請輸入要訂閱的feed名稱");
        url 
= prompt("請輸入要訂閱的feed地址");
        tmp 
= document.getElementById("menu");
        tmp.add(
new Option( url_n, url ));
        oo 
= document.getElementsByTagName("option");
        tmp.selectedIndex 
= oo.length - 1;
        loadXML();
    }

</script>

<form name="Form1">
  <div id="divNewsTitle"> <b>Rss閱讀器</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span id="spanCount"></span>&nbsp; </div>
  <hr/>
  <div id="divAd">
    <div id="divNews1"></div>
    <div id="divNews2"></div>
  </div>
  <hr/>
  <div id="divControls" align="center">
    <input name="pre" type="button" value="後退" onclick="pre_m()"/>
    <input name="stand" type="button" value="暫停" onclick="play()"/>
    <input name="next" type="button" value="前進" onclick="next_m()"/>
    <hr/>
    <select  id="menu" onchange="loadXML()">
        <option value="http://blog.csdn.net/ganhui/Rss.aspx">kam的blog</option>
          <option value="http://192.168.0.55//Rss.xml">fei的blog</option>
    </select>
    <input name="" type="button" value="添加Feed" onclick="add_s()"/>
  </div>
</form>
</body>
</html>

記錄下來,以後自己嘲笑自己一下,試試放到googlepages上去,嘻嘻。
這個版本只能在IE上運行,自己用的是firefox,說這話真羞愧……

ps 真鬱悶,爲何有些語句IE和FF不都支持呢。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章