如何将其传递给另一个函数并获得$(this)

How to pass this to another function and get $(this)

本文关键字:this 函数 另一个      更新时间:2023-09-26

我将this传递给each循环(DOM对象)到另一个函数,但在该函数中,有一部分代码使用$(this) (jQuery对象)。我想知道如何从DOM对象中获得jQuery对象。我以为使用$(obj)会起作用,但它不会!!

我用一个例子来解释。

我想把下面函数的一部分提取到另一个方法中:

    addWidgetControls : function () {
    //...            
    $(settings.widgetSelector, $(settings.columns)).each(function () {
        var thisWidgetSettings = iNettuts.getWidgetSettings(this.id);
        if (thisWidgetSettings.removable) {
            $('<a href="#" class="remove">CLOSE</a>').mousedown(function (e) {
                e.stopPropagation();    
            }).click(function () {
                    $(this).parents(settings.widgetSelector).animate({
                        opacity: 0    
                    },function () {
                        $(this).wrap('<div/>').parent().slideUp(function () {
                            $(this).remove();
                        });
                    });
                return false;
            }).appendTo($(settings.handleSelector, this));
        }
    });        
},

下面是提取的方法(不工作):

    addWidgetControls: function () {
    //...
    $(settings.widgetSelector, $(settings.columns)).each(function () {
        iNettuts.doWidget(this);
    });
},
doWidget: function (widg) {
    $ = jQuery;
    settings = iNettuts.settings;
    var thisWidgetSettings = iNettuts.getWidgetSettings(widg.id);
    if (thisWidgetSettings.removable) {
        $('<a href="#" class="remove"></a>').mousedown(function (e) {
            e.stopPropagation();
        }).click(function () {
            $(widg).parents(settings.widgetSelector).animate({
                opacity: 0
            }, function () {
                $(widg).wrap('<div/>').parent().slideUp(function () {
                    widg.remove();
                });
            });
            return false;
        }).appendTo($(settings.handleSelector, widg));
    }
    //...

doWidget函数中的代码是从原始方法(addWidgetControls)复制的,除了我在其中的任何地方将this更改为widg。但这行不通。

我已经调查了这个问题,并复制了原函数(addWidgetControls)的each循环内的精确代码,并将所有$(widg)替换为$(this),而没有将widg替换为this。它工作正常。(代码如下:)

addWidgetControls : function () {
    //...
    $(settings.widgetSelector, $(settings.columns)).each(function () {
        var wid = this;
        var thisWidgetSettings = iNettuts.getWidgetSettings(wid.id);
        if (thisWidgetSettings.removable) {
            $('<a href="#" class="remove">CLOSE</a>').mousedown(function (e) {
                e.stopPropagation();    
            }).click(function () {
                    $(this).parents(settings.widgetSelector).animate({
                        opacity: 0    
                    },function () {
                        $(this).wrap('<div/>').parent().slideUp(function () {
                            $(this).remove();
                        });
                    });
                return false;
            }).appendTo($(settings.handleSelector, wid));
        }
    });        
},

这意味着当thiswidg相同时,$(this)不知何故与$(widg)不同

PS:我从这个教程中得到了这个代码

如果我理解你,我认为你应该保持widg变量,因为你做了,保持$(this)而不是$(widg)。您将在循环中调用该函数,因为eachthis每次都会更改。然而,如果你每次使用widg,这个变量将指向同一个this在你调用你的函数,这应该是你不希望的。

我想这是因为:

 widg.wrap('<div/>').parent().slideUp(function () {
    widg.remove();
 });

您忘记用$():来包装widg

 $(widg).wrap('<div/>').parent().slideUp(function () {
    $(widg).remove();
 });

也许你想使用Function.prototype.call()方法。

addWidgetControls : function () {
//...            
   $(settings.widgetSelector, $(settings.columns)).each(function () {
       iNettuts.doWidget.call(this);
   }); 
},
doWidget: function(){
    var thisWidgetSettings = iNettuts.getWidgetSettings(this.id);
    if (thisWidgetSettings.removable) {
        $('<a href="#" class="remove">CLOSE</a>').mousedown(function (e) {
            e.stopPropagation();    
        }).click(function () {
                $(this).parents(settings.widgetSelector).animate({
                    opacity: 0    
                },function () {
                    $(this).wrap('<div/>').parent().slideUp(function () {
                        $(this).remove();
                    });
                });
            return false;
        }).appendTo($(settings.handleSelector, this));
    }
}

如果你想设置一个函数的上下文(this赋值),你可以使用applycall。下面是一个例子:

var obj = "testing";
var func = function() {
  alert(this);
}
func();
func.apply(obj);
现在,在浏览器中运行代码(我使用firebug)。

第一个警报将是窗口对象,因为所有对象的默认上下文都渗透到窗口对象。第二个警报我们将上下文设置为字符串testing"这就是警告的内容

所以,正如florent使用call,你也可以使用apply

更新

当你使用代码:

$(settings.widgetSelector, $(settings.columns)).each(function () {
    iNettuts.doWidget(this);
});

this引用.each()方法所在的对象。你想让事情这样发展吗?

谢谢大家的回答。问题解决了,它真的很有趣,很容易找到!我们都知道,this指针每次都是不同的,在这种情况下,只有3个this实例应该被widg替换。@kamaci的答案以及其他一些答案暗示我要解决这个问题。这是最后的代码:

addWidgetControls: function () {
    var iNettuts = this,
        $ = this.jQuery,
        settings = this.settings,
        func = this.doWidget;
    $(settings.widgetSelector, $(settings.columns)).each(function () {
        func(this);
    });
},
doWidget: function (wid) {
    var $ = iNettuts.jQuery,
        settings = iNettuts.settings;
    var thisWidgetSettings = iNettuts.getWidgetSettings(wid.id);
    if (thisWidgetSettings.removable) {
        $('<a href="#" class="remove"></a>').mousedown(function (e) {
            e.stopPropagation();
        }).click(function () {
            $(this).parents(settings.widgetSelector).animate({
                opacity: 0
            }, function () {
                $(this).wrap('<div/>').parent().slideUp(function () {
                    $(this).remove();
                });
            });
            return false;
        }).appendTo($(settings.handleSelector, wid));
    }
    if (thisWidgetSettings.collapsible) {
        $('<a href="#" class="collapse"></a>').mousedown(function (e) {
            e.stopPropagation();
        }).toggle(function () {
            $(this).css({ backgroundPosition: '-38px 0' })
                    .parents(settings.widgetSelector)
                        .find(settings.contentSelector).hide();
            return false;
        }, function () {
            $(this).css({ backgroundPosition: '' })
                    .parents(settings.widgetSelector)
                        .find(settings.contentSelector).show();
            return false;
        }).prependTo($(settings.handleSelector, wid));
    }
},