- [1].在IE中,事件对象是作为一个全局变量来保存和维护的.所有的浏览器事件,不管是用户触发的,还是其他事件,都会更新window.event对象.所以在代码中,只要轻松调用window.event就可以轻松获取事件对象, 再event.srcElement就可以取得触发事件的元素进行进一步处理.
[2].在FireFox中,事件对象却不是全局对象,一般情况下,是现场发生,现场使用,FireFox把事件对象自动传给事件处理程序.
<input type="button" id="btn1" value="你"/>
<input type="button" id="btn2" value="我"/>
<input type="button" id="btn3" value="他"/>
<script>
var $=function(id) {
if(!document.getElementById) return null;
else return document.getElementById(id);
}
window.onload=function() {
$('btn1').onclick=fun1;
$('btn2').onclick=fun2;
$('btn3').onclick=fun3;
}
function fun1(){
;//IE中, window.event使全局对象
//IE下,显示 "[object]" , FF下显示 "undefined"
;//FF中, 第一个参数自动从为 事件对象
//IE下,显示 "undefined", FF下显示 "[object]"
}
function fun2(e) {
; //IE下,显示 "[object]",FF下显示 "undefined"
//注意,我从来没有给 fun2传过参数哦。
//现在 FF自动传参数给 fun2, 传的参数e就是事件对象了
; // IE下,显示"undefined", FF下显示"[object]"
}
function fun3(){ //同时兼容IE和FF的写法,取事件对象
; // IE 和 FF下,都显示 "[object]"
var evt=arguments[0] || window.event;
var element=evt.srcElement || evt.target; //在IE和FF下取得btn3对象 ; // btn3
}
</script>
到这里,我们似乎对IE和FF的事件处理方式都已经理解了,并找到了解决的办法。但是事情还没有结束。看代码
<button id="btn" onclick="fun">按钮</button>
<script>
function fun(){
;
}
</script>
很不幸,fun给我们的结果是undefined, 而不是期望的object!!!!!!!!
原因在于事件绑定的方式:onclick="fun()"就是直接执行了, fun() 函数,没有任何参数的,这种情况下firefox没有机会传递任何参数给fun,而btn.onclick=fun这种情况, 因为不是直接执行函数,firefox才有机会传参数给fun.
解决方法:
方法一:比较笨的方法,既然 firefox没有机会传参数,那么自己勤快点,自己传 !!
<button id="btn" onclick="fun(event)">按钮</button>
<script>
function fun(){
;
var evt=arguments[0] || window.event;
var element=evt.srcElement || evt.target;
;
}
</script>
方法二: 自动查找
<button id="btn4" onclick="fun4()">按钮4</button>
<script>
function fun4(){
var evt=getEvent();
var element=evt.srcElement || evt.target;
;
}
function getEvent(){ //同时兼容ie和ff的写法
if(document.all) return window.event;
func=getEvent.caller;
while(func!=null){
var arg0=func.arguments[0];
if(arg0){
if((arg0.constructor==Event || arg0.constructor ==MouseEvent)
|| (typeof(arg0)=="object" && arg0.preventDefault && arg0.stopPropagation)){
return arg0;
}
}
func=func.caller;
}
return null;
}
</script>
方法三
function SearchEvent()
{
//IE
if(document.all)
return window.event;
func=SearchEvent.caller;
while(func!=null)
{
var arg0=func.arguments[0];
if(arg0)
{
if(arg0.constructor==Event)
return arg0;
}
func=func.caller;
}
return null;
} - 在ie中,事件对象是作为一个全局变量来保存和维护的。 所有的浏览器事件,不管是用户触发
的,还是其他事件, 都会更新window.event 对象。 所以在代码中,只要轻松调用 window.event
就可以轻松获取 事件对象, 再 event.srcElement 就可以取得触发事件的元素进行进一步处理 - 在ff中, 事件对象却不是全局对象,一般情况下,是现场发生,现场使用,ff把事件对象自动传
递给对应的事件处理函数。在代码中,函数的第一个参数就是ff下的事件对象了。
function SearchEvent()
{ if(document.all)
return window.event; func=SearchEvent.caller;
while(func!=null)
{ var arg0=func.arguments[0];
if(arg0.constructor==Event||arg0.constructor==MouseEvent)
{
return arg0;
}
func=func.caller; }
return null;}
2 <button id="btn2">按钮2button>
3 <button id="btn3">按钮3button>
4
5 <script>
6
7 window.onload=function(){
8
9
10
11 }
12
13 function foo1(){
14
15
16
18
19 }
20
21 function foo2(e){
22
23
25
26 }
27
28 function foo3(){
29
30
31
32
33 }
34 script>
35
看到这里,我们似乎对 ie和ff的事件处理方式都已经理解了,并找到了解决的办法
☆ javascript 相关
△ 这里也有部分总结
http://www.cnitblog.com/joyboy/archive/2008/07/01/42429.html
△ document.all("id") -> document.getElementById("id")
并且控件尽量用id,而不是name标识
提示: form 内用于提交的元素必须定义name
提示:
如果控件只有name,没有id, 用getElementById时:
IE:也可以找到对象
FF:返回NULL
△ 获得form里某个元素的方法
elForm.elements['name'];
△ 取集合元素时, ie支持 [],() 2种写法, 但是ff仅支持[],如:
table.rows(5).cells(0)
改为:
table.rows[5].cells[0]
△ 判断对象是否是object的方法应该为
if( typeof(obj) == "object")
△ eval(对象名称) -> document.getElementById
FF支持eval函数
△ 在当前对象的前面插入节点
obj.insertAdjacentElement("beforeBegin", elText);
改为用
obj.parentNode.insertBefore(elText, obj);
△ FF的createElement不支持HTML代码
用document.write(esHTML);
或者创建元素后再设置属性, 对input元素来说,需要先设置type再加入到dom里
var elInput = createElement("input");
elInput.type = "checkbox";
var obj2 = document.getElementById("id2");
obj2.parentNode.insertBefore(elInput, obj2);
如果是直接插入html代码,则可以考虑用
createContextualFragment
△ innerText -> textContent
FF 没有innerText
如果确定没有html代码, 也可以统一用 innerHTML
△ 对象名称中的$不能识别, 建议改为_
objName = "t1$spin"
改为
objName = "t1_spin"
△ FF里设置Attribute为某个对象,然后再取出来,这时候对象的属性都丢失了?
elText.setAttribute("obj", obj);
alert(obj.id) //正确的名字
obj = objText.getAttribute("obj");
alert(obj.id) //null
在IE下没有问题, FF对setAttribute来说,第2个参数都是字符串型的!!!
所以如果第2个参数是对象时,相当于调用对象的 toString() 方法了
解决的方法是用下面的调用方式:
elText.obj = obj;
obj = elText.obj
△ 在html里定义的属性,必须用getAttribute才行
<input type="text" id="t1" isOBJ="true">
获取时:
document.getElementById("t1").isOBJ 总返回 undefined, IE下是可以的
应该用:
document.getElementById("t1").getAttribute("isOBJ")
△ el.class -> el.className
由于class是关键字, 所以需要用 className
或者用 setAttribute/getAttribute
setAttribute("class","css样式名称");
△ FF里select控件不再是:总是在顶端显示
需要设置控件的zIndex
IE6 里select控件总在顶端显示, div不能盖住select
覆盖select控件的方法是, 用 ifame 盖住 select, 再设置div元素的zIndex大于iframe的zIndex
△ 对于if ( vars == undefined ) 下面的值用于判断是等同的
undefined
null
false
0
△ 如果FF调用 el.focus(); 报错
尝试改为:
window.setTimeout( function(){ el.focus(); }, 20);
△ FF下,keyCode是只读的, 那把回车转换为tab怎么办? 在录入时进行键值转换怎么办??
解决方案:
1. 回车跳转 -> 自己写跳转处理代码.
遍历dom里所有的元素, 找到当前元素的下一个能够设置焦点的,当前可见的元素, 给其设置焦点
如果该元素的父节点是不可见的, 则还是会报错, 所以设置焦点时, 需要try catch, 如果报错,则继续找下一个
2. 录入时进行键值转换.
利用selection,选中光标后面的内容,替换为新输入的内容
△ <button> 会被firefox解释为提交form或者刷新页面???
需要写上type <button type="button">按钮</button>
或者在onclick="原函数调用(); return false;"
△ 在firefox里, document.onfocus里获得不到实际获得焦点的控件?
为什么document.keydown可以呢?
△ children -> childNodes
△ sytle.pixelHeight -> style.height
△ 判断函数或者变量是否存在,没有则创建
if (!("funcA" in window)) var funcA = function() { alert("请覆写funcA方法"); };
△ 获得客户区尺寸
IE里与doctype有关
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" >
如果html包含上面的语句,则应该用下面的方法获取
document.documentElement.clientWidth
否则用
document.body.clientWidth
△ window.createPopup
FF不支持
△ document.body.onresize
FF 不支持
用window.onresize
注意,页面打开时并不会触发onresize事件? 需要在onload里也调用一次才行
△ box模型的问题
IE下默认的是 content-box 为了统一,可用设置:
div, td {-moz-box-sizing:border-box;box-sizing:border-box;margin:0;padding: 0;}
而且要定义doctype
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
但是对IE旧代码影响较大
△ 注册事件
IE: el.attachEvent
FF: el.addEventListener("blur", myBlur, false);
第1个参数事件名称不需要带"on"
第3个参数false代表事件传递从事件对象沿dom树往body方向传(与IE的方向一致)
ff里如果不指定 el 则是给全局的事件注册?? 全局岂不是window?
△ 触发事件
IE: el.fireEvent("onclick");
FF:
var e = document.createEvent("Events");
e.initEvent("click", true, false);
element.dispatchEvent(event)
△ 在自定义函数中获得对象句柄
var oThis = this;
obj.onfocus = function(evt){
oThis.doOnFocus(evt);
}
△ 统一事件处理框架代码
function doOnFocus(evt){
evt = evt || window.event;
var el = evt.target || evt.srcElement;
// 后续处理
}
△ FF不支持onpropertychange事件
但是FF里可以定义属性的setter方法, 如下面的:
HTMLElement.prototype.__defineSetter__("readOnly",
function(readOnly){
// 构造虚拟的event对象
var evt = [];
evt["target"] = this;
evt["propertyName"] = "readOnly"
//onpropertychange函数需要定义evt参数, 参考统一事件处理框架代码
if ("onpropertychange" in this) this.onpropertychange(evt);
}
);
△ document.activeElement
用途: 在当前对象的 onblur 事件里, 可以通过 activeElement 获得下一个获得焦点的对象
html5规范里加入
firefox3里已经支持,与IE里效果一样
☆ css 相关
△ cursor:hand -> cursor:pointer
△ FILTER firefox不支持
filter: Alpha(Opacity=50);
替换为
-moz-opacity: 0.5;
△ text-overflow
不支持
△ transparent
firefox下 obj.setAttribute("bgColor","#ffffff") 只支持颜色
必须用 obj.style.backgroundColor = "transparent" 才行
△ FF下text控件高度与IE不同
input[type=text] {
height:20px;
}
注意input与[之间不能有空格!
△ font在IE里不能对body和td等起作用
统一用 font-family
△ expression firefox不支持
expression的确能够解决IE6对css2支持不足的问题,这样只需要定义css就可以兼容IE和FF了
在IE下expression非常消耗CPU, 所以不建议在大量的element上应用!!
△ IE6 仅支持 a:hover, 不支持其它对象的 :hover
1. 加入下面的css
.ie-hover {
behavior: expression(
this.onmouseover = new Function("this.className = 'hover';"),
this.onmouseout = new Function("this.className = 'ie-hover';"),
this.style.behavior = null
);
}
上面必须用 this.style.behavior = null , 否则某些情况会有严重的性能问题
2. 在需要 :hover 的元素上增加 class
<li class="ie-hover">
3. 定义 :hover 样式同时定义 .hover 样式
ul li:hover , ul li.hover {
xxx
}
△ IE6里 <a> 必须定义href属性 a:hover 才有效