0

可能重复:
jquery 将 $(this) 传递给其他函数

我正在编写一个 Javascript/jQuery 函数(尚未重构),但使用$(this). 解释起来有点困难,所以我将添加代码,希望它会变得更加清晰:

var accordion = 'div.accordionContent';
var accordButton = 'div.accordionButton';
var accordClosedArrow = 'url(/public/img/accordion-closed-arrow-';
var accordOpenArrow = 'url(/public/img/accordion-open-arrow-';
$(accordion).hide();
var accordFunc = function(arrowColor){
    var img;
    if ($(this).next(accordion).is(':visible')) {
        img = accordClosedArrow + arrowColor + '.png)';
    } 
    else {
        img = accordOpenArrow + arrowColor + '.png)';
    }

    // these lines throw errors because of $(this)
    $(this).css({backgroundImage:img}).next().slideToggle('slow').siblings(accordion)
        .slideUp();
    $(this).siblings()
        .css({backgroundImage:accordClosedArrow + arrowColor + '.png)' + 'no-repeat'});
    };

    $(accordButton).live('click',function(){
        accordFunc('blue');
    });

    $(accordButton + 'B').live('click',function(){
        accordFunc('orange');
    });

不知道为什么传递$(this)会导致 Chrome 控制台抛出错误:

未捕获的类型错误:无法读取未定义的属性“firstChild”

4

3 回答 3

5

替换accordFunc('blue');accordFunc.call(this, 'blue');对该函数的其他调用并执行同样的操作。

当您调用另一个函数时,该this值不会保留,因此accordFunc它内部指向窗口对象或 null(如果严格模式处于活动状态)。另一种选择是this作为普通参数传递并更改函数定义,例如function accordFunc(elem, arrowColor)使用和使用elem,而不是this在该函数内部。

于 2012-11-09T16:08:55.803 回答
1

当你在 JS 的方法中调用函数时,作用域this变回窗口。这是一种奇怪的行为,但不幸的是它就是这样工作的!尝试将所需的上下文作为参数传递给方法,如下所示:

        var accordFunc = function(ctx, arrowColor){
          var img;
          if ($(ctx).next(accordion).is(':visible')) {
                  img = accordClosedArrow + arrowColor + '.png)';
          } 
          else {
              img = accordOpenArrow + arrowColor + '.png)';
          }

          // these lines throw errors because of $(this)    
          $(ctx).css({backgroundImage:img}).next().slideToggle('slow').siblings(accordion).slideUp();
          $(ctx).siblings().css({backgroundImage:accordClosedArrow + arrowColor + '.png)'     + 'no-repeat'});
        };

        $(accordButton).live('click',function(){
            accordFunc(this, 'blue');
        });
于 2012-11-09T16:12:25.190 回答
0

一个选项是让accordFunc 返回将被绑定的函数,并对颜色使用闭包:

var accordFunc = function(arrowColor){
    return function(){
        var img;
        if ($(this).next(accordion).is(':visible')) {
            img = accordClosedArrow + arrowColor + '.png)';
        } 
        else {
            img = accordOpenArrow + arrowColor + '.png)';
        }

        // these lines throw errors because of $(this)
        $(this).css({backgroundImage:img}).next().slideToggle('slow').siblings(accordion)
        .slideUp();
        $(this).siblings()
            .css({backgroundImage:accordClosedArrow + arrowColor + '.png)' + 'no-repeat'});
    }
};

然后调用:

$(accordButton + 'B').live('click', accordFunc('orange'));
于 2012-11-09T16:16:20.117 回答