Найкращий спосіб розширення плагіна jQuery


77

Я досить новий користувач jQuery, який хоче розширити існуючий плагін jQuery, який виконує близько 75% того, що мені потрібно. Я намагався зробити домашнє завдання з цього приводу. Я перевірив наступні питання щодо stackoverflow:

Я прочитав метод розширення. Однак все це домашнє завдання змусило мене розгубитися. Я працюю з плагіном fullcalendar і мені потрібно змінити деякі особливості поведінки, а також додати нові хуки подій. Я застряг у цьому в самому закритті плагіна? Мені не вистачає чогось очевидного?

В ідеалі ми могли б відокремити наш код від коду плагіна, щоб забезпечити можливе оновлення. Будемо вдячні за будь-яку допомогу, особливо вказівки щодо того, де мені бракує певної інформації чи думок щодо того, чи мають сенс рішення, представлені в інших питаннях Stack Overflow. Мені вони суперечать один одному, і я все ще залишаюся розгубленим.


justkt, чи можете ви опублікувати приклад коду того, як ви розширили плагін fullcalendar? В даний час я намагаюся зробити те саме, але я затруднений і не можу викликати жодної з функцій, які я нібито додав.
Метт Маккормік,

@MattMcCormick - ви пробували прийняту відповідь, перелічену нижче?
justkt

Ах, я включав .prototype. Мені це не потрібно було. Тепер у мене просто $ .extend (true, $ .fullCalendar, extensionMethods); і це працює! В ідеалі я хотів би розширити об'єкт Event, але це не має простору імен, тому я не бачу, як це було б можливо. Це поки працює.
Matt McCormick

2
Див. Msdn.microsoft.com/en-us/library/hh404085.aspx (глава про спадщину)
Катрін

Відповіді:


85

Я просто мав ту саму проблему, намагаючись розширити плагіни інтерфейсу користувача jquery, і ось рішення, яке я знайшов (знайшов через jquery.ui.widget.js):

(функція ($) {
/ **
 * Простір імен: простір імен, в якому знаходиться плагін
 * pluginName: назва плагіна
 * /
    var extensionMethods = {
        / *
         * отримати ідентифікатор елемента
         * це деякий контекст у рамках існуючого плагіна
         * /
        showId: function () {
            повернути this.element [0] .id;
        }
    };

    $ .extend (істина, $ [Простір імен] [Ім'я плагіна] .prototype, extensionMethods);


}) (jQuery);

сподіваюся, це допоможе, будь ласка, запитайте, якщо у вас є питання.


2
Отже, щоб пояснити, якби я хотів розширити автозаповнення користувацького інтерфейсу jQuery, тоді значення Namespaceбуде "ui", а pluginName"автозаповнення"?
Метт Хаггінс,

1
Здається, я відповів на власне запитання. Я знайшов у джерелі автозаповнення, де воно викликає jQuery.widget("ui.autocomplete", ...), і у джерелі віджетів, де воно розділяється на ".", При цьому простір імен - індекс 0, а pluginName - індекс 1. Отже, іншими словами, схоже, я мав рацію. :)
Метт Хаггінс,

4
@Jared - Я в підсумку скористався вашою порадою тут щодо розширення автозаповнення інтерфейсу jQuery. Я описую свої цілі тут: matthuggins.com/articles/… , і я маю повний код тут: github.com/mhuggins/jquery-ui-autocomplete-hints . Якщо у вас є якісь пропозиції щодо вдосконалення, я хотів би їх почути!
Метт Хаггінс,

4
Як знайти простір імен та ім'я плагіна?
Пабло СГ Пачеко

17

У мене було те саме питання, і я прийшов сюди, тоді відповідь Джареда Скотта надихнула мене.

(function($) {

    var fullCalendarOrg = $.fn.fullCalendar;

    $.fn.fullCalendar = function(options) {
        if(typeof options === "object") {
            options = $.extend(true, options, {
                // locale
                isRTL: false,
                firstDay: 1,
                // some more options
            });
        }

        var args = Array.prototype.slice.call(arguments,0);
        return fullCalendarOrg.apply(this, args);
    }

})(jQuery);

3

Я виявив, що з великою кількістю плагінів методи захищені / приватні (тобто в області закриття). Якщо вам потрібно змінити функціональність методів / функцій, то вам не пощастить, якщо ви не хочете це розкласти. Тепер, якщо вам не потрібно змінювати будь-який із цих методів / функцій, тоді ви можете використовувати$.extend($.fn.pluginName, {/*your methods/properties*/};

Інша справа, яку я закінчив робити раніше, - це просто використовувати плагін як властивість мого плагіна, замість того, щоб намагатися його розширити.

Насправді все зводиться до того, як кодується плагін, який ви хочете розширити.


В основному розширенні - це все, що я хочу зробити, але в деяких випадках це такі речі, як додавання обробників подій до елементів DOM, створених всередині плагіна. В інших випадках мені потрібно замінити поведінку всередині існуючих методів. Чим більше я читаю, тим менше я бачу чистого способу це зробити. Будь-які інші думки?
justkt

Ну, якщо ці способи є такими в лобковому API (яким вони, здається, не є), тоді ви можете використати метод, про який я згадав вище, щоб замінити визначення функції. Крім цього, немає чистого шляху. Вам просто доведеться розкласти його для своїх потреб і зламати.
вундеркіндлі

2
@prodigitalson public * API;)
Niks

2
$.fn.APluginName=function(param1,param2)
{
  return this.each(function()
    {
      //access element like 
      // var elm=$(this);
    });
}

// sample plugin
$.fn.DoubleWidth=function()
  {
    return this.each(function()
      {
        var _doublWidth=$(this).width() * 2;
        $(this).width(_doubleWidth);
      });
  }

//

<div style="width:200px" id='div!'>some text</div>

// за допомогою користувацького плагіна

$('#div1').DoubleWidth();

/// над написаним типом утилів зазвичай працюють з елементами dom ///////////////// користувацькі утиліти

(function($){
  var _someLocalVar;
  $.Afunction=function(param1,param2) {
    // do something
  }
})(jquery);

// доступ до util як

$.Afunction();

// цей тип утилів зазвичай розширює javascript


1
Це не те, про що він запитує - він запитує, як найкраще розширити вже існуючий плагін таким чином, що дозволяє оновити базовий плагін, який він використовує в якості базового, додаючи на додачу до нього потрібну функціональність.
вундеркіндлі

1

Мій підхід до переписування плагінів jQuery полягав у переміщенні методів та змінних, до яких потрібно отримати доступ, до блоку параметрів та викликати 'розширити'

// in the plugin js file
$.jCal = function (target, opt) {
    opt = $.extend({
       someFunctionWeWantToExpose: function() {
           // 'this' refers to 'opt', which is where are our required members can be found
       }
    }

    // do all sorts of things here to initialize

    return opt; // the plugin initialisation returns an extended options object
}


////// elsewhere /////

var calendar = $("#cal1").jCal();
calendar.someFunctionWeWantToExpose();

1

Приклад схожий на відповідь Джареда Скотта, але копіювання оригінального прототипу об’єкта дає можливість викликати батьківський метод:

(function($) {

    var original = $.extend(true, {}, $.cg.combogrid.prototype);

    var extension = {
        _renderHeader: function(ul, colModel) {
            original._renderHeader.apply(this, arguments);

            //do something else here...
        }
    };

    $.extend(true, $.cg.combogrid.prototype, extension);

})(jQuery);

0

Віджет jQuery можна розширити за допомогою jQuery Widget Factory.

(function ($) {
    "use strict";

    define([
        "jquery",
        "widget"
    ], function ($, widget) {
        $.widget("custom.yourWidget", $.fn.fullCalendar, {
            yourFunction: function () {
                // your code here
            }
        });

        return $.custom.yourWidget;
    });
}(jQuery));

Перегляньте документацію jQuery, щоб дізнатись більше:
API Widget Factory
Розширення віджетів за допомогою Widget Factory

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.