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) まず明確にするために、bigfunc() に浮かんでいるすべての this と、これがオブジェクトを作成している new bigfunc() で呼び出されるという事実に基づいて、私は正しいと思いますか?

2)私の現在の問題は、bigfunc() 内の次のような関数の 1 つにあります。

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匿名コールバック関数が実行されたときではなく、定義されたときに の値にアクセスする必要があります。ここでの解決策は、新しく定義された関数のスコープに含まthisれる変数 (伝統的に と呼ばれる) にの外部値を格納することです。self

this.slideChildMenu = function() {
    //...
    var self = this;
    $(divref).show(function(){
        self.finishOpeningChild(divref, ulref);
    });
}
于 2012-08-08T20:46:35.563 に答える
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 に答える
1

jQuery セレクターが のスコープを変更したと考えていますthis

あなたの例$(this);では、jQuery APIドキュメントごとにアニメーション化されているオブジェクトを参照します:

指定した場合、アニメーションが完了するとコールバックが発生します。これは、異なるアニメーションを順番に並べるのに役立ちます。コールバックには引数は送信されませんが、アニメーション化される DOM 要素に設定されます。複数の要素がアニメーション化されている場合、コールバックは、アニメーション全体に対して 1 回ではなく、一致した要素ごとに 1 回実行されることに注意してください。

問題のオブジェクトがインスタンス化されている場合は、thislikeを使用せずにドット表記で呼び出すことができますbigFunc.finishOpeningChild(divref, ulref);

于 2012-08-08T20:07:23.477 に答える