GORAGOD.com

บทที่ 18 AJAX กับ JSON (ตอนที่ 2)

บทความนี้จะเป็นตัวอย่างการอ่านข้อมูลจาก RSS แบบที่มีรูปภาพติดมาด้วย โดยที่ RSS ที่อ่านจะต้องส่งรูปภาพกลับมาด้วย ซึ่งปกติจะหาได้จากพวกเว็บวาไรตี้ทั่วๆไป แล้วส่งกลับเป็น JSON ด้วยฟังก์ชั่นของ PHP (แปลงข้อมูลจาก XML ให้เป็น JSON)
if (isset($_POST['url'])) {
    // feed URL
    $feedURL = $_POST['url'];
    // ถ้าไม่ได้กำหนดมาให้คืนค่ากลับทุกรายการข่าว
    $count = isset($_POST['count']) ? (int) $_POST['count'] : -1;
    if ($feedURL && preg_match("/^https?:\/\/.+$/", $feedURL) && ($feedRef = @fopen($feedURL, 'rb'))) {
        $contents = '';
        while (!feof($feedRef)) {
            $contents .= fread($feedRef, 8192);
        }
        fclose($feedRef);
        // RSS parser
        $rss = new SimpleXMLElement($contents, LIBXML_NOWARNING | LIBXML_NOERROR);
        // เขียน header ของเอกสาร จาก XML ที่่ได้รับ
        header("content-type: application/JSON; charset=UTF-8");
        // คืนค่า
        $ret = array();
        foreach ($rss->channel->item as $item) {
            if ($count < 0 || $count > 0) {
                $ret[] = $item;
                $count--;
            }
        }
        // คืนค่า JSON
        echo json_encode($ret, JSON_UNESCAPED_UNICODE);
    }
}

โค้ดหน้า reader.php อ่านข้อมูลจาก URL แล้วคืนค่ากลับเป็น JSON ส่งกลับให้ Ajax เพื่อแสดงผลต่อไป
// ขนาดของรูปภาพแสดงผล
var imagewidth = 75;
// จำนวนคอลัมน์
var cols = 2;

// ฟังก์ชั่นเรียกใช้งาน Ajax
function Inint_AJAX() {
   try { return new ActiveXObject("Msxml2.XMLHTTP")  } catch(e) {} // IE
   try { return new ActiveXObject("Microsoft.XMLHTTP") } catch(e) {} // IE
   try { return new XMLHttpRequest()          } catch(e) {} // Native Javascript
   alert("XMLHttpRequest not supported")
   return null
}

// ฟังก์ชั่นโหลดข่าวและแสดงผล
function loadNews(url, handle, count) {
     var req = Inint_AJAX()
     req.onreadystatechange = function () {
          if (req.readyState == 4) {
               if (req.status == 200) {
                    // to JSON
                    var datas = eval('('+req.responseText+')'),
                         data = '<table class="googeek_news_table"><tr>',
                         col = cols,
                         image;
                    for (var i = 0; i < datas.length; i++) {
                         col--;
                         if (col<0) {
                              col = cols;
                              data += '</tr><tr>';
                         }
                         image  = datas[i].image ? datas[i].image:  "../../ex/googeek/nopic.jpg"
                         data += '<td class="googeek_news_td"><div class="googeek_news_image"><img src="' + image + '" width="' + imagewidth + '"></div></td>'
                         data += '<td class="googeek_news_detail"><a href="' + datas[i].link + '" target="_blank">' + datas[i].title + '</a>'
                         data += '<br />(' + datas[i].pubDate + ')</td>'
                    }
                    data += '</tr></table>';
                    // แสดงผล
                    obj = document.getElementById(handle);
                    obj.innerHTML = data;
                    // ซ่อน loading
                    obj.style.backgroundImage  = "url()";
               }
          }
     }
     req.open("POST", "../../ex/googeek/reader.php", true);
     req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
     // ส่งค่า
     req.send("url=" + url + "&count=" + count);
}

// โหลด RSS เมื่อโหลดเพจเรียบร้อย
window.onload = function ()
{
     loadNews( 'https://www.posttoday.com/rss/src/entertainment.xml' , 'entertainment' , 4 );
     loadNews( 'https://www.posttoday.com/rss/src/it.xml' , 'it' , 4 );
}

โค้ดนี้ เป็นส่วนของ AJAX และ Javascript ในการรับส่งค่า และจัดการแสดงผล โดยในตัวอย่างนี้เป็นการอ่านจาก RSS ของ Post Today
ในกรณีที่ RSS ไม่มีรูปภาพแนบมาด้วย ตัวอ่านจะแสดงรูปภาพเริ่มต้นแทน (สามารถเปลี่ยนได้ nopic.jpg)
<style>
.googeek_news {
     border:1px solid #AAAAAA;
     padding:2px;
     height:180px;
     background-image:url(../../ex/googeek/wait.gif);
     background-position:center;
     background-repeat:no-repeat;
     overflow:hidden;
     margin:3px;
     text-align:left;
}
.googeek_news_table {
     height:100%;
     width:100%;
}
.googeek_news_td {
     margin:3px;
     background-color:#F0F0F0;
     vertical-align:top;
}
.googeek_news_image {
     border:1px solid #AAAAAA;
     background-color:#F0F0F0;
     display: inline-block;
}
.googeek_news_detail {
     vertical-align:top;
     text-align:left;
     color:gray;
     font-family:Tahoma;
     font-size:8pt;
     background-color:#F0F0F0;
}
</style>

<div class="googeek_news" id="entertainment"></div>
<div class="googeek_news" id="it"></div>

ด้านบนเป็นโค้ดส่วน HTML และ CSS สำหรับแสดงผล RSS มี ID สอดคล้องกันกับโค้ด ด้วยนะครับ (สามารถแสดงได้หลายข่าว)
หมายเหตุ ถ้าต้องการนำไปใช้งานให้แก้ไข path ต่างๆ ให้ถูกต้องด้วยนะครับ
ตัวอย่าง