jQuery UI가 위젯 라이브러리를 사용하는 방법


진행률 표시줄을 생성하겠습니다. 다음 예제에서 볼 수 있듯이 이는 생성할 플러그인의 이름과 플러그인을 지원하는 함수를 포함하는 객체 리터럴이라는 두 개의 매개변수를 사용하여 jQuery.widget()을 호출하여 수행할 수 있습니다. 플러그인이 호출되면 새 플러그인 인스턴스가 생성되고 모든 기능은 해당 인스턴스의 컨텍스트에서 실행됩니다. 이는 두 가지 중요한 측면에서 표준 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 네임스페이스를 사용했습니다. 한 수준 깊이의 네임스페이스만 생성할 수 있으므로 custom.progressbar는 유효한 플러그인 이름이지만 very.custom.progressbar는 그렇지 않습니다.

Widget Factory가 두 가지 속성을 제공하는 것을 볼 수 있습니다. this.element는 요소를 포함하는 jQuery 객체입니다. 여러 요소가 포함된 jQuery 객체에서 플러그인이 호출되는 경우 각 요소에 대해 별도의 플러그인 인스턴스가 생성되고 각 인스턴스는 고유한 this.element를 갖습니다. 두 번째 속성인 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() 메서드와 같습니다. 평가자로 사용할 이름만 전달하거나 이름과 값을 전달할 수 있습니다. setter로 사용하거나 키/값 쌍의 해시를 전달하여 여러 값을 설정합니다. 평가자로 사용되는 경우 플러그인은 전달된 이름에 해당하는 옵션의 현재 값을 반환합니다. setter로 사용되면 설정된 각 옵션에 대해 플러그인의 _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 이벤트 객체, 이벤트와 연결된 데이터 해시라는 세 가지 매개 변수를 사용합니다. 콜백 이름은 유일한 필수 매개변수이지만 다른 매개변수는 플러그인에서 사용자 정의 기능을 구현하려는 사용자에게 유용합니다. 예를 들어, 드래그 가능한 플러그인을 생성하는 경우 드래그 콜백이 실행될 때 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( "" );
    }
});
🎜콜백 함수는 기본적으로 추가 옵션이므로 다른 옵션과 마찬가지로 가져오고 설정할 수 있습니다. 콜백이 실행될 때마다 해당 이벤트가 트리거됩니다. 이벤트 유형은 연결 플러그인 이름과 콜백 함수 이름에 따라 결정됩니다. 콜백과 이벤트 모두 아래 예제와 같이 이벤트 개체와 이벤트와 관련된 데이터 해시라는 동일한 두 매개 변수를 허용합니다. 플러그인에는 사용자가 플러그인을 사용하지 못하도록 방지하는 기능이 포함되어야 할 수 있으며, 이를 수행하는 가장 좋은 방법은 취소 가능한 콜백을 만드는 것입니다. 사용자는 event.preventDefault()를 호출하거나 false를 반환하여 네이티브 이벤트를 취소할 수 있는 것처럼 콜백이나 관련 이벤트를 취소할 수 있습니다. 사용자가 콜백을 취소하면 _trigger() 메서드가 false를 반환하므로 플러그인 내에서 적절한 기능을 구현할 수 있습니다. 🎜rrreee

Essence

위젯 팩토리를 사용하여 플러그인을 생성하는 방법을 살펴봤으니 이제 실제로 어떻게 작동하는지 살펴보겠습니다. 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 네임스페이스를 사용한다는 점에 유의하세요. 자신만의 플러그인을 만들 때 자신만의 네임스페이스를 만들어야 합니다. 이렇게 하면 플러그인이 어디에서 왔는지, 어느 범위에 속하는지 더 명확해집니다.