Thứ Tư, 6 tháng 1, 2016

Xây dựng ứng dụng di động dùng HTML5 - Bài 5

[Webapp Tutorial] Xây dựng ứng dụng di động dùng HTML5 - Bài 5

header-object

[Webapp Tutorial] Xây dựng ứng dụng di động dùng HTML5 - Bài 5

Chúng ta sẽ lần lượt làm 2 việc này ngay sau đây. Tuy  nhiên, để có thể nắm được những điều sẽ trình bày ngay sau đây bạn cần có các kiến thức nền như sau:

  1. Biết cơ bản về lập trình javascript, hiểu biết về DOM và cách javascript thao tác với DOM Elements
  2. Biết cơ bản về lập trình với JQuery

Bắt tay vào việc thôi, trong thư mục của ứng dụng hãy tạo tập tin có tên dwdrawing.js,sử dụng thẻ <script> nhúng tập tin này vào tập tin dwdrawing.html ngay sau 2 thẻ <script> đã có ở trong phần <head>. Trong tập tin mới tạo này chúng ta sẽ viết mã javascript để tạo ra một Widget cho JQuery Mobile.

 

5.1. Kiến thức cơ bản về việc viết JQuery Mobile-Widge


JQuery Mobile cung cấp cơ chế cho phép lập trình viên dễ dàng tích hợp thêm tính năng vào bộ thư viện đã có một cách “chính quy”. Đó là cơ chế thêm vào các Widget.
Bản thân một phần trong JQuery Mobile được tạo nên từ nhiều Widget khác nhau. Mỗ Widget chứa các xử lý cho một nhóm chức năng trên một đối tượng nào đó. Lấy ví dụ đơn giản như

  1. Xử lý việc hiển thị và hiệu ứng trên thanh header và thanh footer (gọi chung là fixedtoolbar)
  2. Xử lý việc hiển thị page như là một dialog
  3. Xử lý việc hiển thị và các thao tác, sự kiện cho các nút nhấn (button)

Tương tự như thế, để viết mã JQuery Mobile một cách đúng chuẩn, chúng ta sẽ viết một widget và tạm đặt tên cho widget này là dwdrawing
Mở tập tin dwdrawing.js và nhập vào đoạn mã cơ bản để khai báo thêm một widget  có tên dwdrawing như sau:

(function( $, undefined ) {
 $.widget( "mobile.dwdrawing", $.mobile.widget, {
  
 });
})( jQuery );

Để cho người dùng vẽ hình, tất nhiên chúng ta cần biết người dùng đang vẽ loại hình gì (Hình chữ nhật, Elip hay Path) và người dùng đang chọn màu gì (trong số 7 màu  tương ứng với 7 cây bút của chúng ta). Để lưu trữ hai giá trị này chúng ta sẽ thêm vào thuộc tính có tên là options, mã sẽ như sau:

(function( $, undefined ) {
 $.widget( "mobile.dwdrawing", $.mobile.widget, {
  options:{
   color:'#077ff0',
   pen:'path'//lát có lẽ cần sửa lại chỗ này
  }
 });
})( jQuery );

Mỗi đối tượng widget yêu cầu một hàm khởi tạo có tên _create, hàm này sẽ được JQuery Mobile gọi bất kì khi nào trong mã Javascript sau này chúng ta gọi gởi tạo Widget bằng cách dùng cú pháp dạng: $(selector).dwdrawing(optionsObj);
Hãy thêm vào phương thức này và mã của chúng ta sẽ có chút ít thay đổi như sau:

 

(function( $, undefined ) {
 $.widget( "mobile.dwdrawing", $.mobile.widget, {
  options:{
   color:'#077ff0',
   pen:'path'
  },
  
  _create: function(){
   /*tạo một vài biến sẽ dùng tới sau*/
   var self = this,
   canvas = this.element,
   o = this.options;
  }
 });
})( jQuery );

Tiếp sau, chúng ta sẽ thêm vào đoạn mã thực hiện khởi tạo widget này tự động mỗi khi trang được tạo xong. Để làm việc này chúng ta sẽ nghe ngóng sự kiện trang được tạo xong “pagecreate”, khi sự kiện này diễn ra chúng ta sẽ gọi khởi tạo widget dwdrawing. Code để làm đoạn này được thêm vào như sau:

(function( $, undefined ) {
 $.widget( "mobile.dwdrawing", $.mobile.widget, {
  options:{
   color:'#077ff0',
   pen:'path'//lát có lẽ cần sửa lại chỗ này
  },
  
  _create: function(){
   /*tạo một vài biến sẽ dùng tới sau*/
   var self = this,
   canvas = this.element,
   o = this.options;
  }
 });
 
 /*tự động khởi tạo mỗi khi trang được tạo xong*/
 $( document ).bind( "pagecreate", function( e ) {
  $(":jqmData(role='dwdrawing')", e.target)
  .dwdrawing({pensId:'pens',colorsId:'colors'});
 });
})( jQuery );

Trở lại trang dwdrawing.html, hãy thêm vào thuộc tính data-role=“dwdrawing” cho thẻ <canvas> ván vẽ của chúng ta.
Xem ở đoạn code javascript mới thêm vào, các bạn thấy chúng ta đã truyền cho phương thức khởi tạo widget tham số là đối tượng:

{pensId:'pens',colorsId:'colors'}

Để kiểm tra xem mọi chuyện có diễn ra đúng hay không, ta sẽ đặt một Break-point ngay phía cuối phương thức _create và refresh lại trang. Hình sau cho các bạn thấy kết quả khi Debug dùng Developer Tools trong trình duyệt Google Chrome.

h10 Nhìn qua khung Watch Expressions, chúng ta thấy một vài điều

    • canvas: chính là đối tượng tương đương với thẻ <canvas> trong HTML khi chúng ta lấy về thông qua JQuery
    • o: JQuery Mobile đã tự động thực hiện việc trộn các thuộc tính của options mà chúng ta khai báo (ở dòng 3 hình trên) với đối tượng là tham số truyền vào (chứa colorsId và pensId) khi khởi tạo widget.

 

5.2. Phương thức xử lý việc người dùng chọn một màu vẽ

Chúng ta sẽ viết mã để khi người dùng bấm chọn một màu thì chương trình sẽ thực hiện 3 thao tác:

  1. Việc 1. Cây bút màu hiện tại đang được chọn sẽ thụt lại và mờ đi
  2. Việc 2. Cây bút mới được chọn sẽ thò dài ra và hiện rõ lên
  3. Việc 3. Lấy màu tương ứng với cây bút mới được chọn vào thuộc tính color của đối tượng options (options hiện tại là một thuộc tính của đối tượng widget dwdrawing).

Chúng ta sẽ đặt tên cho nó là _changeColorListener và code của phương thức này sẽ được viết như sau:

/*nghe ngóng việc bấm chọn màu mới*/
_changeColorListener:function(){
 /*bắt sự kiện bấm vào một cây bút (thẻ li)*/
 var self = this;
 $("#"+this.options.colorsId+" li" )
 .bind('vclick',function(e){
  /*Việc 1. hiệu ứng làm mờ bút màu hiện tại*/
  $("#"+self.options.colorsId+" li.active" )
  .animate({opacity:0.4,width:40},150)
  .removeClass('active');
  
  /*Việc 2. hiệu ứng hiện rõ bút màu mới click*/
  $(this).animate({opacity:0.9,width:60},
   200,
   "linear",
   function(){
    /*Việc 3. thiết lập màu mới chọn vào options*/
    self.options.color = "#"+$(this).attr('class').substring(1);
    $(this).addClass('active');
   });
  });
}//kết thúc _changeColorListener

Bạn hãy đọc các ghi chú ở trên để hiểu rõ chúng ta thực hiện từng việc ra sao. Như đã nói, các bạn cần có kiến thức JQuery cơ bản để hiểu được đoạn code trên. Nếu bạn có hứng thú mà có điều gì đó không hiểu rõ, hãy đặt câu hỏi trên group facebook tại http://facebook.com/groups/danweb
Chúng ta sẽ gọi phương thức này trong khi khởi tạo widget, có nghĩa ngay trong phương thức _create, toàn bộ tập tin dwdrawing.js trở thành như sau:

(function( $, undefined ) {
 $.widget( "mobile.dwdrawing", $.mobile.widget, {
  options:{
   color:'#077ff0',
   pen:'path'//lát có lẽ cần sửa lại chỗ này
  },
  
  _create: function(){
   /*tạo một vài biến sẽ dùng tới sau*/
   var self = this,
   canvas = this.element,
   o = this.options;
   this._changeColorListener();
  },
  
  /*nghe ngóng việc bấm chọn màu mới*/
  _changeColorListener:function(){
   /*bắt sự kiện bấm vào một cây bút (thẻ li)*/
   var self = this;
   $("#"+this.options.colorsId+" li" )
   .bind('vclick',function(e){
    /*Việc 1. hiệu ứng làm mờ bút màu hiện tại*/
    $("#"+self.options.colorsId+" li.active" )
    .animate({opacity:0.4,width:40},150)
    .removeClass('active');
    
    /*Việc 2. hiệu ứng hiện rõ bút màu mới click*/
    $(this).animate({opacity:0.9,width:60},
     200,
     "linear",
     function(){
      /*Việc 3. thiết lập màu mới chọn vào options*/
      self.options.color = "#"+$(this).attr('class').substring(1);
      $(this).addClass('active');
     });
    });
  }//kết thúc _changeColorListener
 });
 
 /*tự động khởi tạo mỗi khi trang được tạo xong*/
 $( document ).bind( "pagecreate", function( e ) {
  $(":jqmData(role='dwdrawing')", e.target)
  .dwdrawing({pensId:'pens',colorsId:'colors'});
 });
})( jQuery );

 

5.3. Phương thức xử lý việc người dùng bấm chọn kiểu vẽ

Gần tương tự như trên, chúng ta sẽ viết phương thức _changePenListener nhằm xử lý việc người dùng chọn kiểu vẽ hình chữ nhật hay Elip hay Path.
mã nguồn của phương thức này như sau:

/*nghe ngóng việc bấm chọn kiểu vẽ*/
_changePenListener:function(){
 /*bắt sự kiện bấm vào một kiểu (thẻ li)*/
 var self = this;
 $("#"+this.options.pensId+" li" )
 .bind('vclick',function(e){
  /*Việc 1. hiệu ứng làm mờ kiểu hiện tại*/
  $("#"+self.options.pensId+" li.active" )
  .animate({opacity:0.4,width:40},150)
  .removeClass('active');
  
  /*Việc 2. hiệu ứng hiện rõ kiểu mới click*/
  $(this).animate({opacity:0.9,width:60},
   200,
   "linear",
   function(){
    /*Việc 3. thiết lập kiểu mới chọn vào options*/
    self.options.pen = $(this).attr('class');
    $(this).addClass('active');
   });
  });
}//kết thúc _changePenListener

Chúng ta cũng thực thi nó ngay khi khởi tạo widget này, thêm vào dòng lệnh gọi nó trong phương thức _create, toàn mã nguồn của tập tin dwdrawing.js sẽ như sau:

(function( $, undefined ) {
 $.widget( "mobile.dwdrawing", $.mobile.widget, {
  options:{
   color:'#077ff0',
   pen:'path'//lát có lẽ cần sửa lại chỗ này
  },
  
  _create: function(){
   /*tạo một vài biến sẽ dùng tới sau*/
   var self = this,
   canvas = this.element,
   o = this.options;
   this._changeColorListener();
   this._changePenListener();
  },
  
  /*nghe ngóng việc bấm chọn màu mới*/
  _changeColorListener:function(){
   /*bắt sự kiện bấm vào một cây bút (thẻ li)*/
   var self = this;
   $("#"+this.options.colorsId+" li" )
   .bind('vclick',function(e){
    /*Việc 1. hiệu ứng làm mờ bút màu hiện tại*/
    $("#"+self.options.colorsId+" li.active" )
    .animate({opacity:0.4,width:40},150)
    .removeClass('active');
    
    /*Việc 2. hiệu ứng hiện rõ bút màu mới click*/
    $(this).animate({opacity:0.9,width:60},
     200,
     "linear",
     function(){
      /*Việc 3. thiết lập màu mới vào options*/
      self.options.color = "#"+$(this).attr('class').substring(1);
      $(this).addClass('active');
     });
    });
  },//kết thúc _changeColorListener
  
  /*nghe ngóng việc bấm chọn kiểu vẽ*/
  _changePenListener:function(){
   /*bắt sự kiện bấm vào một kiểu (thẻ li)*/
   var self = this;
   $("#"+this.options.pensId+" li" )
   .bind('vclick',function(e){
    /*Việc 1. hiệu ứng làm mờ kiểu hiện tại*/
    $("#"+self.options.pensId+" li.active" )
    .animate({opacity:0.4,width:40},150)
    .removeClass('active');
    
    /*Việc 2. hiệu ứng hiện rõ kiểu mới click*/
    $(this).animate({opacity:0.9,width:60},
     200,
     "linear",
     function(){
      /*Việc 3.thiết lập kiểu mới vào options*/
      self.options.pen = $(this).attr('class');
      $(this).addClass('active');
     });
    });
  }//kết thúc _changePenListener
 });
 
 /*tự động khởi tạo mỗi khi trang được tạo xong*/
 $( document ).bind( "pagecreate", function( e ) {
  $(":jqmData(role='dwdrawing')", e.target)
  .dwdrawing({pensId:'pens',colorsId:'colors'});
 });
})( jQuery );

Để mọi chuyện được đơn giản trước khi chúng ta đi nội dung tiếp sau các bạn hãy tải source-code chúng ta đã cùng nhau làm cho tới thời điểm này tại đây: dwdrawing-v3.zip
Kiểm tra việc hiển thị và sự kiện bấm chọn công cụ trên trình duyệt Safari của IOS, mọi test-case đều ok

h11

Kiểm tra việc hiển thị và việc thực hiện chọn công cụ trên Buit-in Browser của Android 3.1, mọi tesk-case đều ok.

h12

 

Còn tiếp...

 

 

Đào Ngọc Giang

Bình luận  

 
0 #2 Đào Ngọc Giang Thứ 2-04-13 17:15
Hi Vương!
Về câu hỏi 1:
- Đoạn {pensId:'pens', colorsId:'color s'} trong Javascript là 1 đối tượng không tên, có 2 thuộc tính (property). Thuộc tính pensId mang giá trị là 'pens', thuộc tính colorsId mang giá trị là 'colors'.
- Vậy đoạn .dwdrawing({pensId:'pens', colorsId:'color s'}); có nghĩa gọi phương thức dwdrawing() và truyền vào tham số cho nó là đối tượng ta vừa đề cập trên.

Về câu hỏi 2:
- nếu bắt buộc li có 2 class thì bạn không dùng thuộc tính class làm mã màu nữa. Thay vào đó bạn có thể đặt một thuộc tính có tên ví dụ dạng data-color="#ff 0000" rồi sau đó get giá trị mã màu theo kiểu $('li').attr('d ata-color')
Trích dẫn
 
 
0 #1 Nguyễn Đức Vương Thứ 2-04-13 09:13
Chào anh, anh có thể cho em hỏi đoạn {pensId:'pens', colorsId:'color s'} hoạt động như nào được không. Nó lấy giá trị của 2 cái ul hay chỉ ngẫu nhiên trùng tên.
Nếu cái đoạn li color em có 2 class thì phải làm sao để chọn được class màu.
Em xin cảm ơn
Trích dẫn
 

Thêm ý kiến


Security code
Làm mới


2

Facebook

Thống kê truy cập

Hiện có 313 khách đang truy cập
1795318

0 nhận xét: