2012-09-14 20 views
6

Tôi đọc số jquery documentation of plugin authoring và quen với điều đó. Tuy nhiên, các ví dụ được đưa ra luôn hoạt động trên một tập hợp các phần tử đã so khớp trước đó. Tôi muốn tạo ra một chức năng mà có thể làm cả hai:Cách tạo chức năng plugin jQuery có thể gọi để sử dụng độc lập, không hoạt động trên bộ sưu tập

// example usage of my to-be-created plugin function 

// this is the way described in the docs, and I know how to do that 
$("a").myFunction() 

// but I also want to be able to call the function without a collection: 
$.myFunction(); 

Nếu $.myFunction() được gọi mà không có một bộ sưu tập để hoạt động trên, nó sẽ tạo ra nó là bộ sưu tập riêng của những gì các yếu tố để phù hợp - loại của một quá trình khởi tạo (nhưng không nhất thiết chỉ chạy một lần). Ngoài ra, $.myFunction() nên duy trì khả năng chịu tải.

Các giả về những gì tôi muốn đạt được:

// [...] 
function myFunction(): { 
    if (notCalledOnACollection) { 
     // this should run when called via $.myFunction() 
     $elements = $("a.myClass"); 
    } 
    else { 
     $elements = $(this); 
    } 
    return $elements.each (function() { 
     // do sth. here 
    }); 
} 

Tôi thực sự muốn giữ tất cả các chức năng thực hiện/chức năng trong một định nghĩa hàm duy nhất, và không có hai tên riêng chức năng hoặc hai đều được đặt tên các hàm ở hai vị trí riêng biệt trong đối tượng jQuery. Và tất nhiên tôi có thể thêm tham số myFunction (do_init) cho biết nhánh nào của câu lệnh if để thực thi, nhưng điều đó sẽ làm lộn xộn danh sách đối số của tôi (tôi muốn sử dụng phương pháp đó cho nhiều plugin và sẽ có đối số là myFunction() Tôi chỉ cần rời khỏi đây để đơn giản).

Bất kỳ đề xuất nào tốt?

Trả lời

8

Chỉ cần thêm một tài liệu tham khảo trong definiton plugin, bạn có thể dễ dàng sử dụng mã Plugin tiêu chuẩn:

(function($) { 
    $.myPlugin = $.fn.myPlugin = function(myPluginArguments) { 
     if(this.jquery) 
      //"this" is a jquery collection, do jquery stuff with it 
     } else { 
      //"this" is not a jquery collection 
     } 
    }; 

    $.fn.myPlugin.otherFunc = function() { 
    }; 
})(jQuery); 

Sự khác biệt duy nhất ở đây là phần $.myPlugin = cho phép bạn trực tiếp gọi plugin của bạn mà không cần chạy selector jquery của chức năng. Nếu bạn quyết định bạn cần các hàm hoặc thuộc tính khác, bạn có thể tạo chúng làm thuộc tính của plugin.

Cách sử dụng:

//using a selector (arguments optional) 
$(".someClass").myPlugin(); 

//using the options variable - or whatever your arguments are 
$.myPlugin({id: "someId"}); 

//accessing your other functions/properties 
$.myPlugin.otherFunc(); 
+0

Tôi có vấn đề nghiêm trọng với giải pháp của bạn. Tôi đã sao chép cách tiếp cận của bạn trên jsfiddle: http://jsfiddle.net/pnpbU/ Nhưng một khi tôi chạy '$ .myPlugin()', tất cả trình duyệt thử nghiệm tiêu thụ CPU 100% và gặp khó khăn (thử nghiệm với FF trên Linux và Windows , Safari trên máy Mac). – Dyna

+0

Tôi không thấy sự cố đó trên máy của mình. Và tôi đang ở trên một con khủng long vào lúc này. Và bên cạnh đó, jsfiddle không nên được sử dụng để kiểm tra hiệu suất, họ đã có một loạt các tính năng bổ sung được tải. Tôi cũng đã thử nghiệm tại địa phương và cũng không thấy vấn đề ở đó. Tôi thực sự nghi ngờ những gì bạn thấy có liên quan đến mã này. – Donamite

+0

Bạn đã bỏ ghi chú dòng trong phần js của jsfiddle chưa? Khác nó sẽ không chạy! Tôi đang ở trường đại học ngay bây giờ và có quyền truy cập vào một loạt các máy tính và tôi có thể tái tạo cpu 100% tiêu thụ trên 3 máy vật lý khác nhau. Sử dụng http://jsfiddle.net/pnpbU (với uncommenting dòng cuối cùng) và nhấn chạy sẽ chặn/kết thúc kịch bản trên Fedora 17: Firefox 14.0.1, Chrome 22; Windows 7: Firefox 14, IE9; OS X Lion: Safari 5, Firefox 14. Vì vậy, nó là * definetely * reproducible. Điều này không liên quan gì đến jsfiddle, sao chép tập lệnh đó cùng với jQuery 1.8.0 và chạy cho thấy cùng một hiệu ứng. – Dyna