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

时间:2011-11-12 22:45:01

标签: javascript jquery

我将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。但它不起作用。

我已调查此问题并将原始函数的each循环内的已执行代码复制(addWidgetControls)并将所有$(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));
        }
    });        
},

这意味着当$(this)$(widg)

相同时,thiswidg不同{/ 1}}

PS:我从this tutorial

获得了此代码

5 个答案:

答案 0 :(得分:1)

如果我理解你,我认为你应该保持widg变量,并保持$(this)而不是$(widg)。您将在循环中调用该函数,因为eachthis每次都会更改。但是,如果每次使用widg时这个变量将指向该函数内的相同this,则会调用您的函数,这应该是您不想要的。

答案 1 :(得分:1)

我认为这是因为:

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

你忘了用$()包装 widg

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

答案 2 :(得分:1)

也许您想使用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));
    }
}

答案 3 :(得分:1)

如果要设置函数的上下文(this分配),可以使用applycall。这是一个例子:

var obj = "testing";

var func = function() {
  alert(this);
}

func();
func.apply(obj);

现在,在浏览器中运行代码(我使用了firebug)。

第一个警报将是窗口对象,因为所有对象的默认上下文都会向下移动到窗口对象。第二个警告我们将上下文设置为字符串“testing”,这就是警报所说的内容。

因此,当fflorent使用call时,您也可以使用apply

更新

当您使用代码时:

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

this指的是.each()方法所在的对象。你想让它以这种方式工作吗?

答案 4 :(得分:0)

感谢所有答案。问题解决了,它真的很有趣,很容易找到!众所周知,this指针不时会有所不同,在这种情况下,只有this的3个实例应该被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));
    }
},