最近做了一些javascript相关的工作,把收获和大家分享一下,感谢下meizz,他的框架jsframework给我提供了许多现成的工具
title这个元素比较特殊
如果title中有经过htmlencode的字符,通过document.title获得的内容将会自动解码,并且在ie中通过给title加上一个id然后用document.getElementById(titleid).innerHTML来获得其中内容也仍然是已经解码的,而firefox则不会
<
html
>
<
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
<!
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"
xml:lang
="zh-CN"
lang
="zh-CN"
>
这是document.body.scrollTop始终为0,这时需要用document.documentElement.scrollTop才能获得正确的值
而如果不加xhtml的申明,document.documentElement.scrollTop将为0
下面这个getScrollXY()方法可以包装这个变化
<
html
>
<
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也具有这个属性
if
(
typeof
(HTMLElement)
!=
"
undefined
"
&&
!
window.opera){
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下获得鼠标位置的方法
<
button
onclick
="onClick()"
>
获得鼠标点击横坐标
</
button
>
<
script
type
="text/javascript"
>
function
onclick(){
alert(event.clientX);
}
</
script
>
需要改成
<button onclick="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的属性我们可以这样做
if
(
typeof
(HTMLElement)
!=
"
undefined
"
&&
!
window.opera){
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
if
(
typeof
(HTMLElement)
!=
"
undefined
"
&&
!
window.opera){
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
String.prototype.format
=
function
()
{
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/