我有一个仅在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
是组件<h:commandLink/>
生成的Javascript函数)
问题是document.forms["foobar"]
在最初呈现页面时运行良好,但是一旦在Ajax调用之后重新呈现表单,此代码在Firefox上不再起作用(但适用于IE6)。
当我在Ajax调用之后单击表单中的一个链接时,这会导致Javascript错误。
请注意,如果我在Ajax调用后调用document.getElementById("foobar");
,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 -ed元素(特别是我的foobar
表单),这会导致删除来自document.forms
数组。
然后,它再次添加foobar
表单及其新内容。但Firefox确实不更新document.forms
数组,而IE6则更新document.forms["foobar"]
数组。
这就是为什么undefined
在Ajax调用之后返回reRender
。
我解决此问题的方法是更改reRender
属性,以便仅重新呈现表单的子部分,而不是表单本身。这样,我的链接就可以了。
但是,我想知道是否有其他方法可以解决此问题,而无需修改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);
};
属性。
有什么想法吗?
修改的
单击命令链接时的Javascript代码如下:
<h:commandLink>
在jsfcljs(document.forms['foobar'], 'someId', '')
onclick属性中,我们调用在jsfcljs(undefined, 'someId', '')
中评估的f
。然后,当调用f is undefined
时,我收到一条Javacript错误,指出{{1}}。
答案 0 :(得分:2)
问题实际上是我所看到的HTML问题。
您的表单应使用名称定义,而不仅仅是id属性:
不同的浏览器对名称和ID等效区别对待。如果这不能解决您的问题评论,我将生成一个测试用例,不需要服务器端来演示您所看到的任何效果。
解决问题代码的另一种方法是在客户端重写内联onclick事件调用,以便通过id而使用document.getElementById(“foobar”)调用来引用表单而不是document.forms [“foobar” ]
答案 1 :(得分:0)
我记得这是Sun Mojarra 1.2(已经存在4年)的一个漏洞。升级lib应该可以解决这个问题。目前最新的Sun Mojarra 1.2是1.2_14,仅在三周前发布。只需用/WEB-INF/lib
替换它们中的两个JSF库。