从今天开始记录JavaScript使用的兼容问题
一、推荐获取元素的HTML代码使用innerHTML,是W3C属性兼容所有浏览器,不要使用innerText和outerHTML,因为这不是标准的属性FF内不被支持的。解决代替outerHTML方法如下:
1.使用document.createElement("DIV").appendChild(parentLink.cloneNode(true)).parentNode.innerHTML;创建一个元素新元素添加到子节点后获取innerHTML即元素的outerHTML值。
2.网上还有另外一种方案是给dom元素prototype自定义添加一个outerHTML属性,代码如下:
{
HTMLElement.prototype.__defineGetter__("outerHTML",function()
{
var a=this.attributes, str="<"+this.tagName, i=0;for(;i<a.length;i++)
if(a[i].specified)
str+=" "+a[i].name+'="'+a[i].value+'"';
if(!this.canHaveChildren)
return str+" />";
return str+">"+this.innerHTML+"</"+this.tagName+">";
});
HTMLElement.prototype.__defineSetter__("outerHTML",function(s)
{
var r = this.ownerDocument.createRange();
r.setStartBefore(this);
var df = r.createContextualFragment(s);
this.parentNode.replaceChild(df, this);
return s;
});
HTMLElement.prototype.__defineGetter__("canHaveChildren",function()
{
return !/^(area|base|basefont|col|frame|hr|img|br|input|isindex|link|meta|param)$/.test(this.tagName.toLowerCase());
});
}
二、今天在使用<a>链接元素在onclick事件里动态创建form提交的时候遇到了一个小问题,表单能正确提交的服务器端去,但是提交表单后页面竟然没有刷新,这个问题只在ie6里才发生,ie7、FF浏览器内均没有问题,后来baidu一下原来时候<a>元素的href的问题,我之前写的都是<a href="javascript:;" onclick="form.sumbit()"></a>来写的,但href为javascrip:;或是javascript:void(0)类型的时候sumbit后为什么就不会刷新页面,按道理href为javascript无返回值类型没有问题啊,而且onclick事件将在link到href之前触发,如果onclick为return false那么href的link将恒不会打开的,除开a的target为_blank的时候会打开一个新的当前地址的窗体。将href改为一个常见的链接地址在再onclick事件里面返回false既可,但是一定要记得在onclick里面写上return fn()加上return啊;或者把href直接改成#完事了,这样onclick没return false也无关系了,不过href到#页面将跳转到最top位置,有个时候就会有问题;那为什么调用的JavaScript函数一定要写在onclick事件里面而不是href="javascript:fn()"这样呢?因为我在fn函数里面可能需要传递event事件参数或当前对象this,但是href不是事件没有event事件参数且this对象不是指向当前点击触发的原元素,所以我在fn里面要获取触发时间的原元素就比较困难了。
三、IE跟其他标准的浏览器在DOM认识处理上有个非常重大的区别,IE在获取childNodes的时候会很'人性化'把TEXT_NODE空文本节点给忽略掉,而FF等浏览器不会,但有时候我们只需要获取nodeType=1的元素节点,如果为TEXT_NODE文本节点误当元素节点设置它一些属性时会出错,一般做到兼容的办法是获取childNodes时逐一判断nodeType!=3(jquery的做法),但是就麻烦了一点,我一般用childNodes的时候我会用document.getElementById('id').getElementsByTagName('li'),但这是在预知所有的childNodes的nodeName前提下的,如果可以控制程序动态输出所有的childNodes的时候,可预先清除所有的空格换行,这样用childNodes获取的节点就没有TEXT_NODE空文本节点了,使用firstChild、lastChild、previousSibling、parentNode属性的时候也要注意TEXT_NODE空文本节点的情况。
四、博客前台页面在实现切换风格的时候遇到了一个比较棘手的问题:当用js设置页头部的link样式文件href路径,不会加载新样式文件的import url(public.css)样式,public.css是我公共定义样式,为保持每个页面只有一个link样式,我选择在外接样式文件里再import公共样式,在刷新页面时候会一起加载,但是在用js改变link的路径时ie7不会加载里面的import样式,发现低版本的ie6里面没有这个问题,好象ie8也存在这个问题,其他ff等标准浏览器没有这个问题,真是囧了。困绕了我好几天,今天google了一下终于在博客园里面找到了答案,先设置一下link.href="",再设置link.href="new.css",真是无语了,有点像需要在ie里使用setTimeout(function (){},0)这种感觉了,还好总算能解决ie里面的这个小bug,仅多写了一句就实现了所有浏览器的兼容何乐而不为呢?
五、JavaScript监视键盘的keydown事件,判断是否同时按下Ctrl+S或回车键,兼容IE和所有标准浏览器,按下Ctrl+S阻止浏览器弹出“网页另存为”的对话框,阻止其事件的默认行为。
function editorKeyDown(e)
{
var isPrevent = false;
var num = e.which ? e.which : e.keyCode; //获取键盘按下num
if( e.ctrlKey && (num == 83 || num == 13) )
{
isPrevent = true;
switch(num)
{
case 83:
//按下了Ctrl+回车键的事件处理
break;
case 13:
//按下了Ctrl+S键的事件处理
break;
}
}
if(isPrevent)
{
//阻止事件默认行为
if ( document.all )
return false;
e.preventDefault();
}
}