jQuery UI がウィジェット ライブラリを使用する方法


プログレスバーを作成します。次の例に示すように、これは、作成するプラグインの名前と、そのプラグインをサポートする関数を含むオブジェクト リテラルの 2 つのパラメータを指定して jQuery.widget() を呼び出すことで実行できます。プラグインが呼び出されると、新しいプラグイン インスタンスが作成され、すべての関数がそのインスタンスのコンテキストで実行されます。これは、2 つの重要な点で標準の jQuery プラグインとは異なります。まず、コンテキストは DOM 要素ではなくオブジェクトです。次に、コンテキストは常に単一のオブジェクトであり、コレクションではありません。 jQuery.widget() 来完成,它带有两个参数:一个是要创建的插件名称,一个是包含支持插件的函数的对象文字。当插件被调用时,它将创建一个新的插件实例,所有的函数都将在该实例的语境中被执行。这与两种重要方式的标准 jQuery 插件不同。首先,语境是一个对象,不是 DOM 元素。其次,语境总是一个单一的对象,不是一个集合。

$.widget( "custom.progressbar", {
    _create: function() {
        var progress = this.options.value + "%";
        this.element
            .addClass( "progressbar" )
            .text( progress );
    }
});

插件的名称必须包含命名空间,在这个实例中,我们使用了 custom 命名空间。您只能创建一层深的命名空间,因此,custom.progressbar 是一个有效的插件名称,而 very.custom.progressbar 不是一个有效的插件名称。

我们看到部件库(Widget Factory)为我们提供了两个属性。this.element 是一个包含一个元素的 jQuery 对象。如果我们的插件在包含多个元素的 jQuery 对象上调用,则会为每个元素创建一个单独的插件实例,且每个实例都会有自己的 this.element。第二个属性,this.options,是一个包含所有插件选项的键名/键值对的哈希(hash)。这些选项可以被传给插件,如下所示:

$( "<div></div>" )
    .appendTo( "body" )
    .progressbar({ value: 20 });

当我们调用 jQuery.widget(),它通过给 jQuery.fn(用于创建标准插件的系统) 添加函数来扩展 jQuery。所添加的函数名称是基于您传给 jQuery.widget() 的名称,不带命名空间 - "progressbar"。传给插件的选项是在插件实例中获取设置的值。如下面的实例所示,我们可以为任意一个选项指定默认值。当设计您的 API 时,您应该清楚你的插件的最常见的使用情况,以便您可以设置适当的默认值,且确保使所有的选项真正可选。

$.widget( "custom.progressbar", {
 
    // Default options.
    options: {
        value: 0
    },
    _create: function() {
        var progress = this.options.value + "%";
        this.element
            .addClass( "progressbar" )
            .text( progress );
    }
});

调用插件方法

现在我们可以初始化我们的进度条,我们将通过在插件实例上调用方法来执行动作。为了定义一个插件方法,我们只在我们传给 jQuery.widget()

$.widget( "custom.progressbar", {
 
    options: {
        value: 0
    },
 
    _create: function() {
        var progress = this.options.value + "%";
        this.element
            .addClass( "progressbar" )
            .text( progress );
    },
 
    // Create a public method.
    value: function( value ) {
 
        // No value passed, act as a getter.
        if ( value === undefined ) {
            return this.options.value;
        }
 
        // Value passed, act as a setter.
        this.options.value = this._constrain( value );
        var progress = this.options.value + "%";
        this.element.text( progress );
    },
 
    // Create a private method.
    _constrain: function( value ) {
        if ( value > 100 ) {
            value = 100;
        }
        if ( value < 0 ) {
            value = 0;
        }
        return value;
    }
});

プラグインの名前には名前空間が含まれている必要があります。この例では、custom 名前空間を使用しました。ネームスペースは 1 レベルの深さまでしか作成できないため、custom.progressbar は有効なプラグイン名ですが、very.custom.progressbar は有効ではありません。

ウィジェット ファクトリが 2 つのプロパティを提供していることがわかります。 this.element は、要素を含む jQuery オブジェクトです。複数の要素を含む jQuery オブジェクトでプラグインが呼び出された場合、要素ごとに個別のプラグイン インスタンスが作成され、各インスタンスには独自の this.element が設定されます。 2 番目の属性 this.options は、すべてのプラグイン オプションを含むキーと値のペアのハッシュです。これらのオプションは次のようにプラグインに渡すことができます:

var bar = $( "<div></div>" )
    .appendTo( "body" )
    .progressbar({ value: 20 });
 
// Get the current value.
alert( bar.progressbar( "value" ) );
 
// Update the value.
bar.progressbar( "value", 50 );
 
// Get the current value again.
alert( bar.progressbar( "value" ) );
jQuery.widget() を呼び出すと、それが jQuery.fn に渡されます (標準プラグインの作成に使用されます)。システム)jQueryを拡張する機能を追加します。追加された関数名は、名前空間なしで jQuery.widget() に渡した名前 (「progressbar」) に基づいています。プラグインに渡されるオプションは、プラグイン インスタンスに設定された値を取得します。以下の例に示すように、任意のオプションにデフォルト値を指定できます。 API を設計するときは、適切なデフォルトを設定し、すべてのオプションを確実にオプションにできるように、プラグインの最も一般的な使用例を認識する必要があります。
$.widget( "custom.progressbar", {
    options: {
        value: 0
    },
    _create: function() {
        this.options.value = this._constrain(this.options.value);
        this.element.addClass( "progressbar" );
        this.refresh();
    },
    _setOption: function( key, value ) {
        if ( key === "value" ) {
            value = this._constrain( value );
        }
        this._super( key, value );
    },
    _setOptions: function( options ) {
        this._super( options );
        this.refresh();
    },
    refresh: function() {
        var progress = this.options.value + "%";
        this.element.text( progress );
    },
    _constrain: function( value ) {
        if ( value > 100 ) {
            value = 100;
        }
        if ( value < 0 ) {
            value = 0;
        }
        return value;
    }
});

プラグイン メソッドの呼び出し

これで、進行状況バーを初期化できます。プラグイン インスタンスでメソッドを呼び出してアクションを実行します。プラグイン メソッドを定義するには、jQuery.widget() に渡すオブジェクト内の関数を参照するだけです。関数名の前にアンダースコアを付けることで、「プライベート」メソッドを定義することもできます。 🎜
$.widget( "custom.progressbar", {
    options: {
        value: 0
    },
    _create: function() {
        this.options.value = this._constrain(this.options.value);
        this.element.addClass( "progressbar" );
        this.refresh();
    },
    _setOption: function( key, value ) {
        if ( key === "value" ) {
            value = this._constrain( value );
        }
        this._super( key, value );
    },
    _setOptions: function( options ) {
        this._super( options );
        this.refresh();
    },
    refresh: function() {
        var progress = this.options.value + "%";
        this.element.text( progress );
        if ( this.options.value == 100 ) {
            this._trigger( "complete", null, { value: 100 } );
        }
    },
    _constrain: function( value ) {
        if ( value > 100 ) {
            value = 100;
        }
        if ( value < 0 ) {
            value = 0;
        }
        return value;
    }
});
🎜 プラグイン インスタンスでメソッドを呼び出すには、メソッドの名前を jQuery プラグインに渡します。呼び出しているメソッドがパラメータを受け入れる場合は、それらのパラメータをメソッド名の後に渡すだけです。 🎜🎜🎜注: 🎜メソッドは、プラグインの初期化に使用されたのと同じ jQuery 関数にメソッド名を渡すことによって実行されます。これは、連鎖メソッド呼び出しを維持しながら jQuery 名前空間の汚染を防ぐために行われます。この章の後半では、より自然に見える他の使用方法を見ていきます。 🎜
var bar = $( "<div></div>" )
    .appendTo( "body" )
    .progressbar({
        complete: function( event, data ) {
            alert( "Callbacks are great!" );
        }
    })
    .bind( "progressbarcomplete", function( event, data ) {
        alert( "Events bubble and support many handlers for extreme flexibility." );
        alert( "The progress bar value is " + data.value );
    });
 
bar.progressbar( "option", "value", 100 );

オプションを使用する

option() メソッドはプラグインに自動的に提供されます。 option() メソッドを使用すると、初期化後にオプションを取得および設定できます。このメソッドは、jQuery の .css() メソッドや .attr() メソッドに似ています。値として使用する名前だけを渡すことも、名前と値を渡すこともできます。セッターとして使用するか、キーと値のペアのハッシュを渡して複数の値を設定します。 valuer として使用される場合、プラグインは渡された名前に対応するオプションの現在の値を返します。セッターとして使用すると、設定されたオプションごとにプラグインの _setOption メソッドが呼び出されます。プラグインで _setOption メソッドを指定して、オプションの変更に反応できます。オプションを変更するアクションを個別に実行するには、_setOptions をオーバーロードできます。 option() 方法是自动提供给插件的。option() 方法允许您在初始化后获取并设置选项。该方法像 jQuery 的 .css().attr() 方法:您可以只传递一个名称作为取值器来使用,也可以传递一个名称和值作为设置器使用,或者传递一个键名/键值对的哈希来设置多个值。当作为取值器使用时,插件将返回与传入名称相对应的选项的当前值。当作为设置器使用时,插件的 _setOption 方法将被每个被设置的选项调用。我们可以在我们的插件中指定一个 _setOption 方法来反应选项更改。对于更改选项要独立执行的动作,我们可以重载 _setOptions

var bar = $( "<div></div>" )
    .appendTo( "body" )
    .progressbar()
    .data( "progressbar" );
 
// Call a method directly on the plugin instance.
bar.option( "value", 50 );
 
// Access properties on the plugin instance.
alert( bar.options.value );

添加回调

最简单的扩展插件的方法是添加回调,这样用户就可以在插件状态发生变化时做出反应。我们可以看下面的实例如何在进度达到 100% 时添加回调到进度条。_trigger() 方法有三个参数:回调名称,一个启动回调的 jQuery 事件对象,以及一个与事件相关的数据哈希。回调名称是唯一一个必需的参数,但是对于想要在插件上实现自定义功能的用户,其他的参数是非常有用的。例如,如果我们创建一个可拖拽插件,我们可以在触发拖拽回调时传递 mousemove 事件,这将允许用户对基于由事件对象提供的 x/y 坐标上的拖拽做出反应。请注意,传递到 _trigger() 的原始的事件必须是一个 jQuery 事件,而不是一个原生的浏览器事件。

var bar = $.custom.progressbar( {}, $( "<div></div>" ).appendTo( "body") );
 
// Same result as before.
alert( bar.options.value );

回调函数本质上只是附加选项,所以您可以像其他选项一样获取并设置它们。无论何时执行回调,都会有一个相对应的事件被触发。事件类型是通过连接插件的名称和回调函数名称确定的。回调和事件都接受两个相同的参数:一个事件对象和一个与事件相关的数据哈希,具体如下面实例所示。您的插件可能需要包含防止用户使用的功能,为了做到这点,最好的方法就是创建爱你可撤销的回调。用户可以撤销回调或者相关的事件,与他们撤销任何一个原生事件一样,都是通过调用 event.preventDefault() 或返回 false 来实现的。如果用户撤销回调,_trigger() 方法将返回 false

$.custom.progressbar.prototype.reset = function() {
    this._setOption( "value", 0 );
};

コールバックの追加🎜🎜 プラグインを拡張する最も簡単な方法は、プラグインの状態が変化したときにユーザーが反応できるようにコールバックを追加することです。次の例は、進行状況が 100% に達したときに進行状況バーにコールバックを追加する方法を示しています。 _trigger() メソッドは、コールバック名、コールバックを開始する jQuery イベント オブジェクト、イベントに関連付けられたデータのハッシュの 3 つのパラメータを取ります。コールバック名は唯一の必須パラメータですが、他のパラメータはプラグインにカスタム機能を実装したいユーザーにとって役立ちます。たとえば、ドラッグ可能なプラグインを作成する場合、ドラッグ コールバックが起動されたときに Mousemove イベントを渡すことができます。これにより、ユーザーはイベント オブジェクトによって提供される X/Y 座標に基づいてドラッグに反応できるようになります。 _trigger() に渡される元のイベントは、ネイティブ ブラウザ イベントではなく、jQuery イベントである必要があることに注意してください。 🎜
$.widget( "custom.progressbar", {
    options: {
        value: 0
    },
    _create: function() {
        this.options.value = this._constrain(this.options.value);
        this.element.addClass( "progressbar" );
        this.refresh();
    },
    _setOption: function( key, value ) {
        if ( key === "value" ) {
            value = this._constrain( value );
        }
        this._super( key, value );
    },
    _setOptions: function( options ) {
        this._super( options );
        this.refresh();
    },
    refresh: function() {
        var progress = this.options.value + "%";
        this.element.text( progress );
        if ( this.options.value == 100 ) {
            this._trigger( "complete", null, { value: 100 } );
        }
    },
    _constrain: function( value ) {
        if ( value > 100 ) {
            value = 100;
        }
        if ( value < 0 ) {
            value = 0;
        }
        return value;
    },
    _destroy: function() {
        this.element
            .removeClass( "progressbar" )
            .text( "" );
    }
});
🎜コールバック関数は本質的に単なる追加オプションであるため、他のオプションと同じように取得および設定できます。コールバックが実行されるたびに、対応するイベントがトリガーされます。イベントの種類は、接続プラグインの名前とコールバック関数の名前によって決まります。コールバックとイベントは両方とも、以下の例に示すように、イベント オブジェクトとイベントに関連付けられたデータのハッシュという同じ 2 つのパラメーターを受け入れます。プラグインには、ユーザーがプラグインを使用できないようにする機能を含める必要がある場合があります。これを行うための最良の方法は、取り消し可能なコールバックを作成することです。ユーザーは、event.preventDefault() を呼び出すか、false を返すことで、ネイティブ イベントをキャンセルするのと同じように、コールバックや関連イベントをキャンセルできます。ユーザーがコールバックを取り消すと、_trigger() メソッドは false を返し、プラグイン内に適切な機能を実装できるようになります。 🎜rrreee

Essence

Widget Factory を使用してプラグインを作成する方法を説明したので、実際にどのように機能するかを見てみましょう。 jQuery.widget() を呼び出すと、プラグインのコンストラクターが作成され、渡したオブジェクトがプラグイン インスタンスのプロトタイプとして設定されます。プラグインに自動的に追加されるすべての機能は、jQuery.Widget.prototype として定義された基本ウィジェット プロトタイプから取得されます。プラグイン インスタンスが作成されると、プラグイン名をキーとして、jQuery.data を使用して元の DOM 要素に保存されます。 jQuery.widget() 时,它将为插件创建一个构造函数,并设置您为插件实例传入的作为原型的对象。所有自动添加到插件的功能都来自一个基本的小部件原型,该原型定义为 jQuery.Widget.prototype。当创建插件实例时,会使用 jQuery.data 把它存储在原始的 DOM 元素上,插件名作为键名。

由于插件实例直接链接到 DOM 元素上,您可以直接访问插件实例,而不需要遍历插件方法。这将允许您直接在插件实例上调用方法,而不需要传递字符串形式的方法名,同时您也可以直接访问插件的属性。

rrreee

您也可以在不遍历插件方法的情况下创建一个实例,通过选项和元素直接调用构造函数即可:

rrreee

扩展插件的原型

插件有构造函数和原型的最大好处是易于扩展插件。通过添加或修改插件原型上的方法,我们可以修改插件所有实例的行为。例如,如果我们想要向进度条添加一个方法来重置进度为 0%,我们可以向原型添加这个方法,它将在所有插件实例上可调用。

rrreee

如需了解扩展小部件的更多细节,以及如何在一个已有的小部件上创建一个全新的小部件的更多细节,请查看 通过部件库(Widget Factory)扩展小部件(Widget)

清理

在某些情况下,允许用户应用插件,然后再取消应用。您可以通过 _destroy() 方法做到这一点。在 _destroy() 方法内,您应该撤销在初始化和后期使用期间插件所做的一切动作。_destroy() 是通过 .destroy() 方法被调用的,.destroy() 方法是在插件实例绑定的元素从 DOM 上移除时被自动调用的,所以这可被用于垃圾回收。基本的 .destroy() 方法也处理一些常用的清理操作,比如从小部件的 DOM 元素上移除实例引用,从元素上解除绑定小部件命名空间中的所有事件,解除绑定所有使用 _bind()

プラグイン インスタンスは DOM 要素に直接リンクされているため、プラグイン メソッドを経由せずにプラグイン インスタンスに直接アクセスできます。これにより、メソッド名を文字列として渡すことなく、プラグイン インスタンス上でメソッドを直接呼び出すことができるようになり、プラグインのプロパティにも直接アクセスできるようになります。

rrreee

オプションと要素を介してコンストラクターを直接呼び出すだけで、プラグイン メソッドを経由せずにインスタンスを作成することもできます:

rrreee

拡張プラグイン プロトタイプ

プラグインにはコンストラクターとプロトタイプがあります最大の利点は、プラグインの拡張が簡単なことです。プラグイン プロトタイプのメソッドを追加または変更することで、プラグインのすべてのインスタンスの動作を変更できます。たとえば、進行状況を 0% にリセットするメソッドをプログレス バーに追加したい場合、このメソッドをプロトタイプに追加すると、すべてのプラグイン インスタンスで呼び出すことができるようになります。 🎜rrreee🎜 ウィジェットの拡張の詳細と、既存のウィジェットの上に新しいウィジェットを作成する方法については、「Widget Factory を使用してウィジェットを拡張する」をご覧ください。 。 🎜

クリーニング

🎜 ユーザーがプラグインを適用し、特定の状況下でプラグインの適用を解除できるようにします。これは、_destroy() メソッドを通じて実行できます。 _destroy() メソッド内で、初期化中およびその後の使用中にプラグインによって実行されたすべてのアクションを元に戻す必要があります。 _destroy().destroy() メソッドを通じて呼び出されます。これは、DOM からプラグイン インスタンスにバインドされている要素で、削除時に自動的に呼び出されるため、これを使用できます。ゴミ収集用に。基本的な .destroy() メソッドは、ウィジェットの DOM 要素からのインスタンス参照の削除、要素からのウィジェットの名前空間内のすべてのイベントのバインド解除、追加されたすべてのイベントのバインドの解除など、いくつかの一般的なクリーンアップ操作も処理します。 <コード>_bind()。 🎜rrreee🎜コメントを閉じる🎜🎜Widget Factory は、ステートフル プラグインを作成するための単なる方法です。他にもいくつかの異なるモデルがあり、それぞれに独自の長所と短所があります。ウィジェット ファクトリは、多くの一般的な問題を解決し、効率を大幅に向上させます。また、コードの再利用性も大幅に向上するため、jQuery UI やその他のステートフル プラグインに適しています。 🎜

このセクションでは、公式の jQuery UI プラグインによって予約されている custom 命名空间。ui 名前空間を使用することに注意してください。独自のプラグインを作成する場合は、独自の名前空間を作成する必要があります。これにより、プラグインがどこから来たのか、どのスコープに属するのかが明確になります。