随着Ext 3.0 core beta的降临,积极响应号召,一步步将ext core应用到 web page上面,当然先用稳定的ext 2.2了。
今天碰到一个奇怪的问题 ,希望与大家分享,免得再遇到。
首先看下面的一段代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>select 测试 </title>
<script src='ext-base.js' type='text/javascript'></script>
<script src='ext-core.js' type='text/javascript'></script>
</head>
<body>
<select id='test_select'>
</select>
<script type='text/javascript'>
Ext.onReady(function() {
Ext.DomHelper.append(Ext.get('test_select'), {tag:'option',value:1,html:'出来了'});
});
</script>
</body>
</html>
我们期望的是 select 的 option 元素能够动态创建 ,事实上 确实 firefox成功达到了我们的期望,而ie系列则不出意料奇怪的失败了。
那么就分析一下 : Ext.DomHelpe.append 吧
append : function(el, o, returnElement){
el = Ext.getDom(el);
var newNode;
//默认 useDom 为 false
if(this.useDom){
newNode = createDom(o, null);
el.appendChild(newNode);
}else{
//我们到这了 ,构造 <option> html 串
var html = createHtml(o);
// 主要是这个
newNode = this.insertHtml("beforeEnd", el, html);
}
return returnElement ? Ext.get(newNode, true) : newNode;
},
那么主要就看 insertHtml ,将 构造的 option 串 插入到 select 中。
insertHtml : function(where, el, html){
where = where.toLowerCase();
if(el.insertAdjacentHTML){
if(tableRe.test(el.tagName)){
var rs;
if(rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html)){
return rs;
}
}
switch(where){
case "beforebegin":
el.insertAdjacentHTML('BeforeBegin', html);
return el.previousSibling;
case "afterbegin":
el.insertAdjacentHTML('AfterBegin', html);
return el.firstChild;
case "beforeend":
el.insertAdjacentHTML('BeforeEnd', html);
return el.lastChild;
case "afterend":
el.insertAdjacentHTML('AfterEnd', html);
return el.nextSibling;
}
throw 'Illegal insertion point -> "' + where + '"';
}
var range = el.ownerDocument.createRange();
var frag;
switch(where){
case "beforebegin":
range.setStartBefore(el);
frag = range.createContextualFragment(html);
el.parentNode.insertBefore(frag, el);
return el.previousSibling;
case "afterbegin":
if(el.firstChild){
range.setStartBefore(el.firstChild);
frag = range.createContextualFragment(html);
el.insertBefore(frag, el.firstChild);
return el.firstChild;
}else{
el.innerHTML = html;
return el.firstChild;
}
case "beforeend":
if(el.lastChild){
range.setStartAfter(el.lastChild);
frag = range.createContextualFragment(html);
el.appendChild(frag);
return el.lastChild;
}else{
el.innerHTML = html;
return el.lastChild;
}
case "afterend":
range.setStartAfter(el);
frag = range.createContextualFragment(html);
el.parentNode.insertBefore(frag, el.nextSibling);
return el.nextSibling;
}
throw 'Illegal insertion point -> "' + where + '"';
}
可见 ,ext 出于 性能的考虑 ,默认不直接采用dom插入,而采用 构造html 串 ,对于 ie 利用 insertAdjacentHTML ,而对 fx 则使用 range .
Ext的作者 考虑到了 对于 table 需要特殊处理 ,对于 table 系列 则采用 insertIntoTable.
而对于 option 作者 不知为什么没有考虑 ,于是 ie 的 insertAdjacentHTML 失效了.
( ps : 后来查到 很早的一个源于1.x 的 bug : http://extjs.com/forum/archive/index.php/t-1902.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>select 测试 </title>
<script src='ext-base.js' type='text/javascript'></script>
<script src='ext-core.js' type='text/javascript'></script>
</head>
<body>
<select id='test_select'>
</select>
<script type='text/javascript'>
Ext.onReady(function() {
//为了使 ie 能够运行 :
Ext.DomHelper.useDom=true;
Ext.DomHelper.append(Ext.get('test_select'), {tag:'option',value:1,html:'出来了'});
});
</script>
</body>
</html>
本文探讨了在ExtJS中动态添加option元素到select框时IE浏览器出现的问题,并提供了解决方案。通过设置Ext.DomHelper.useDom为true,确保了在IE下也能正确插入选项。
759

被折叠的 条评论
为什么被折叠?



