1

私はこの質問を間違った方法で行ったことを確信しています。onClick="someFunc(arg1,arg2...)"javascriptパーサーなどに文字列を渡そうとしています。

パーサーは、args(arg1、arg2など)を使用してsomeFuncのonClickイベントを作成する必要があります。

私の問題は、テキストがパーサーを通過するときに、someFuncの文字列名を保持する変数のスコープが渡され、添付されたイベントがすべて最後に宣言された文字列として登録されることです。

以下のコードでは、attributes._onClickは文字列'onClick = "someFunc(arg1、arg2);"である可能性があります。1つの要素の後に'onClick= "otherFunc(argA、argB);"が続きます パーサーが文字列内を移動するときに、別の要素に対して。

ブラウザ(Firefox V14.01)の出力には、常にotherFuncとして登録されるイベント関数があります。したがって、クロージャ内のf_nameは変数として評価されませんが、代わりに、ブロック全体の解析全体で宣言されたf_nameの最後の値として登録されます。

私はこれを理解するために必要な程度の範囲に精通していません。この方法でイベントを添付する方法を知っている人はいますか(パーサーの外に出てイベントを追加することを避けようとしています)?

           temp = attributes._onClick ;
            var x = 0 ;
            var f_name,f_args ;
            while(temp[x] != '') {
                temp[x] = temp[x].replace(')','').split('(') ;//remove paranthesis and separate func name from args
                f_name = temp[x][0] ;
                f_args = temp[x][1].split(',') ;//turn string of args into array
                el.onclick = function() { window[f_name].apply(el,f_args) ; }
                x++ ;
            }
4

1 に答える 1

0

あなたは JavaScript の落とし穴につまずいています。これは、ある時点でほぼすべての人にさまざまな方法で同じ問題を引き起こします。

変数「f_name」は、作成中のすべての関数で共有されます。つまり、ループの反復ごとに新しい関数が作成されますが、「f_name」は 1 つしかありません。したがって、すべての関数は、最後の反復で持っていた値である同じ値を参照します。

関連するソリューションがいくつかあります。1 つの方法は、イベント ハンドラーを確立するステートメントを、すぐに呼び出す別の無名関数でラップすることです。これにより、「f_name」のコピーを作成して、 1 つのハンドラーが排他的に使用できるようになります。

               el.onclick = function(name) {
                return function() { window[name].apply(el,f_args) ; };
               }(f_name);

興味深いことに、SO のこの質問にはおそらく何百ものバリエーションがあります。

于 2012-07-31T18:00:39.890 に答える