最近做了一些javascript相关的工作,把收获和大家分享一下,感谢下meizz,他的框架jsframework给我提供了许多现成的工具
title这个元素比较特殊
如果title中有经过htmlencode的字符,通过document.title获得的内容将会自动解码,并且在ie中通过给title加上一个id然后用document.getElementById(titleid).innerHTML来获得其中内容也仍然是已经解码的,而firefox则不会
< head >
< title id ="tt" > < iframe src= " www.baidu.com " / > </ title >
</ head >
< body >
< div id ="dd" > < iframe src= " www.baidu.com " / > </ div >
document.title: < input id ="disp1" />< br />
document.getElementById(titleid): < input id ="disp2" />< br />
document.getElementbyId(divid): < input id ="disp3" />
< script type ="text/javascript" >
document.getElementById( " disp1 " ).value = document.title;
document.getElementById( " disp2 " ).value = document.getElementById( " tt " ).innerHTML;
document.getElementById( " disp3 " ).value = document.getElementById( " dd " ).innerHTML;
</ script >
</ body >
</ html >
ie中的结果
firefox的结果
xhtml不支持document.body.scrollTop
当为html文档加上如下头以支持xhtml过渡标准时候,使用document.body.scrollTop值始终为0
< html xmlns ="http://www.w3.org/1999/xhtml" xml:lang ="zh-CN" lang ="zh-CN" >
这是document.body.scrollTop始终为0,这时需要用document.documentElement.scrollTop才能获得正确的值
而如果不加xhtml的申明,document.documentElement.scrollTop将为0
下面这个getScrollXY()方法可以包装这个变化
< body >
< div id ="dd" > < br />< br />< br />< br />< br />< br />< br />< br />< br />< br />< br />
< br />< br />< br />< br />< br />< br />< br />< br />< br />< br />
</ div >
scrollLeft: < input id ="disp1" />< br />
scrollTop: < input id ="disp2" />< br />
< button onclick ="onClick()" > 获得scrollXY </ button >
< script type ="text/javascript" >
function getScrollXY(){
var x,y;
if (document.body.scrollTop){
x = document.body.scrollLeft;
y = document.body.scrollTop;
}
else {
x = document.documentElement.scrollLeft;
y = document.documentElement.scrollTop;
}
return {x:x,y:y};
}
function onClick(){
document.getElementById( " disp1 " ).value = getScrollXY().x;
document.getElementById( " disp2 " ).value = getScrollXY().y;
}
</ script >
</ body >
</ html >
firefox的outerHTML
firefox没有outerHTML这个很有用的属性,用下面这个方法可以让你的firefox也具有这个属性
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.__defineGetter__( " canHaveChildren " , function ()
{
switch ( this .tagName.toLowerCase())
{
case " area " : case " base " : case " basefont " :
case " col " : case " frame " : case " hr " :
case " img " : case " br " : case " input " :
case " link " : case " meta " : case " isindex " :
case " param " : return false ;
} return true ;
});
}
firefox和ie的事件
firefox和ie的事件对象稍微不同,比方说下面这个在ie下获得鼠标位置的方法
< script type ="text/javascript" >
function onclick(){
alert(event.clientX);
}
</ script >
需要改成
<button οnclick="onClick(event)">获得OuterHTML</button>
<script type="text/javascript">
function onclick(event){
alert(event.clientX);
}
</script>
才能在两种浏览器下使用
children与childNodes
ie提供的children,childNodes和firefox下的childNodes的行为是有区别的,firefox下childNodes会把换行和空白字符都算作父节点的子节点,而ie的childNodes和children不会
比如
<div id="dd">
<div>yizhu2000</div>
</div>
id为dd的div在ie下用childNodes查看,其子节点数为1,而ff下为三,我们可以从ff的dom查看器里面看到他的childNodes为["/n ", div, "/n"]
要在ff下模拟children的属性我们可以这样做
HTMLElement.prototype.__defineGetter__( " children " , function ()
{
for ( var a = [],j = 0 ,n,i = 0 ; i < this .childNodes.length; i ++ ){
n = this .childNodes[i]; if (n.nodeType == 1 ){a[j ++ ] = n; if (n.name){
if ( ! a[n.name])a[n.name] = []; a[n.name][a[n.name].length] = n;}
if (n.id) a[n.id] = n;}} return a;
});
}
几个有用的工具函数
在ff下模拟ie的insertAdjacentHTML
HTMLElement.prototype.insertAdjacentHTML = function (where, html)
{
var e = this .ownerDocument.createRange();
e.setStartBefore( this );
e = e.createContextualFragment(html);
switch (where)
{
case ' beforeBegin ' : this .parentNode.insertBefore(e, this ); break ;
case ' afterBegin ' : this .insertBefore(e, this .firstChild); break ;
case ' beforeEnd ' : this .appendChild(e); break ;
case ' afterEnd ' :
if ( ! this .nextSibling) this .parentNode.appendChild(e);
else this .parentNode.insertBefore(e, this .nextSibling); break ;
}
};
}
模拟DotNet的string.format
{
if (arguments.length == 0 ) return this ;
for ( var s = this , i = 0 ; i < arguments.length; i ++ )
s = s.replace( new RegExp( " //{ " + i + " //} " , " g " ), arguments[i]);
return s;
};
这样我们就可以在程序里使用诸如:
"username:{0} nickname {1}".format("yizhu2000","二毛五")
资源
meizz的blog http://blog.csdn.net/meizz/