我有一个仅在 IE6 浏览器上使用的 JSF 1.2 应用程序(Sun RI、Facelets、Richfaces)。现在,我们还必须支持 Firefox(是的!)。
在我的一个页面中,我有一个包含将重新呈现整个表单的按钮的表单。重新渲染后,<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 调用后单击表单中的一个链接时,这会导致 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将从 DOM 树对象中删除reRender元素(特别是我的表单),从而将其从数组中删除。然后,它再次添加带有新内容的表单。但是 Firefox 不会更新数组,而 IE6 会。这就是在 Ajax 调用之后返回的原因。foobar
document.forms
foobar
document.forms
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
.