3

IE6ブラウザーでのみ使用されていたJSF1.2アプリケーション(Sun RI、Facelets、Richfaces)があります。今、Firefoxもサポートする必要があります(ええ!)。

私のページの1つに、フォーム全体を再レンダリングするボタンを含むフォームがあります。再レンダリング後、いくつかのリンク(<h:commandLink/>)がこのフォームに追加されます。

JSFコードは次のようになります。

<h:form id="foobar">
    ...
    <a4j:commandButton ... reRender="foobar"/>
    ...
    <h:commandLink .../>
</h:form>

私の問題は、コマンドリンクコンポーネントによって生成されたHTMLコードに関連しています。これは次のとおりです。

<a href="#" onclick="if(typeof jsfcljs == 'function'){jsfcljs(document.forms['foobar'],'...','');}return false">bla bla</a>

(詳細についてjsfcljsは、コンポーネントによって生成されたJavascript関数です<h:commandLink/>

問題はdocument.forms["foobar"]、ページが最初にレンダリングされたときにうまく機能していることですが、Ajax呼び出しの後にフォームが再レンダリングされると、このコードはFirefoxでは機能しなくなります(ただし、IE6では機能します)。

これにより、Ajax呼び出しの後にフォーム内の1つのリンクをクリックすると、Javascriptエラーが発生します。

document.getElementById("foobar");Ajax呼び出しの後に呼び出すと、Firefoxが私のフ​​ォームを見つけることに注意してください...

次のJavascript関数を検討する場合:

function test() {
    var e = document.forms;
    var tmp = "";
    for (i = 0; i < e.length; i++) {
        tmp = tmp + e[i].id + " ; ";
    }
    alert(tmp);
}

Ajax呼び出しの前後に実行すると、次の結果が得られます。

someForm ; anotherForm ; foobar ; // Before Ajax call on FF 
someForm ; anotherForm ; // After Ajax call on FF. PROBLEM HERE!

someForm ; anotherForm ; foobar ; // Before Ajax call on IE6 
someForm ; anotherForm ; foobar ; // After Ajax call on IE6

問題の理由についての私の考えは次のとおりです。

クライアント側でAjax応答を受信すると、a4jはreRender-ed要素(特に私のfoobarフォーム)をDOMツリーオブジェクトから削除します。その結果、document.forms配列から削除されます。次に、foobar新しいコンテンツを含むフォームを再度追加します。ただし、Firefoxはアレイを更新しませdocument.formsが、IE6は更新します。そのため、Ajax呼び出しの後にdocument.forms["foobar"]戻ります。undefined

この問題を解決するための私の解決策reRenderは、フォーム自体ではなく、フォームのサブパーツのみを再レンダリングするために属性を変更することです。このように、私のリンクは機能します。

reRenderただし、属性を変更せずにこの問題を解決する別の方法があるかどうかを知りたいと思いました。何か案が?


編集

コマンドリンクをクリックしたときのJavascriptコードは次のとおりです。

function dpf(f) {
    var adp = f.adp;
    if (adp != null) {
        for (var i = 0; i < adp.length; i++) {
            f.removeChild(adp[i]);
        }
    }
};

function apf(f, pvp) {
    var adp = new Array();
    f.adp = adp;
    var ps = pvp.split(',');
    for (var i = 0, ii = 0; i < ps.length; i++, ii++) {
        var p = document.createElement("input");
        p.type = "hidden";
        p.name = ps[i];
        p.value = ps[i + 1];
        f.appendChild(p);
        adp[ii] = p;
        i += 1;
    }
};

function jsfcljs(f, pvp, t) {
    apf(f, pvp);
    var ft = f.target;
    if (t) {
        f.target = t;
    }
    f.submit();
    f.target = ft;
    dpf(f);
};

<h:commandLink>onclick属性では、で評価されるを呼び出しjsfcljs(document.forms['foobar'], 'someId', '')ますjsfcljs(undefined, 'someId', '')。次に、fが呼び出されると、それを示すJavacriptエラーが発生しますf is undefined

4

2 に答える 2

2

問題は、実際には私が見たものからのHTMLです。

フォームは、単なるid属性ではなく、名前で定義する必要があります。

ブラウザが異なれば、名前とIDの同等性の扱いも異なります。これで問題のコメントが解決しない場合は、サーバー側で表示されている効果を実証する必要のないテストケースを作成します。

問題コードを回避する別の方法は、クライアント側でインラインonclickイベント呼び出しを書き直して、document.forms ["foobar"]の代わりにdocument.getElementById( "foobar")呼び出しを使用してidでフォームを参照することです。

于 2010-01-08T03:19:40.340 に答える
0

これは、Sun Mojarra 1.2(すでに4年前から存在している)のバグの1つとして思い出します。ライブラリをアップグレードすると、この問題が解決するはずです。現在最新のSunMojarra1.2は、わずか3週間前にリリースされた1.2_14です。2つのJSFライブラリ/WEB-INF/libをそれらに置き換えるだけです。

于 2010-01-08T11:53:15.440 に答える