-1

つまり、オブジェクトリテラルを使用して、未知の量の変数を任意の順序で関数に渡すことができるようにしたいのです。これは理論的には大したことではありませんが、私のコードでは、このオブジェクトリテラルは。と呼ばれる2番目の関数に渡されon_changeます。

on_change要素のinnerHTMLを文字列と比較することで機能します。同じ場合は、関数を再度呼び出すためのタイムアウトを設定します。要素のinnerHTMLが文字列と異なる場合、3番目のパラメーターが実行されます。これは、関数または文字列のいずれかになります。どちらの方法でも実行されます。私はこの機能を十分にテストし、しばらくの間使用しました。

ただし、オブジェクトリテラルを関数呼び出しに流すことができないようです...

var params = { xpos:'false'};
on_change('window_3_cont_buffer','','
if(Window_manager.windows[3].window_cont_buffer.getElementsByTagName(\'content\')[0].getElementsByTagName(\'p\')[0].innerHTML == \'ERROR\'){
alert(Window_manager.windows[3].window_cont_buffer.getElementsByTagName(\'content\')[0].getElementsByTagName(\'p\')[1].innerHTML);
return false;
} else { 
Window_manager.windows[3].load_xml(\'location/view.php?location_ID=3\', \'\', ' + params + ' ); }
');

私はこれをフォーム送信の一部と呼んでいます。この行の後で、関数を呼び出してajaxを介してコンテンツをロードします。これは正常に機能し、on_change関数からコードをトリガーします。

load_xml私は関数をテストしました、それは呼び出しalert(param.xpos)て正しい応答を得ることができます。未定義のチェックを追加して、電話をかける残りの時間にload_xmlアラートが殺到しないようにすることもできます。

このload_xml関数は最初に関数を設定しon_change、次に関数を呼び出してコンテンツを非表示のdivにロードします。AJAXリクエストがそのDIVを更新すると、on_change関数は関数を呼び出す必要がありparse_xmlます。これにより、xmlファイルから情報が取得されます。ただし...このオブジェクトリテラルパラメータの考え方は、このparse_xml関数に特定のものを無視するように指示できるということです。

on_change("window_" + this.id + "_cont_buffer", "", "Window_manager.windows[" + this.id + "].parse_xml('" + param + "')");

これはの一部でありload_xml、そこにparamビットがあっても完全に正常に機能します。ただし、parse_xmlそのパラメータを使用できないようです。

私はそれを、オブジェクトリテラルが通過したことを意味すると思うことがparse_xmlできalert(param)、与えることができるようになりましたが、呼び出しようとすると未定義になります。[object object]alert(param.xpos)

私はこれが問題の豚であることを知っています、そして私は関数に無数のブールパラメータをとらせるだけでそれを回避することができました、しかしそれはあまり良い解決策ではありません。

4

4 に答える 4

2

事実上、あなたが持っているのはこれです:

var params = {param: "value"};
foo("bar('one', 'two', 'three');");

...その文字列でfoo使用evalする場所は、次のようになります。

function foo(codestring) {
    eval(codestring);
}

...そしてあなたはそれに埋め込む方法を探していますparams

これを行うに、オブジェクトリテラルを文字列としてシリアル化して、他の文字列と組み合わせたときに文字列全体が評価されるようにします。ブラウザは徐々にJSONシリアル化を組み込んでいますが、今のところ、jQuery、Prototype、または(この部分が必要な場合は)Crockfordのjson2.jsを使用します。これはJSON.stringify、JSON文字列に変換できるオブジェクトをJSONに変換するためのものです。文字列。それで:

var params = {param: "value"};
foo("bar(" + JSON.stringify(params) + ");");

しかし、本当にやりたいのは、そのロジックのすべてが文字列内のコードではなくコードとして表現されるようにリファクタリングすることです。次に、リテラルを直接渡すことができます。さらに、モジュール化、デバッグなど、他の多くの利点もあります。

var params = {param: "value"};
function callBar() {
   bar(params);
}
foo(callBar);

...文字列fooではなく関数を呼び出すように変更します。evaleval可能な限り避けるべきであり、ダライ・ラマを言い換えると、それは[ほぼ]常に可能です。)私のサンプルは次fooのように変更されます。

function foo(func) {
    func();
}

fooの追加情報を含める必要がある場合bar(およびcallBarそれらの追加の引数を処理するように設定されている場合)、Function#callまたはを使用してそれFunction#applyを行うことができます。(これらのリンクはMDCへのリンクですが、心配しないでください。Firefox固有ではなく、ECMA仕様に何年も含まれており、ほぼ普遍的にサポートされています。)

于 2010-03-24T12:45:56.777 に答える
1

文字列内にオブジェクトを入れることはできません。オブジェクトをシリアル化し、文字列に追加してから、反対側の構造化オブジェクトに解析して戻す必要があります。JSONは単純なJavaScriptとして評価されるため、これを行う最も簡単な方法は、JSONを使用することです(JSON.stringifyまたは、JSONを持たない古いブラウザーの場合はライブラリフォールバックを使用します)。

まったく同じオブジェクトを取得することはできませんが、同じ属性とプロパティを持つ新しいオブジェクトを取得することに注意してください。これは単純な型でのみ機能するため、オブジェクトなどに関数を含めることはできません。

ただし、いずれの場合も、JavaScriptコードを文字列で渡すことは、徹底的に回避する必要のあるアンチパターンです。代わりにインライン関数を使用すると、文字列に何ができるか、何ができないかを心配する必要がなくなり、読み取り不可能なラッピングと\エスケープをすべて取り除くことができます。

var params = {xpos: 'false'};
on_change('window_3_cont_buffer', '', function() {
    var w= Window_manager.windows[3];
    var ps= w.window_cont_buffer.getElementsByTagName('content')[0].getElementsByTagName('p');
    if (ps[0].innerHTML==='ERROR') {
        alert(ps[1].innerHTML);
        return false;
    } else { 
        w.load_xml('location/view.php?location_ID=3', '', params);
    }
});
于 2010-03-24T12:49:34.770 に答える
0

あなたに役立つかもしれないいくつかの一般的なテクニック:

// Example of calling function objects given as arguments:

function on_change(foo, callback1, callback2) {
    if (foo)
        callback1();
    else
        callback2.call(available_as_this);
}

on_change(foo, function() { your code }, function() { another code });


// Example of function taking arbitrary number of arguments:

function any_params() {
    console.log('I got ' + arguments.length + 'arguments!');
    console.log('First argument: ' + arguments[0]);
}

any_params('one', 'two', 'three', [], null, {});

引数variableおよびcall()を参照してください。

于 2010-03-24T12:51:42.507 に答える
0

オブジェクトリテラルを使用して、ランダムな量の変数を任意の順序で関数に渡すことができるようにしたいと思います。

パラメータと関数を含むオブジェクトを作成して、それを渡してみませんか?受信関数は、オブジェクトを使用する前に、オブジェクトのプロパティが設定されているかどうかをテストするだけです。

于 2010-03-24T12:54:04.620 に答える