0

背景:我正在尝试编辑 zen 购物车水平弹出菜单,以使弹出菜单在菜单内内联打开。我遇到的问题是我很难理解它附带的 javascript/jquery。

在不发布整个内容的情况下,代码的结构是这样的:

(declare some vars)

//some functions like this:
function funcname(obj) {
//do something
}

//then one big master function like this:
function bigfunc(arg1, arg2, arg3, arg4, arg5) {

//declare some vars based on this
this.varname1=varname1;
this.varname2=varname2;

//declare some functions inside the big function
this.innerfunc1= function() {
//do stuff
}

this.innerfunc2= function() {
//do stuff
}

}//end of big function

//then goes on to declare init function

function initfunc(){
//this creates new bigfunc(arg1 arg2 arg3...) for each main menu item
}

//finally calls init function with
window.onload = initfunc();

现在开始我的困惑 -

1)首先为了澄清,我是否正确地基于所有 this 在 bigfunc() 中浮动以及它被 new bigfunc() 调用的事实是 this 正在创建一个对象?

2)我目前的问题是 bigfunc() 中的一个函数,如下所示:

this.slideChildMenu = function() {
        var divref = this.children[0].div;
        var ulref = this.children[0].ul;
        var maxwidth = this.children[0].width;
        var nextWidth;
        if (this.isMouseOnMe  || this.isMouseOnChild()) {
            nextWidth = divref.offsetWidth + slideSpeed_out;
            if (nextWidth >= maxwidth) {
                this.finishOpeningChild(divref, ulref, maxwidth);
            } else {
                ulref.style.left = nextWidth - maxwidth + "px";
                divref.style.width = nextWidth + "px";
                setTimeout("slideChildMenu('" + this.getId() + "')", slideTimeout_out);
            }
        }

现在我的计划是改变它以使用 jquery show 打开元素所以我尝试了这个:

this.slideChildMenu = function() {
        var divref = this.children[0].div;
        var ulref = this.children[0].ul;
        if (this.isMouseOnMe  || this.isMouseOnChild()) {
            $(divref).show(function(){
                    this.finishOpeningChild(divref, ulref);
                });
            }
        }

但我得到这个-> TypeError: this.finishOpeningChild is not a function

现在,这个 js 中还有很多其他的东西,所以我不会梦想在这里请人为我做我的工作,但我希望如果有人能向我解释为什么这个函数不是我可能的函数能够解决剩下的问题。

注意:我认为这与“this”的范围有关,但在两个版本的代码中 this 的值似乎完全相同。

我知道这很长,但非常感谢您的帮助。

4

3 回答 3

2

函数中的值this称为函数运行的“上下文”。通常,每当您将回调函数作为参数传递时(就像您对 所做的那样$(divref).show(function() {...})),该函数可以在它想要的任何上下文中运行回调。在这种情况下,jQueryshow函数选择在动画元素的上下文中运行它的回调。

但是,您希望在定义this匿名回调函数时而不是在运行时访问 的值。这里的解决方案是将 的外部值存储在一个变量(传统上称为)中,该变量包含在新定义的函数的范围内:thisself

this.slideChildMenu = function() {
    //...
    var self = this;
    $(divref).show(function(){
        self.finishOpeningChild(divref, ulref);
    });
}
于 2012-08-08T20:46:35.563 回答
1

我在想 jQuery 选择器已经改变了this.

在您的示例$(this);中,指的是根据 jQuery api 文档进行动画处理的对象:

如果提供,则在动画完成后触发回调。这对于将不同的动画按顺序串在一起很有用。回调没有发送任何参数,但它被设置为动画的 DOM 元素。如果为多个元素设置了动画,请务必注意,每个匹配的元素都会执行一次回调,而不是对整个动画执行一次。

如果有问题的对象被实例化,你可以用点表示法调用它而不使用thislikebigFunc.finishOpeningChild(divref, ulref);

于 2012-08-08T20:07:23.477 回答
1

您可能对范围有点困惑,跟踪并不总是那么容易,但做一些更像这样的事情:

var site = {
    init: function(elm) {
        self=site;
        self.master.funcname2(self.varname1, elm); //call function in master
    },
    funcname: function(obj) {
        //do something
    },
    varname1: 'some string',
    varname2: 3+4,
    master: function() {
        this.varname3 = sin(30);
        this.funcname2 = function(stuff, element) {
            site.funcname(element); //call function in 'site'
            var sinus = site.master.varname3; //get variable
        }
    }
}

window.onload = function() {
    var elm = document.getElementById('elementID');
    site.init(elm); //call init function
}

通常会使跟踪变得更容易一些。

于 2012-08-08T20:19:11.790 回答