IE下ComboBox和DateField消失的解决方法

作者:技术拾光时间:2026-06-10 08:21:06浏览:618

在IE浏览器缩放窗口时,ExtJS的ComboBox和DateField组件消失,因x-form-item-body类的position:relative导致渲染异常。通过条件注释仅针对IE浏览器覆盖为position:static即可解决。该问题仅在IE中出现,利用条件注释实现浏览器特定修复,此方法简洁有效且不影响其他浏览器兼容性。

前言

ComboBox和DateField是Ext JS表单中的基础组件,本身并不复杂,但在实际开发中却遇到了一个让人头疼的问题:在IE浏览器里,只要缩放窗口,这两个组件就会直接消失。点击页面其他位置,它们偶尔又会重新显示,且不报任何错误。其他浏览器(Chrome、Firefox)均运行正常。这究竟是什么原因造成的?

问题发生的状况

事情是这样的:项目原本采用纯HTML表单,后来引入了Ext JS,但并未按照标准方式(先创建Form组件,再通过add field添加字段)进行重构。而是直接在原有的HTML input上,利用Ext JS的render方法将input转换为ComboBox和DateField。正是这种“半路出家”的做法,埋下了隐患。

ComboBox的生成机制

先来看ComboBox是如何被创建的:

  1. 根据id找到原始input;
  2. 找到该input的父节点(随后原始input可以被删除);
  3. 创建新的Ext JS ComboBox组件,渲染到父节点中,id复用原始input的id。

DateField的机制与此类似。代码大致如下:

复制代码 代码如下:
var comboInput = Ext.get(inputId);
var comboInputParent = comboInput.parent();
comboInput.destroy();
var store = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [
{"abbr":"AL", "name":"Alabama"},
{"abbr":"AK", "name":"Alaska"},
{"abbr":"AZ", "name":"Arizona"}
//...
]
});

Ext.create('Ext.form.ComboBox', {
id: inputId,
store: store,
displayField: 'name',
valueField: 'abbr',
typeAhead : true,
renderTo : comboInputParent
});

方案探求

首先使用IE Developer工具观察窗口变化后的组件状态,发现组件实际上仍然存在——DOM树中能找得到。Ext JS的ComboBox内部结构大致如下:一个div中嵌套一个table,table中嵌套一行tr,tr中包含两个td,第二个td负责显示组件。具体结构如下:

复制代码 代码如下:

起初怀疑是销毁原始input导致无法正常渲染,于是尝试使用hide()、setDisabled、setVisible等方法,但均未奏效。进一步观察发现,那个td虽然仍挂在页面上,但位置已经偏离——不再位于table下方。这多半是CSS的问题。

抱着尝试的心态,在IE Developer中直接删除该td上的class x-form-item-body,组件立刻恢复正常!可见问题就出在这个class上。查看Ext JS中x-form-item-body的CSS定义:

复制代码 代码如下:
.x-form-item-body {
position: relative;
}

定义非常简单——仅一行position: relative;。没错,正是这个相对定位导致了渲染异常。

为了不直接修改Ext JS本身的CSS(防止后续升级时被覆盖),在页面中增加覆盖样式:

复制代码 代码如下:

static是position的默认值,相当于不设置定位。尝试后,问题完美解决。不过Chrome和Firefox并未出现此问题,为了尽可能减小改动的影响,使用条件注释仅对IE生效:

复制代码 代码如下:

只有在IE浏览器下,这段代码才会生效。至此,问题彻底解决。