2009-02-25 4 views
7

Tôi đang cố viết một plugin sẽ thêm một vài phương thức vào đối tượng trình bao bọc jQuery. Về cơ bản, tôi muốn khởi tạo nó như thế này:jQuery: Có thể đính kèm các trường/phương thức vào đối tượng trình bao bọc jQuery không?

var smart = $('img:first').smartImage(); 

Các 'smartImage' plugin sẽ đính kèm 2 phương pháp để các đối tượng được tham chiếu bởi 'thông minh', vì vậy tôi sẽ có thể làm điều gì đó như:

smart.saveState(); 
// do work 
smart.loadState(); 

Thật không may, tôi không thể tìm ra cách đính kèm 2 phương pháp này vào đối tượng bao bọc. Mã tôi tuân theo mẫu plugin jQuery điển hình:

(function($) 
{ 
    $.fn.smartImage = function() 
    { 
     return this.each(function() 
     { 
      $(this).saveState = function() { /* save */ } 
      $(this).loadState = function() { /* load */ } 
     } 
    } 
} 

Sau khi tôi gọi smartImage(), không phải 'saveState' cũng không phải 'loadState' được xác định. Tôi đang làm gì sai?

Trả lời

5

Bạn không thể đính kèm các phương thức/thuộc tính theo cách mà bạn đã chứng minh, vì như bạn đã nói, đối tượng jQuery chỉ là một trình bao bọc xung quanh bất kỳ phần tử DOM nào chứa nó. Bạn chắc chắn có thể đính kèm các phương thức/thuộc tính vào nó, nhưng chúng sẽ không tồn tại khi chúng được chọn bởi jQuery một lần nữa.

var a = $('.my-object'); 
a.do_something = function(){ alert('hiya'); } 
a.do_something(); // This alerts. 

var b = $('.my-object'); 
b.do_something(); // Freak-out. 

Nếu bạn muốn có một phương pháp để tồn tại trên các đối tượng jQuery khi phục hồi nó một lần thứ hai, nó cần phải được giao cho jQuery.fn. Vì vậy, bạn có thể xác định phương pháp học của bạn, gán nó vào jQuery.fn, và sử dụng các thiết lập dữ liệu jQuery để duy trì trạng thái cho bạn ...

$.fn.setup_something = function() 
{ 
    this.data('my-plugin-setup-check', true); 
    return this; 
} 

$.fn.do_something = function() 
{ 
    if (this.data('my-plugin-setup-check')) 
    { 
     alert('Tada!'); 
    } 
    return this; 
} 

var a = $('.my-object').setup_something(); 
a.do_something(); // Alerts. 
$('.my-object').do_something(); // Also alerts. 

Tôi đề nghị bạn nhìn vào http://docs.jquery.com/Internals/jQuery.datahttp://docs.jquery.com/Core/data#name

+0

Tôi không biết về điều này 'dữ liệu' bản đồ, mà hóa ra là chính xác những gì tôi muốn. Cảm ơn! –

5

Bạn đang thực sự trả về một đối tượng jQuery trong hàm smartImage(). Đó là cách chính xác để viết một plugin jQuery, để bạn có thể kết nối nó với các hàm jQuery khác.

Tôi không chắc chắn có cách nào để làm những gì bạn muốn hay không. Tôi khuyên bạn nên làm như sau:

(function($) { 
    var smartImageSave = function() { return this.each(function() { }); }; 
    var smartImageLoad = function() { return this.each(function() { }); }; 

    $.fn.extend({ "smartImageSave":smartImageSave, 
        "smartImageLoad":smartImageLoad }); 
}); 

var $smart = $("img:first"); 
$smart.smartImageSave(); 
$smart.smartImageLoad(); 

Đó là một kỹ thuật mà tôi quen thuộc và đã sử dụng thành công.

2

Tôi không hoàn toàn chắc chắn lý do tại sao bạn đang thiết kế plugin của bạn theo cách này - bạn có thể muốn xem xét một cái gì đó dọc theo dòng gợi ý jonstjohn của - nhưng sau phải giống với những gì bạn đang yêu cầu cho:

jQuery.fn.extend({ 
    smartImage: function() { 
     return { 
      saveState: function() { /* save */ }, 
      loadState: function() { /* load */ } 
     }; 
    } 
});