หน้าเว็บ

วันศุกร์ที่ 5 ตุลาคม พ.ศ. 2555

การทำ push state ajax

push state ajax คืออะไร ?
        
        ก่อนจะที่เราจะไปรู้จักความหมายของ push state ajax  เราลองมาดูปัญหาของ ajax ที่เราใช้กันแบบธรรมดาดูก่อนน่ะครับ

        ในปัจจุบัน  เว็บส่วนใหญ่  กลายเป็นเว็บที่ใช้เทคโนโลยีที่ไม่มีการรีเฟรชหน้าเข้ามาเกี่ยวข้องไปเกือบหมดแล้ว  เทคโนโลยีนั้นก็คือเทคโนโลยี ajax ซึ่งย่อมาจาก asynchronous javascript and xml   เป็นเทคโนโลยีที่ช่วยทำให้ web browser ไปโหลดเอาเข้ามูลมาจาก web server โดยปราศจากการรีเฟรชหน้า browser เหมือนในสมัยก่อน  ข้อดีของเทคโนโลยีนี้  คือการแสดงผลมันลื่นครับ  หน้าเว็บไม่ต้องกระพริบไปกระพริบมา  ซึ่งอาจทำให้ผู้ใช้งานเกิดความรำคาญก็เป็นไปได้  

ต่อมาเรามาดูข้อเสียกันครับ

        ข้อเสียน่ะเหรอครับ  ผมว่าหลายๆคนคงจะนึกไม่ถึง   และโปรแกรมเมอร์หลายๆคนไปเอาเทคโนโลยี ajax มาใช้  แต่ดันลืมว่า  มันมีข้อเสียที่ร้ายแรงอย่างนึงที่  ajax ทำให้เราไม่ได้  นั่นก็คือ การ book mark page นั้นๆ  หรือการจดจำ url ของ page นั้น  แล้วได้ข้อมูลเหมือนเดิม  นี่ละครับ  ข้อเสียที่ร้ายแรงที่ว่า  เพราะเมื่อเรา request ajax ไป  อย่าลืมน่ะครับว่า url ของ browser เราไม่ได้เปลี่ยนไปด้วย  ถ้าเรา refresh browser ในขณะนั้น  รับรองได้ว่าข้อมูล  ajax นั้นจะหายไปแน่ๆ  ยกเว้นแต่ว่า ajax นั้นเป็นตัวแปรระดับ session scope  

        เมื่อรู้ปัญหาแล้ว ทีนี้ก็ทำให้เกิดแนวคิดในการแก้ปัญหานั้น  จึงทำให้เกิดวิธีการที่เรียกว่า push state ajax  คือการเก็บ state ของ request ajax ในขณะนั้นไว้  เพื่อให้ได้ข้อมูลเดิม  เมื่อเรา refresh หน้า browser

แนวคิดในการทำ push state ajax
        การทำ push state ajax เราจะทำผ่านตัวแปร object global ของ javascript ที่ชื่อว่า history  ซึ่งตัวแปรนี้  เราจะมีการเรียกใช้งาน  function pushState();  ที่เอาไว้เก็บ state ของ page ในขณะนั้นไว้   คุณสมบัติ  push state นี้  เป็นคุณสมบัติใหม่ที่มากับ HTML5  ฉะนั้นจึงใช้งานได้กับบาง browser  บาง browser ก็ใช้งานไม่ได้  ต้องใช้วิธีการอื่นมาเก็บ state แทน  เช่น IE < IE10  ที่ ใช้ไม่ได้   เขาจะใช้   location.hash   หรือที่เราเคยเห็น url ที่มีสัญลักษณ์  #  ต่อท้ายเข้ามาช่วยแทน  ในที่นี้ผมไม่ขอเอ่ยถึงน่ะครับ

        การใช้ history.pushState();  เป็นแบบนี้ครับ คือ  เมื่่อ มี request ajax เกิดขึ้น  เราก็แค่เปลี่ยน url ของ browser นั้นให้ตรงกับเนื้อหาที่ได้มา  แล้วก็เก็บ url นั้นไว้ใน history.pushState();  เพื่อที่เวลาเรา refresh browser หรือกดปุ่ม back หรือปุ่ม forward  ของ browser  มันจะได้เอา state นั้นออกมาใช้งาน (pop state) ได้ในภายหลัง  แนวคิดง่ายๆ   มีแค่นี้เองครับ

        ทีนี้เรามาลงในส่วนของโค๊ดกันดีกว่าครับ
$(function(){

    //<a href='www.na5cent.blogspot.com/profile' class='proflie'>profile</a>
    //ตรงนี้เป็น tag a(html link) ที่มี class = profile ที่ทำหน้าที่เป็น menu ครับ
    //ซึ่งเมื่อเราคลิกที่เมนู  ก็จะให้ไป request content โดยใช้ ajax มาจาก web server
    //จากนั้นก็ push state เก็บไว้
    $("a.profile").click(function(){       
        profilePushState($(this));

        //เป็นการ disable tag a เพื่อไม่ให้เกิดการ refresh หน้า browser ครับ
        return false; 
    });
        
        
    //ในส่วนนี้เป็นการ pop state หรือการคืน state เมื่อมีการ refresh browser 
    //หรือการกดปุ่ม back หรือปุ่ม forward ของ browser นั่นเอง
    $( window ).bind( "popstate", function(event) {
        profilePopState(location.href);
    });

    
    //functon ที่จะให้ทำเมื่อเกิด event pop state ครับ
    function profilePopState(url){
        //อันนี้เป็นตัวแปร global ที่ผมทำไว้ว่าจะให้ไปอัพเดท content ตรงไหนของหน้าเว็บ
        var updatePart = profileUrls.update; 

        //อันนี้คือ url ที่ pop มาได้ครับ  ซึ่งจะทำการ request ไปยัง web server 
        //เพื่อไป get เอา content ในขณะนั้นมา
        var wallURL = profileUrls[url].request; 

        //เรียกใช้ ajax get ของ jquery พร้อมระบุ url ที่จะ request ไป
        $.get(wallURL, function(response){
            //update content
            $(updatePart).html(response); 
 
            //ทำให้เกิด event resize window เพื่อเอาไว้ resize content บางส่วน
            $(window).trigger('resize'); 
        });
    }


    //function ที่จะทำเมื่อมีการคลิกที่เมนูหรือ tag a.profile
    function profilePushState(data){
        //get url key ที่จะ request ไป
        var urlState = data.attr("href"); 

        //get ว่า menu ไหนที่ทำการคลิก  เช่น menu information, menu image เป็นต้น
        //<a href='www.na5cent.blogspot.com/profile'class='proflie'>profile</a>
        var wallModule = data.html();  

        //อันนี้เป็นตัวแปร global ที่ผมทำไว้ว่าจะให้ไปอัพเดท content ตรงไหนของหน้าเว็บ
        var updatePart = profileModules.update; 

        //นำ menu ไป get url จริงที่จะเป็น url request ajax ซึงก็ขึ้นอยู่กับการ design ของแต่ละคนน่ะครับ  
        //ไม่ต้องทำเหมือนผมก็ได้  พอดีผมทำระบบที่ค่อนข้างซับซ้อนนิดนึง  ก็เลยต้องมีการแปลงไปแปลงมา  
        //แค่นั้นเองครับ จริงๆ แล้วไม่ต้องแปลงก็ได้  แค่ design url request ajax ใน tag a ให้ตรงกันก็พอครับ
        var wallURL = profileModules[wallModule.trim()][urlState]; 

        //เรียกใช้ ajax get ของ jquery พร้อมระบุ url ที่จะ request ไป
        $.get(wallURL, function(response){
            //update content
            $(updatePart).html(response); 
 
            //push state  โดยการเก็บ url ในขณะนั้นไว้  
            //และเปลี่ยน url ของ browser ให้ตรงกับ request ajax ที่ส่งไป
            history.pushState(null, null, urlState); 

            //ทำให้เกิด event resize window เพื่อเอาไว้ resize content บางส่วน
            $(window).trigger('resize'); 
        });
    }
});
        ในส่วนของ server เราก็แค่เขียนโปรแกรม เพื่อจัดการ response ให้กับ request ajax นั้นๆ คือจัดการ content ให้ตรงกับที่ request ajax ไปก็แค่นั้นเองครับ

        หวังว่าคงพอเข้าใจ concept  ของการทำ push state ajax กันน่ะครับ  เพราะว่าผมแค่เขียนเพื่ออธิบาย concept และการทำงานคร่าวๆ เท่านั้น  ในส่วนของ รายละเอียดลึกๆ นั้นก็คงต้องไปหาอ่านเอาเองน่ะครับ  ซึ่งถ้าอยากรู้ว่าจะหาอ่านได้จากที่ไหน  ก็ลองถามพี่ google ดูในเรื่อง push state ajax ครับ

        อ้อ ลืมไปครับ  วิธีการนี้เว็บระดับโลกเขาใช้กัน  ลองสังเกตดู  facebook, twitter, หรือ google+  น่ะครับ   ซึ่งเขาใช้ push state  กันเกือบทั้ง application แล้ว

ลองดูตัวอย่างนี้ดูครับ  ลองคลิกที่ link ต่างๆ  แล้วสังเกตดูครับ
http://html5-history-pushstate.ssdtutorials.com/universal
http://html5.gingerhost.com/
http://html5doctor.com/demos/history/socks

หรือไม่ก็  facebook, twitter, หรือ google+  น่ะครับ  อันนี้เขาค่อนข้างซับซ้อนหน่อย   เพราะเขาอยู่ในระดับโลกกันแล้ว  ^___________^


2 ความคิดเห็น:

  1. ขอบคุณมากครับ ได้ความรู้ใหม่ๆ เป็นประโยชน์กับผมมากครับ

    ตอบลบ
    คำตอบ
    1. ลองไปใช้ JS Framework ใหม่ๆ ดูครับ
      เช่นอาจจะเป็น BackboneJS, AngularJS, ReatJS
      ให้ดูเรื่อง Router ครับ แล้วจะเข้าใจเรื่องพวกนี้มากขึ้น

      ลบ