我正在编写Javascript / jQuery函数(未经过REFACTORED YET),但是使用$(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控制台抛出错误:
未捕获的TypeError:无法读取未定义的属性“firstChild”
答案 0 :(得分:5)
将accordFunc('blue');
替换为accordFunc.call(this, 'blue');
,并对该函数的其他调用执行此操作。
当您调用另一个函数时,this
值不会被保留,因此在accordFunc
内它指向窗口对象或null(如果严格模式处于活动状态)。另一个选择是将this
作为普通参数传递并更改函数定义,例如到function accordFunc(elem, arrowColor)
并在该函数中使用elem
代替this
。
答案 1 :(得分: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');
});
答案 2 :(得分: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'));