Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Saturday, 24 November 2012

เทคนิคการสร้าง Unique Array ใน JavaScript

สำหรับบทความนี้ผมจะมานำเสนอเทคนิคในการสร้าง Unique Array (คือ Array ที่มีค่า Value ไม่ซ้ำกัน) สำหรับเทคนิคที่จะนำมาใช้งานเป็นการปรับปรุงความสามารถของ Class Array ผ่านทาง Prototype ลองดูตัวอย่างนะครับ

 Array.prototype.getUnique = function(){
   var u = {}, a = [];
   for(var i = 0, l = this.length; i < l; ++i){
      if(u.hasOwnProperty(this[i])) {
         continue;
      }
      a.push(this[i]);
      u[this[i]] = 1;
   }
   return a;
}

เมื่อเราปรับปรุงความสามารถของ Array เรียบร้อยแล้ว เราก็จะมาลองใช้งานดูดังนี้ โดยเริ่มจากการประกาศ Array ขึ้นมาก่อน โดยเราจะลองทำให้ Array มีค่าซ้ำๆกันอยู่ ดังนี้ครับ

var arr = [1,2,3,3];  // สังเกตุว่า มี 3 ซ้ำกันอยู่ 2 ตัว

alert(arr.getUnique()); // ค่าที่ Alert ออกมาจะเป็น [1,2,3] สังเกตุว่าค่าที่ซ้ำจะถูกกำจัดออกไปแล้ว

แหล่งที่มา : http://bit.ly/TbfHie

Thursday, 22 November 2012

tablesorter - Flexible client side Table Sorting

สำหรับบทความนี้ผมอยากจะมาแนะนำเกี่ยวกับ jQuery Plugin ตัวนึงที่มีชื่อว่า tablesorter ซึ่งมีหน้าที่ในการปรับปรุงความสามารถของ Table ให้สามารถ Sort ได้ โดยเขียน Code แค่ไม่กี่บรรทัด ตาม Style ของ jQuery เดี๋ยวลองมาดูตัวอย่างการใช้งานกันนะครับ

เริ่มต้นด้วยการเรียกใช้งาน jQuery กับ tablesorter กันก่อน

<script type="text/javascript" src="/path/to/jquery-latest.js"></script>
<script type="text/javascript" src="/path/to/jquery.tablesorter.js"></script>

ส่วน HTML tag สำหรับ Table ของเรา ก็หน้าตาประมาณนี้ครับ

<table id="myTable" class="tablesorter">
<thead>
<tr>
    <th>Last Name</th>
    <th>First Name</th>
    <th>Email</th>
    <th>Due</th>
    <th>Web Site</th>
</tr>
</thead>
<tbody>
<tr>
    <td>Smith</td>
    <td>John</td>
    <td>jsmith@gmail.com</td>
    <td>$50.00</td>
    <td>http://www.jsmith.com</td>
</tr>
<tr>
    <td>Bach</td>
    <td>Frank</td>
    <td>fbach@yahoo.com</td>
    <td>$50.00</td>
    <td>http://www.frank.com</td>
</tr>
<tr>
    <td>Doe</td>
    <td>Jason</td>
    <td>jdoe@hotmail.com</td>
    <td>$100.00</td>
    <td>http://www.jdoe.com</td>
</tr>
<tr>
    <td>Conway</td>
    <td>Tim</td>
    <td>tconway@earthlink.net</td>
    <td>$50.00</td>
    <td>http://www.timconway.com</td>
</tr>
</tbody>
</table>

คราวนี้มาถึงส่วนสำคัญ คือ การเรียกใช้งาน tablesorter สามารถเรียกใช้งานได้ดังนี้ครับ

$(document).ready(function() 
    { 
        $("#myTable").tablesorter(); 
    } 
); 
      
ในกรณีที่ต้องการตั้งค่าการ Sorting ไว้ล่วงหน้า ก็สามารถทำได้ โดยกำหด options เพิ่มเติมดังนี้

$(document).ready(function() 
    { 
        $("#myTable").tablesorter( {sortList: [[0,0], [1,0]]} ); 
    } 
); 

คราวนี้เมื่อ Table แสดงผล ข้อมูลก็จะถูกเรียงลำดับไว้เรียบร้อย โดยใน Code ที่แสดงให้ดู กำหนดไว้ว่า ให้เรียงลำดับข้อมูลใน columns ที่ 0 และ 1 โดยเรียงในแบบ ascending ครับ

สำหรับผู้ที่สนใจ สามารถศึกษาเพิ่มเติมได้ที่ http://tablesorter.com

moment.js - javascript date library for parsing, validating, manipulating, and formatting dates

moment.js คือ JavaScript สำหรับช่วยในการทำงานเกี่ยวกับวันที่และเวลา มีขนาดเพียง 3.5kb ลองดูตัวอย่างการใช้งานเบื้องต้นดังนี้ครับ

moment().format('MMMM Do YYYY, h:mm:ss a');
moment().format('dddd');
moment().format("MMM Do YY");
moment().format('YYYY [escaped] YYYY');
moment().format();

นอกจากนี้ยังรองรับการแสดงผลวันที่และเวลาเป็นภาษาต่างๆ (แต่ลองดูตัวอย่างจากในหน้าเว็บ ยังไม่เห็นภาษาไทยครับ) สำหรับผู้ที่สนใจ สามารถศึกษาข้อมูลเพิ่มเติมได้ที่ http://momentjs.com/

วิธีการเรียกใช้งาน Controller จาก Script ภายนอก ใน Angular.js

โดยปกติเราสามารถเรียกใช้งาน Controller ได้โดยผ่านการ Binding แต่สำหรับในกรณีที่เรามีความจำเป็นต้องเรียกใช้งาน property หรือ method ที่อยู่ภายใน Controller จาก Script ที่อยู่ภายนอก ซึ่งเราไม่สามารถใช้วิธีการ binding ได้ เราสามารถทำโดยการเรียกใช้งานผ่าน scope โดยตรง ซึ่ง โดยปกติ Angular จะสร้าง scope Object ไว้กับ Element ที่เราประกาศให้เป็น Controller ซึ่งเราสามารถดึงเอา Scope Object ออกมาใช้งานได้ดังต่อไปนี้

ตัวอย่างของ Code ในส่วนของ Controller

function HelloCtrl($scope){
    $scope.title = 'Hello!';
    $scope.test = function(){
        alert('xxx');
    }
}

สมมุติว่า ประกาศ controller ไว้ที่ body tag ดังนี้

<html ng-app>
<body ng-controller="HelloCtrl">
</body>
</html>

เราสามารถดึง scope object ออกมาจาก body tag ได้ดังนี้

var scope = angular.element($('body')).scope();

จากนั้น เมื่อเราได้ scope object ออกมาแล้ว เราก็จะสามารถเรียกใช้งาน property และ method ที่อยู่ภายใน controller ได้ตามปกติ ยกตัวอย่างเช่น

alert(scope.title);  // เรียกใช้งาน property ที่ชื่อว่า title
scope.test(); // เรียกใช้งาน method ที่ชื่อว่า test

เทคนิคการ Share Data ระหว่าง Controller ใน Angular.js

สำหรับเทคนิคต่อไปนี้ เป็นการใช้ข้อมูลร่วมกันระหว่าง Controller โดยใช้วิธีการ bind Service ลองดูตามตัวอย่างดังต่อไปนี้ครับ

<!doctype html>
<html ng-app="project">
<head>
    <title>Angular: Service example</title>
    <script src="http://code.angularjs.org/angular-1.0.1.js"></script>
    <script>
var projectModule = angular.module('project',[]);

projectModule.factory('theService', function() { 
    return {
        thing : {
            x : 100
        }
    };
});

function FirstCtrl($scope, theService) {
    $scope.thing = theService.thing;
    $scope.name = "First Controller";
}

function SecondCtrl($scope, theService) {  
    $scope.someThing = theService.thing;
    $scope.name = "Second Controller!";
}
    </script>
</head>
<body> 
    <div ng-controller="FirstCtrl">
        <h2>{{name}}</h2>
        <input ng-model="thing.x"/>        
    </div>

    <div ng-controller="SecondCtrl">
        <h2>{{name}}</h2>
        <input ng-model="someThing.x"/>            
    </div>
</body>
</html>

จากตัวอย่าง เมื่อเรามีการ update ข้อมูลใน Service จะส่งผลให้ Controller ที่ Bind เอาไว้กับข้อมูลใน Service มีการเปลี่ยนแปลงตามไปด้วย

วิธีการ Communicate ข้าม Controller ใน Angular.js

สำหรับผู้ที่ใช้ Angular.js และมีการสร้าง Controller ไว้มากกว่า 1 ตัว สามารถสื่อสารข้ามกันระหว่าง Controller ได้ โดยอาศัยการใช้ Message ดังต่อไปนี้

function FirstController($scope) {
  $scope.$on('someEvent', function() {});
  // another controller or even directive
}

function SecondController($scope) {
  $scope.$emit('someEvent', args);
}
 
จากในตัวอย่างจะสังเกตุว่า SeconCotroller จะส่ง Message ออกมา ในขณะที่ FirstController ก็รอรับ Message อยู่ ลองเอาไปประยุกต์ใช้ดูแล้วกันนะครับ

แหล่งที่มา : http://stackoverflow.com/questions/9293423/can-one-controller-call-another-in-angularjs

เทคนิคการ Remove Item ออกจาก Array ใน JavaScript

สมมุติว่าเราประกาศ Array ไว้ดังต่อไปนี้

var myArray = ['a','b','c','d','e'];

แล้วเราต้องการลบ item ตัวที่ 1 (index เท่ากับ 0) ออกจาก myArray ด้วยการใช้คำสั่ง delete ดังต่อไปนี้

delete myArray[0];

สิ่งที่เกิดขึ้นก็คือ JavaScript จะไม่ได้ทำการลบ item นั้นออกจาก Array จริงๆ แต่เป็นการไปแทนที่ข้อมูลในตำแหน่งนั้นๆด้วย undefined ซึ่งถ้าเรา debug ดูใน Firebug เราจะเห็นว่าข้อมูลใน myArray เป็นดังต่อไปนี้

[undefined,'b','c','d','e'];

ซึ่งไม่เป็นไปอย่างที่เราต้องการ แต่มีวิธีแก้ครับ โดยนำ Script ที่เขียนไว้โดย John Resig ซึ่งเขียนเพิ่มคำสั่ง remove เข้าไปใน Array  มาใช้งานดังนี้ครับ

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

ตอนนี้ หากเราอยากลบ item ที่ 1 เราก็เพียงใช้คำสั่ง

myArray.remove(0);  // item ที่ 1 จะมีค่า index = 0

หรือหากอยากจะลบ item ลำดับที่ 2 จากตำแหน่งท้ายสุดของ Array ก็สามารถทำได้ดังนี้

myArray.remove(-2);

หรือหากอยากจะลบหลายๆ item พร้อมๆ กัน ก็สามารถทำได้ โดยการส่งค่า index ที่ต้องการลบเข้าไป ดังนี้

myArray.remove(1,3); // จะเป็นการลบ item ในตำแหน่งที่ 2 และ 4 ตามลำดับ

แหล่งที่มา : http://stackoverflow.com/questions/500606/javascript-array-delete-elements


Wednesday, 21 November 2012

Object Oriented JavaScript

โดยปกติเราสามารถเขียน JavaScript ได้ 2 รูปแบบ ดังนี้ คือ

1. แบบProcedural

function sayHelloWorld(name){
    alert('Hello '+name);
}

sayHelloWorld('Peter');

2. แบบ Object Oriented

var World = function(){
     this.sayHello = function(name){
        alert('Hello '+name);
    }
}

var world = new World();
world.sayHello('Peter');

การเขียนในรูปแบบของ Object Oriented เหมาะสำหรับการเขียน Application ที่มีความซับซ้อนขึ้นมาหน่อย จะสังเกตุว่าการสร้าง Class ในภาษา JavaScript จะดูแปลกๆหน่อย เพราะสร้างขึ้นมาจาก Function ประโยชน์ของการเขียน JavaScript ในแบบ Object Oriented คือสามารถดูแลแก้ไขได้ง่าย รองรับการ Encapsulate โดยการสร้าง Property และ Method ช่วยป้องกันปัญหา Global Pollution เพราะเราสามารถประกาศตัวแปรให้อยู่เฉพาะใน Scope ของ Class เท่านั้น

ในภาษา JavaScript ไม่มี Private หรือ Public directive ให้ใช้เหมือนในภาษาอื่นๆ แต่เราสามารถจำลองการสร้าง private variable ได้โดยการประกาศ local variable ไว้ภายใน Class สำหรับ variable ตัวไหนที่เราต้องการให้สามารถ access ได้แบบ Public เราก็สามารถประการให้เป็น property ไปซะ อย่างเช่น

var World = function(){
    var counter = 10;
     this.color = 'red';
     this.sayHello = function(name){
        alert('Hello '+name);
    }
}

จากตัวอย่าง เราจะไม่สามารถ access ตัวแปรที่ชื่อว่า counter ได้จากภายนอก Class เนื่องจากเป็น Local Variable ที่มองเห็นได้เฉพาะภายใน Scope ของ Class เท่านั้น แต่สำหรับตัวแปรที่ชื่อว่า this.color และ method ที่ชื่อว่า this.sayHello() นั้น ถือว่าเป็นตัวแปรประเภท Public ซึ่งเราสามารถ access ได้จากภายนอก Class โดย access ผ่าน instance ของ Class อย่างเช่น

var world = new World();
world.color = 'blue';
world.sayHello('Peter');

จากตัวอย่าง เราสร้าง instance ขึ้นมาจาก Class World โดยเก็บ instance ที่สร้างขึ้นมาไว้ในตัวแปรที่ชื่อว่า world จากนั้นเราก็จะสามารถเรียกใช้งาน property และ method ที่อยู่ภายใน Class World ได้ทั้งหมด แต่เราจะไม่สามารถ access ตัวแปรที่ชื่อว่า counter ได้ เนื่องจากเป็น local variable ที่มองเห็นได้เฉพาะภายใน Class เท่านั้น สำหรับการเรียกใช้งาน property และ method ภายใน Class สามารถทำได้ โดยเรียกใช้งานผ่านตัวแปรที่ชื่อว่า this ซึ่งใช้แทน instance ของ class นั้นๆ

หากดูเผินๆ เหมือนกับว่าภาษา JavaScript สามารถทำ inheritance ได้ แต่แท้ที่จริงแล้วภาษา JavaScript ไม่มีความสามารถในการทำ inheritance โดยตรง แต่จำลองการทำ inheritance ผ่านกระบวนการ copy คุณสมบัติจาก Object ตัวอื่นมาไว้ใน prototype ของตัวเอง และอาศัยการค้นหา method ที่ประกาศเอาไว้ใน prototype chain ดังตัวอย่างต่อไปนี้

World = function(){
    this.sayHello = function(){
        alert('say hello');
    }
}

MyClass = function(x){
    this.x = x;
}

MyClass.prototype = new World();

var obj = new MyClass(10);
obj.sayHello();

จากในตัวอย่าง เราจะเห็นได้ว่า MyClass ทำการสืบทอดคุณสมบัติมาจาก World ทำให้ MyClass สามารถเรียกใช้งาน sayHello() (ซึ่ง implement เอาไว้ใน World) ได้ หากเราลอง debug object ผ่าน Firebug ดู เราก็จะเห็นว่า method ที่ inherit มา ถูก copy มาไว้ที่ _prototype ซึ่งทำให้ class ของเราสามารถเรียกใช้งานได้ ซึ่งดูคล้ายกับการ inherit แต่ที่จริงแล้วเป็นการ copy

Tuesday, 13 November 2012

AngularJS - JavaScript MVC Framework powered by Google




AngularJS คือ JavaScript Framework อีกตัวหนึ่งที่ช่วยในการพัฒนา Web Application ในรูปแบบ MVC (Model-View-Controller) มีจุดเด่นคือ ความง่ายในการใช้งาน เขียน Code ไม่เยอะ รองรับการทำ Data Binding แบบ Bi-Direction (เวลาที่เราแก้ไข View จะส่งผลให้ Model มีการ update โดยอัตโนมัติ ในทำนองเดียวกัน เวลาที่เราแก้ไข Model ก็จะส่งผลให้ View มีการ update โดยอัตโนมัติเช่นเดียวกัน) การใช้งาน AngularJS สามารถใช้งานได้ง่าย เพราะไม่ต้องมีการ extend class อย่างเช่น Model , View , Controller ก่อนการใช้งาน (ซึ่งถือเป็นจุดเด่นที่แตกต่างจาก MVC Framework อย่าง Backbone) การนำ MVC Framework มาใช้ในการ Develop Web Application จะช่วยให้เราสามารถแยกส่วนที่เป็น Presentation (HTML) ออกจากส่วนที่เป็น Coding (JavaScript) ทำให้แก้ไขได้ง่าย การควบคุมการทำงานของ Web Application ใน Angular.js จะทำผ่าน Controller ซึ่งถือเป็นแกนหลักในการทำงาน โดยหลักในการทำงาน จะอาศัยการ binding ส่วนที่เป็น UI บนหน้าเว็บของเราเข้ากับตัว Controller จากนั้นเราจะเขียน Code สำหรับควบคุมการทำงานทั้งหมดผ่าน Controller นี้ ไม่ว่าจะเป็นการ ลบ เพิ่ม แก้ไข ข้อมูล หรือ อะไรก็แล้วแต่ ซึ่ง Code ภายในส่วนของ Controller นั้นจะมองเห็นข้อมูลของหน้าเว็บเราผ่านทาง Model (เราต้องทำการ binding UI element ให้เป็น Model ก่อน ผ่าน attribute ที่ชื่อว่า ng-model)

Web Application ที่เราพัฒนาขึ้นโดยใช้ AngularJS สามารถแบ่งการทำงานออกเป็นหลาย Controller ได้ โดยเราสามารถกำหนด config ของ Application เพื่อให้ route ไป ยัง controller แต่ละตัวได้ นอกจากนั้น เรายังสามารถพัฒนาความสามารถเพิ่มเติม โดยสร้างเป็น module ผ่านทาง factory method ที่ AngularJS เตรียมไว้ให้ ทำให้ code ของเรามีความเป็นระเบียบเรียบร้อย สำหรับ class ช่วยเหลือต่างๆที่จำเป็นก็มีเตรียมไว้ให้ใช้งาน อย่างเช่น HTTP Object เพื่อเอาไว้สร้าง AJAX Request เป็นต้น

โดยรวมๆ ถือว่าใช้งานง่ายครับ พอลองใช้งานแล้วก็รู้สึกชอบทันที เป็น Framework ที่หลวมๆ ไม่ค่อยมีกฎเกณฑ์อะไรมาก ช่วยให้เราเขียน Web Application ได้ง่ายขึ้น ไม่ต้อง extend class ต่างๆให้วุ่นวาย เขียน code น้อย เพราะการใช้ data binding จะช่วยลดการเขียน code ลงได้เยอะ เพราะเราไม่ต้อง query DOM element เพื่อทำการ update เอง แต่ตัว Framework จะจัดการให้เสร็จเรียบร้อย อันนี้เป็นความเห็นส่วนตัวของผมเอง ยังไงก็ไปลองเล่นดูกันเอาเองแล้วกันนะครับ อาจจะชอบหรือไม่ชอบไมรู้ แต่ผมชอบ!

แหล่งที่มา : http://angularjs.org

Monday, 12 November 2012

เรียกใช้งาน JavaScript ในแบบ Modular โดยใช้ Require.js

สำหรับบทความนี้ผมอยากจะมาแนะนำเกี่ยวกับเทคนิคในการเรียกใช้งาน JavaScript ในแบบ Modular โดยใช้ Require.js ประโยชน์ของการใช้ Require.js คือ จะช่วยให้เราสามารถเรียกใช้งาน JavaScript ในแบบ Asynchronous (คือความสามารถในการ load หลายๆ file ได้พร้อมๆกัน) ทำให้สามารถ load เสร็จได้เร็วขึ้นกว่าการ load โดยใช้ script tag แบบปกติ แต่เป้าหมายจริงๆ ของ Require.js อยู่ที่การแบ่ง coding ออกให้เป็นสัดส่วน หรือเราเรียกว่า module แต่ละ module จะมีหน้าที่เฉพาะของตัวเอง หากเราต้องการใช้ เราก็ค่อยเรียกมาใช้งาน ซึ่งทำให้การเรียกใช้งานมีความยืดหยุ่น เรียกใช้งานได้รวดเร็ว และสามารถ maintain ได้ง่ายอีกด้วย นอกจากนั้น Require.js ยังมีความสามารถในเรื่องของการ load dependency ที่จำเป็นก่อนการเรียกใช้งานแต่ละ module ได้อีกด้วย เดี๋ยวเราลองมาดูวิธีการใช้งานแบบง่ายๆก่อนนะครับ ขั้นแรกเลย ก็ต้องไป download "require.js" มาก่อน (โดยเข้าไป download ได้จาก http://requirejs.org) จากนั้น วิธีการเรียกใช้งาน ให้เรียกใช้งานดังต่อไปนี้ครับ

<script data-main="scripts/main.js" src="scripts/require.js"></script>

วิธีการเรียกใช้งาน require.js ก็เหมือนกับการเรียกใช้งาน JavaScript อื่นๆโดยทั่วไป แต่ให้สังเกตุ attribute ที่ชื่อว่า data-main ซึ่งมีไว้เพื่อให้เรากำหนด JavaScript ที่ใช้เป็น file หลัก สำหรับที่เราจะเรียกใช้งาน module อื่นๆต่อไป (JavaScript ที่เรากำหนดไว้ใน data-main จะถูกเรียกใช้งานหลังจากที่ "require.js" ถูกโหลดเสร็จเรียบร้อย)

ต่อไป เราจะมาดู script ในส่วนของ main.js (จะตั้งชื่อเป็นอย่างอื่นก็ได้ แต่ถ้าตั้งเป็นชื่ออื่น ก็ต้องกำหนดค่าใน data-main ให้สัมพันธ์กันด้วย แค่นั้นเอง) หน้าที่ของ main.js ก็คือ เป็นไฟล์หลักที่ใช้สำหรับ load module อื่นๆ จะสังเกตุว่า ผมใช้คำว่า module จะไม่ใช้คำว่า script เพราะ Require.js พยายามให้เรามอง JavaScript เป็น module เดี๋ยวมาลองดูตัวอย่างกันก่อนแล้วกันนะครับ

main.js
======
require(["helper/util"], function(util) {
    util.hello();
});

ใน main.js เราเรียกใช้งาน function ที่ชื่อว่า require เพื่อ load "helper/util" module (ให้สังเกตุว่า ไม่ต้องใส่ .js เข้าไป เดี๋ยว require.js จะเติมให้เองโดยอัตโมมัติ) ส่วน path ในการเรียกใช้งาน ก็จะ relative จาก file ที่เรากำหนดให้เป็น file หลัก ซึ่งในที่นี้ก็คือ main.js นั่นเอง (เราสามารถกำหนดได้ว่า จะให้ require.js ไปมองหา module จากที่ไหน โดยการกำหนดค่า config ซึ่งในที่นี้ไม่อธิบายแล้วกันนะครับ เพราะมันจะยาวไป หากสนใจจริงๆ ก็เข้าไปอ่านได้ที่ http://requirejs.org/docs/api.html)

parameter ตัวแรก คือ array ของชื่อ module ที่เราต้องการ load ส่วน parameter ตัวที่สองคือ call function ที่จะถูกเรียกใช้งานเมื่อ module ที่เราต้องการถูก load ขึ้นมาเรียบร้อยแล้วนั่นเอง ให้สังเกตุว่ามีการส่งค่า util เข้าไปที่ function ด้วย นั่นหมายความว่า module ที่เรา load ในขณะนี้จะถูกส่งมาในตัวแปรที่ชื่อว่า util นั่นเองครับ ซึ่งภายใน function นี้ เราสามารถเรียกใช้งาน util.hello() ได้แล้วครับ

ส่วนต่อไป เดี๋ยวเราจะมาลองดูกันต่อใน script ส่วนที่เป็นการ define module ซึ่งจากตัวอย่างในที่นี้ก็คือ util.js ครับ

util.js
=====
define(function(){   
    var m = {};

    m.hello = function(){
        alert('Hello!');
    }

    return m;
});

ในส่วนของ util.js เราสร้าง Anonymous Function ขึ้นมา ซึ่งภายจะกำหนดค่าต่างๆ หรือจะทำอะไรก็แล้วแต่ แต่สุดท้ายจะต้องคืนค่า module กลับมา สำหรับในตัวอย่างนี้เราประกาศตัวแปรที่ชื่อว่า m เอาไว้สำหรับเก็บ namespace ที่เราสร้างขึ้นมาใหม่ โดยใช้ {} และภายใน namespace นี้ เราก็ประกาศ function ชื่อว่า hello() เอาไว้ เมื่อทุกอย่างเสร็จเรียบร้อย เราจะคืนค่า m กลับออกไป

สำหรับตัวอย่างที่ยกมาให้ดู อาจจะดูไม่ค่อยมีประโยชน์ในการนำไปใช้งานจริงๆสักเท่าไหร่ แต่มันได้ concept ครับ ลองคิดดูแบบง่ายๆ แทนที่จะต้องเขียน Framework ตัวใหญ่ๆ ถ้าหากเราสามารถแบ่ง Framework ออกเป็นส่วนๆ แล้วค่อยๆเรียกใช้งานเท่าที่จำเป็น เราก็ไม่จำเป็นต้อง load JavaScript ตัวใหญ่ๆทีเดียวแบบเมื่อก่อนแล้วครับ และยังช่วยให้เรา extend ความสามารถเพิ่มเติมต่อไปได้ง่ายอีกด้วยครับ เพราะมีการแยก module ออกจากกันอย่างชัดเจน ช่วยให้เราทำงานง่ายขึ้น และก็แก้ไขก็ง่ายดีด้วยครับ

ที่จริงแล้วเทคนิคนี้มันมีชื่อเรียก ชื่ออย่างเป็นทางการมันเรียกว่า Modular Pattern เป็น Best Practice รปแบบหนึ่ง ซึ่งผมเห็นว่ามันมีประโยชน์ดี แล้วสามารถนำไปใช้งานได้จริงครับ ก็คิดว่าบทความนี้น่าจะพอจุดประกายให้ใครอีกหลายคนนำไปประยุกต์ใช้งานกันต่อไปนะครับ หากนำไปใช้งานแล้วได้ผลดี ก็อาจช่วยเขียนบทความเป็นวิทยาทานให้คนอื่นๆต่อไปแล้วกันนะครับ
  
แหล่งที่มา : http://requirejs.org

JavaScript Module Pattern

สำหรับใครที่กำลังศึกษา หรือว่ากำลังเขียน JavaScript Framework ควรที่จะอ่านบทความนี้ดูก่อนครับ คิดว่าหากนำไปใช้ จะช่วยให้สามารถวางโครงสร้างของ Framework ได้ flexible มากขึ้น โดยเราสามารถออกแบบ Framework ออกเป็น module แล้วค่อยๆ include เพิ่มเติมตามความจำเป็น ซึ่งช่วยให้ Framework ของเราไม่ใหญ่เกินความจำเป็นด้วยครับ ลองศึกษาดูได้ที่นี่ครับ http://bit.ly/Uy44Y8

ควรศึกษาการใช้งาน require.js เพิ่มเติมด้วยนะครับ อ่านเพิ่มเติมได้ที่นี่ครับ http://requirejs.org

วิธีการ Select DOM Element โดยไม่ใช้ jQuery

โดยส่วนมากเวลาที่เราต้องการ select DOM element เรามักจะนึกถึง jQuery เพราะใช้ง่าย และแทบจะเป็น library มาตรฐานสำหรับการพัฒนา web ในปัจจุบันไปแล้ว สำหรับบทความนี้ ผมอยากจะมาแนะนำการ select DOM element โดยไม่ใช้ jQuery (อาจจะด้วยเหตุผลใดก็ตาม) เมื่อก่อน เวลาเราจะ select DOM element เราก็มักจะนึกถึง methods ที่ชื่อว่า getElementById() กับ getElementByTagName() ซึ่งการใช้งานค่อนข้างจำกัด ไม่หลากหลายเท่าการใช้ CSS Selector เหมือนใน jQuery ซึ่งเป็นหนึ่งในเหตุผลว่าทำไม jQuery ถึงได้รับความนิยม หลายๆคน (รวมทั้งผมด้วย) ใช้ jQuery กันจนเคยชิน จนไม่รู้เลยว่าเดี๋ยวนี้ DOM selector APIs ได้รับการพัฒนาขึ้นจากเมื่อก่อนมาก ซึ่งในปัจจุบันรองรับการใช้งาน CSS selector แล้วด้วย ผ่านทาง APIs ที่ชื่อว่า querySelector() และ querySelectorAll() ทั้ง 2 APIs รองรับการใช้งาน CSS selector โดยมีความแตกต่างกันที่ querySelector() จะ return DOM element เพียงแค่ตัวเดียว ในขณะที่ querySelectorAll() จะ return DOM elements ทั้งหมดที่ตรงตามเงื่อนไข ส่วนวิธีการเรียกใช้งาน ดูตามตัวอย่างข้างล่างนี่เลยครับ

document.querySelector('#myheader') //returns the element with ID="myheader"
document.querySelector('p.description') //returns the P with class="description" element

document.querySelectorAll('.mygroup') //returns all elements with class="mygroup"
document.querySelectorAll('#biography, #gallery') //returns both elements "#biography" and "#gallery" (inclusive)

แหล่งที่มา : http://www.javascriptkit.com/dhtmltutors/css_selectors_api.shtml

Saturday, 10 November 2012

ทำความรู้จักกับ WebFont Loader

WebFont Loader ช่วยให้เราสามารถเรียกใช้งาน Web Font Provider ต่างๆ ไม่ว่าจะเป็น Google, Typekit, Fonts.com หรือแม้กระทั่ง font ที่เรา host เอง ผ่าน interface แบบเดียวกัน ทำให้เราสามารถ เปลี่ยน Provider ได้ง่าย นอกจากนั้น ยังมี Event ต่างๆให้เราใช้งาน ยกตตัวอย่างเช่น "Active" จะ Trigger เมื่อ Web Font พร้อมใช้งาน ซึ่งมีประโยชน์อย่างมากในตอนที่เรานำ Web Font ไปใช้กับ canvas ซึ่งถ้าหากเราเรียกใช้งาน Web Font ในขณะที่ยัง load ไม่เสร็จ การแสดงผลก็จะไม่เป็นอย่างที่เราต้องการ และในอีกกรณีคือ ใช้เพื่อแก้ปัญหา "flash of unstyled text" (FOUT)

ตัวอย่างการเรียกใช้งาน WebFont Loader เพื่อ Load WebFont ที่ Hosting เอง

    <script type="text/javascript">
      WebFontConfig = {
        custom: { families: ['iannvcd'],urls: ['fonts/iannvcd/stylesheet.css']},
        active: function(){},
        inactive: function(){}
      };
      (function() {
        var wf = document.createElement('script');
        wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
            '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
        wf.type = 'text/javascript';
        wf.async = 'true';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(wf, s);
      })();
    </script>

สำหรับผู้ที่สนใจ สามารถศึกษาเพิ่มเติมได้ที่ https://github.com/typekit/webfontloader

แหล่งที่มา : https://github.com/typekit/webfontloader

เทคนิคการทำให้ IE8 ใช้งาน HTML5 Canvas 2D ได้

สำหรับ Browser ใหม่ๆอย่างเช่น Firefox, Safari, Chrome และ Opera ต่างรองรับการใช้งาน HTML5 canvas  2D context อยู่แล้ว แต่ปัญหาอยู่ที่ IE8 ซึ่งยังไม่รองรับการใช้งาน ซึ่งเราสามารถทำให้ IE8 รองรับการใช้งาน canvas ได้ โดยใช้ ExplorerCanvas ซึ่งวิธีการใช้งานก็เพียงแค่ include script ดังต่อไปนี้เข้าไปบริเวณส่วนหัวของ page

<head>
<!--[if IE]><script src="excanvas.js"></script><![endif]-->
</head>

แต่วิธีนี้ก็มีปัญหาอยู่นิดนึง คือ ในกรณีที่เราสร้าง canvas ขึ้นมาเองในขณะ runtime (คือ ไม่ได้เขียน canvas tag ไว้ใน HTML แต่ใช้ JavaScript สร้างขึ้นมา) ซึ่งในกรณีนี้ canvas ที่ถูกสร้างขึ้นจะไม่มี method ที่ชื่อว่า getContext ซึ่งจะทำให้เราไม่สามารถวาดอะไรไปบน canvas ได้นั่นเอง วิธีในการแก้ไขก็คือ  คุณจะต้องเรียก G_vmlCanvasManager.initElement() ก่อน ดังต่อไปนี้

var el = document.createElement('canvas');
G_vmlCanvasManager.initElement(el);
var ctx = el.getContext('2d');

สำหรับผู้ที่สนใจ สามารถเข้าไปดาวน์โหลด ExplorerCanvas มาใช้งานได้จากที่นี่ครับ http://code.google.com/p/explorercanvas/

แหล่งที่มา: http://diveintohtml5.info/canvas.html

Friday, 21 September 2012

Load CSS and JavaScript at Runtime using "rloader"

สำหรับผู้ที่ต้องการ load CSS หรือ JavaScript ในขณะ Run Time ลองใช้งาน rloader ดูครับ เป็น jQuery Plugin ใช้งานง่าย เพียงแค่บรรทัดเดียว นอกจากนั้น rloader ยังช่วย tracking CSS หรือ JavaScript ที่เรา load ไปแล้ว ทำให้ไม่ load ซ้ำ ซึ่งจะเหมือนกับการใช้งาน require_once ใน PHP เทคนิคในการ load CSS หรือ JavaScript ในรูปแบบนี้ บางครั้งเราเรียกกันว่า Lazy Loading สำหรับผู้ที่สนใจ สามารถศึกษาการใช้งานได้ที่นี่ครับ http://code.google.com/p/rloader/

แหล่งที่มา: http://code.google.com/p/rloader/

Monday, 27 August 2012

JSColor JavaScript/HTML Color Picker

พอดีว่าผมกำลังพัฒนา Web Application ขึ้นมาตัวหนึ่ง และอยากจะให้ User สามารถกำหนดสีของ Background ได้เอง แต่ถ้าจะให้ User ป้อน HTML Color ในรูปแบบ Hex Code ก็คงจะดูไม่ดีซักเท่าไหร่ ก็เลยลองค้นใน Google ในที่สุดก็เจอ Library ตัวนึงมีชื่อว่า JSColor ซึ่งเป็น JavaScript สำหรับช่วยสร้าง Color Picker พัฒนาขึ้นโดย Jan Odvárko ดูแล้วน่าสนใจดีครับ สำหรับใครที่อยากจะลอง Download มาใช้งานก็เข้าไปที่นี่ครับ http://jscolor.com/

แหล่งที่มา : http://jscolor.com/

Friday, 17 August 2012

Social Media Share Button

ผมกำลังเพิ่ม share to Social เข้าไปใน web ที่ผมกำลังทำอยู่ ก็เลยลองค้นไปใน Google ก็เจอวิธีสร้างปุ่ม share แบบง่ายๆ ก็เลยอยากจะ post เอาไว้ เผื่อใครกำลังอยากได้วิธีในการสร้างปุ่ม share แบบไม่ต้องวุ่นวายมาก ลองเข้าไปดูตัวอย่างได้ที่นี่ครับ http://bit.ly/Pq9640 หรือถ้าหากไม่อยากเขียนเอง ก็ลองใช้บริการของ share this, add this หรือ Lockerz Share ดู มีให้เลือก share ไปหลาย platform ครับ ส่วนอันนี้เป็นอีกบทความหนึ่งที่เขียนแนะนำวิธีการ implement social button เอาไว้ ลองเข้าไปอ่านดูครับ http://yoast.com/social-buttons/

แหล่งที่มา : http://bit.ly/Pq9640

Friday, 3 August 2012

Use Regular Expression with JavaScript

บทความที่จะนำมาแนะนำต่อไปนี้เป็น Tutorial ที่สอนการใช้งาน Regular Expression ในภาษา JavaScript (เป็นบทความจาก http://www.advanced-javascript-tutorial.com) มีตัวอย่างการใช้งานหลายรูปแบบ มีประโยชน์ครับ สำหรับผู้ที่สนใจสามารถเข้าไปอ่านได้ที่นี่ครับ http://www.advanced-javascript-tutorial.com/RegularExpressions.cfm#.UBrnUqCOJdg

แหล่งที่มา: http://www.advanced-javascript-tutorial.com

Thursday, 2 August 2012

History.js gracefully supports the HTML5 History/State APIs in all browsers

สำหรับใครที่อยากใช้งาน HTML5 History/State APIs แต่กลัวปัญหาเรื่อง Browser Support ลองดู JavaScript Library ตัวนี้ครับ มืชื่อว่า history.js ซึ่งจะช่วยให้เราสามารถใช้งาน HTML5 History/State APIs ได้ใน Browser ต่างๆ สำหรับ Browser ไหนที่ยังไม่รองรับ ก็จะ Fall Back ไปใช้ Hash URL แทน สำหรับผู้ที่สนใจสามารถเข้าไป download มาใช้งานได้ที่นี่ครับ https://github.com/balupton/History.js

แหล่งที่มา: https://github.com/balupton/History.js

jQuery hashchange Plugin by Ben Alman

ปัญหาอย่างหนึ่งของการใช้ AJAX คือ เราจะไม่สามารถใช้งาน Direct URL หรือทำการ Bookmark ได้เหมือนกับการสร้าง web page โดยวิธีปกติ สำหรับวิธีแก้ไขที่เราพบเห็นกันทั่วไปคือการใช้ location.hash (parameter บริเวณส่วนต่อท้ายของ URL ที่ขึ้นต้นด้วย #) และจับการเปลี่ยนแปลงของ hash ผ่าน window.onhashchange แต่ปัญหาก็คือจะสามารถใช้งานได้เฉพาะในบาง Browser เท่านั้น (IE 8+, FF 3.6+, Chrome 5+) วันนี้ผมจึงอยากจะมาแนะนำ jQuery hashchange plugin ที่พัฒนาขึ้นโดย Ben Alman ที่จะช่วยให้เราสามารถจับการเปลี่ยนแปลงของ hash ได้แบบ cross browser สำหรับวิธีการใช้งาน สามารถดูได้ตามตัวอย่างต่อไปนี้ครับ


สำหรับผู้ที่สนใจสามารถศึกษาเพิ่มเติมได้ที่นี่ครับ http://benalman.com/projects/jquery-hashchange-plugin/

แหล่งที่มา: http://benalman.com/projects/jquery-hashchange-plugin/