javascript 如何处理 jQuery UI 小部件中的事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4021470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 10:10:29  来源:igfitidea点击:

How to handle events in jQuery UI widgets

javascriptjqueryjquery-ui

提问by Arun P Johny

I'm trying to write a jQuery widget following the model given here. Here is a snapshot of the widget:

我正在尝试按照此处给出的模型编写一个 jQuery 小部件。这是小部件的快照:

(function ($) {
    $.widget("ui.notification", {
        _create: function () {
            if (!this.element.hasClass("ntfn")) {
                this.element.addClass("ntfn");
            }

            this.elTitle = this.element.append("<div class='ntfn-title'>Notifications</div>");

            this.elTitle.click(this._titleClick)
        },
        _titleClick: function () {
            console.log(this);
        }
    });
})(jQuery);

Here the problem is with the scope of "this" inside the _titleClickmethod, inside the method this points to the titleelement. But I need it to point to the widgetelement.

这里的问题在于_titleClick方法内部“this”的范围,在方法内部 this 指向title元素。但我需要它指向widget元素。

I think one way of doing it will be to use a wrapper class like

我认为这样做的一种方法是使用包装类

var that = this;
this.elTitle.click(function() {
    that._titleClick.apply(that, arguments);
});

Is this the best way to solve this problem or is there any general pattern to solve this issue?

这是解决这个问题的最佳方法还是有解决这个问题的一般模式?

采纳答案by Arun P Johny

I wrote a method my own to solve this issue

我自己写了一个方法来解决这个问题

_wrapCallback : function(callback) {
    var scope = this;
    return function(eventObject) {
        callback.call(scope, this, eventObject);
    };
}

回答by Jens Bannmann

Use the this._on()methodto bind the handler. This method is provided by the jQuery UI widget factory and will make sure that within the handler function, thisalways refers to the widget instance.

使用this._on()方法绑定处理程序。此方法由 jQuery UI 小部件工厂提供,将确保在处理程序函数中this始终引用小部件实例。

_create: function () {
    ...
    this._on(this.elTitle, {
        click: "_titleClick" // Note: function name must be passed as a string!
    });
},
_titleClick: function (event) {
    console.log(this);       // 'this' is now the widget instance.
},

回答by nrako

You should look to jQuery.proxy() http://api.jquery.com/jQuery.proxy/

你应该看看 jQuery.proxy() http://api.jquery.com/jQuery.proxy/

el.bind('evenname', $.proxy(function () {
   this.isMyScope.doSomething();
}, scope));

回答by Steve Sheldon

In your create, init (or somewhere in your instance) function do this:

在您的创建、init(或您实例中的某处)函数中执行以下操作:

        _create: function() {

        ...

        // Add events, you will notice a call to $.proxy in here. Without this, when using the 'this'
        // property in the callback we will get the object clicked, e.g the tag holding the buttons image
        // rather than this widgets class instance, the $.proxy call says, use this objects context for the the 'this'
        // pointer in the event. Makes it super easy to call methods on this widget after the call.
        $('#some_tag_reference').click($.proxy(this._myevent, this));

        ...

        },

Now define your objects event hander like this:

现在像这样定义你的对象事件处理程序:

        _myevent: function(event) {

            // use the this ptr to access the instance of your widget
            this.options.whatever;
        },

回答by legendJSLC

define var scope=this, and use scopein event handler.

定义var scope=this,并在事件处理程序中使用作用域

    _create: function () {           
        var scope = this;
        $(".btn-toggle", this.element).click(function () {
            var panel = $(this).closest(".panel");
            $(this).toggleClass("collapsed");
            var collapsed = $(this).is(".collapsed");
            scope.showBrief(collapsed);
        });
    },

回答by b01

Another way to do the same thing without using closure, is to pass the widget as a part of the event data like so:

另一种不使用闭包做同样事情的方法是将小部件作为事件数据的一部分传递,如下所示:

// using click in jQuery version 1.4.3+.
var eventData = { 'widget': this };

// this will attach a data object to the event,
// which is passed as the first param to the callback.
this.elTitle.click(eventData, this._titleClick);

// Then in your click function, you can retrieve it like so:
_titleClick: function (evt) {
    // This will still equal the element.
    console.log(this);
    // But this will be the widget instance.
    console.log(evt.data.widget);
};

回答by rism

It used to be via the jquery bindmethod now onis favoured.

它曾经是通过 jquerybind方法现在on受到青睐。

As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document. For earlier versions, the .bind() method is used for attaching an event handler directly to elements. Handlers are attached to the currently selected elements in the jQuery object, so those elements must exist at the point the call to .bind() occurs. For more flexible event binding, see the discussion of event delegation in .on() or .delegate().

从 jQuery 1.7 开始, .on() 方法是将事件处理程序附加到文档的首选方法。对于早期版本, .bind() 方法用于将事件处理程序直接附加到元素。处理程序附加到 jQuery 对象中当前选定的元素,因此这些元素必须在调用 .bind() 时存在。要获得更灵活的事件绑定,请参阅 .on() 或 .delegate() 中事件委托的讨论。

_create: function () {
   var that = this; 
   ...
   elTitle.on("click", function (event) {
             event.widget = that;   // dynamically assign a ref (not necessary)
             that._titleClick(event);
    });
},
_titleClick: function (event) {
    console.log(this);             // 'this' now refers to the widget instance.
    console.log(event.widget);     // so does event.widget (not necessary)
    console.log(event.target);     // the original element `elTitle`
},