Javascript在Firefox上开发的典型原因是什么? [英] What are the typical reasons Javascript developed on Firefox fails on IE?
问题描述
我开发了一些JavaScript增强页面,可以在最近的Firefox和Safari上正常运行。我错过了检查Internet Explorer,现在我发现这些页面不能在IE 6和7(到目前为止)上工作。该脚本不知何故不执行,页面显示,如果JavaScript不在那里,虽然一些JavaScript执行。我使用自己的库与dom操纵,从YUI 2我使用YUI-Loader和XML-Http-Request,并在一个页面上使用psupload,这取决于JQuery。
我正在从Office XP安装Microsoft脚本编辑器,现在将进行调试。我现在也会写特定的测试。
IE的典型失败点是什么?什么方向我可以保持我的眼睛打开。
我发现这个页面,这显示了一些差异。请访问: Quirksmode
你可以从您的经验名称,我应该首先寻找一些典型的东西?
我以后也会在这里提出更多的问题来处理特定的任务,但现在我对您的经验感兴趣,为什么IE通常在Firefox中运行正常的脚本失败
编辑:感谢所有这些好的答案!
在此期间,我调整了整个代码,以便它也可以与Internet Explorer一起使用。我整合了jQuery,并在其上建立了自己的类。这是我的基本错误,我从一开始就没有在jQuery上构建所有的东西。现在我有。
另外JSLint帮了我很大的忙。
答案帮助。
如果您看到任何错误/遗漏等,请随时更新此列表。注意:IE9修复了很多以下的问题,所以很多这个只适用于IE8及以下版本,并且在一定程度上适用于IE9的怪异模式。例如,IE9支持SVG,< canvas>
,< audio>
和< ; video>
本地,但是您必须启用标准符合模式,以使它们可用。
常规:
-
部分加载的文档存在问题:添加您的JavaScript在
window.onload
或类似的事件,因为IE不支持部分加载的文档中的许多操作。 -
不同属性:在CSS中,IE中
elm.style.styleFloat
vselm .style.cssFloat
在Firefox中。在< label>
标记中,对属性的访问是通过
elm.htmlFor $ IE中的c $ c>和Firefox中的
elm.for
。请注意,的在IE中保留,所以
elm ['for >)可能是阻止IE升级一个例外。
:。 动态创建单选按钮: IE< 8有一个错误,它使用
$ b基本的JavaScript语言:
$ b-
访问字符串中的字符:
'string'[0]
在IE中不受支持,因为它不在原始的JavaScript规范中。使用'string'.charAt(0)
或'string'.split('')[0]
注意到访问数组中的项目要比在IE中使用charAt
和字符串要快得多(尽管当split
是第一个) -
对象结束之前的逗号:
{'foo':'bar',}
在IE中是不允许的。
特定元素的问题:
-
获取IFrame的
文档
:
- Firefox和IE8 +:
IFrame.contentDocument
(IE开始支持这个 ) - IE:
IFrame.contentWindow.document
- (
IFrame.contentWindow
引用了两个浏览器中的窗口
)
- Firefox和IE8 +:
-
画布:IE9之前的版本不支持
< canvas>
元素。 IE确实支持 VML 这是一个类似的技术,然而, explorercanvas 可以为< canvas>
元素提供原地包装为许多操作。请注意,在使用VML的标准模式下,IE8的速度要慢许多倍,并且比使用怪异模式时还要多出许多的毛刺。 / strong> IE9本地支持SVG。 IE6-8可以支持SVG,但只能使用外部插件一些支持JavaScript操作的插件。 -
< audio>
和<$ c仅在IE9中支持$ c>< video>
document.createElement
创建的单选按钮不可检查。另见如何在Javascript中动态创建一个单选按钮,并在所有浏览器中工作?以解决这个问题。 >嵌入式JavaScript在 -
-
获取元素大小/位置:元素的宽度/高度有时
elm.style.pixelHeight / Width 在IE中,而不是 elm.offsetHeight / Width
,但在IE中都不可靠,特别是在怪癖模式下,有时候会比另一个更好。 -
获取屏幕大小(获取屏幕的可视区域):
- Firefox:
window.innerWidth / innerHeight
IE标准模式: document.documentElement.clientWidth / clientHeight
- Firefox:
- IE quirks模式: strong>
document.body.clientWidth / clientHeight
< a href>
标记和 onbeforeunload
IE中的冲突:在 a
标记的 href
部分中(例如< a href =javascript: doStuff()>
那么IE将总是显示从 onbeforeunload
返回的消息,除非 onbeforeunload $ c $事先删除c>处理程序。另见关闭标签时询问确认 a>。 code> onsuccess
和 onerror
是不支持在IE中,并被一个特定于IE的 onreadystatechange
所取代,无论下载是成功还是失败,都会被触发。另请参阅 JavaScript疯狂获取更多信息。 元素大小/位置/滚动和鼠标位置:
$ b
elm.offsetTop
和 elm.offsetLeft
错误地报告,导致元素的位置不正确,这就是为什么在很多情况下弹出元素等几个像素关闭。另外请注意,如果元素(或元素的父元素)的显示
的 none
那么IE在访问大小/位置属性时会引发一个异常,而不像Firefox那样返回 0
。
文档滚动位置/鼠标位置:这个实际上并不是由w3c定义的,所以即使在Firefox中也是非标准的。要找到文档
的 scrollLeft
/ scrollTop
:
- Firefox和IE以怪癖模式:
document.body.scrollLeft / scrollTop 标准模式下的IE:code>
-
document.documentElement.scrollLeft / scrollTop
li>
-
注意:其他一些浏览器使用
pageXOffset
/pageYOffset
以及。
function getDocScrollPos(){
var x = document.body.scrollLeft ||
document.documentElement.scrollLeft ||
window.pageXOffset || 0,
y = document.body.scrollTop ||
document.documentElement.scrollTop ||
window.pageYOffset || 0;
return [x,y];
};
为了获得鼠标的位置游标, evt.clientX
和 evt.clientY
在 mousemove
不会添加滚动位置 code> var mousepos = [0,0];
document.onmousemove = function(evt){
evt = evt || window.event;
if(typeof evt.pageX!='undefined'){
// Firefox支持
mousepos = [evt.pageX,evt.pageY];
} else {
// IE支持
var scrollpos = getDocScrollPos();
mousepos = [evt.clientX + scrollpos [0],evt.clientY + scrollpos [1]];
};
};
< h2>选择/范围:
-
< textarea>
和< input>
选择:selectionStart
和selectionEnd
没有在IE中实现,并且有一个专有的范围系统在它的位置,另见 textarea中的插入符号位置,从开始的字符开始。
-
获取文档中当前选定的文本: )
- IE:
document.selection.createRange()。text
$ b $ h
$ b $ h $元素由ID:
-
document.getElementById
也可以引用name
attrib (取决于在文档中首先定义的),所以最好不要使用具有相同的名称
和id
。这可以追溯到id 不是w3c标准的日子。 document.all
(一个专有IE特有的属性)显着更快而不是document.getElementById
,但是还有其他的问题,因为它始终优先于id>之前的
name
/ code>。我个人使用这个代码,回来检查,只是为了确保:
function getById(id){
var e;
if(document.all){
e = document.all [id];
if(e& e.tagName&& e.id === id){
return e;
};
};
e = document.getElementById(id);
if(e& e.id === id){
return e;
} else if(!e){
return null;
} else {
throw'通过name而不是id找到的元素:'+ id;
};
};
-
IE做不支持设置
col ,
colGroup
,frameSet
,html
,头
,style
,表,
tBody
,tFoot
,tHead
,title
和tr
元素。这里有一个函数,它可以处理与表格相关的元素:
pre $函数setHTML(elm,html){
/ /先尝试innerHTML
尝试{
elm.innerHTML = html;
} catch(exc){
function getElm(html){
//创建一个新元素并返回第一个子元素
var e = document.createElement('div') ;
e.innerHTML = html;
返回e.firstChild;
};
函数替换(elms){
//从elm'
中删除旧元素while(elm.children.length){
elm.removeChild(elm.firstChild);
}
//将新元素从'elms'添加到'elm'
(var x = 0; xelm .appendChild(elms.children [X]);
};
};
// IE 6-8不支持为
设置innerHTML // TABLE,TBODY,TFOOT,THEAD和TR直接
var tn = elm.tagName.toLowerCase();
if(tn ==='table'){
replace(getElm('< table> + html +'< / table>));
} else if(['tbody','tfoot','thead']。indexOf(tn)!= -1){
replace(getElm('< table>< tbody>' + html +'< / tbody>< / table>'。firstChild);
} else if(tn ==='tr'){
replace(getElm('< table>< tbody>< tr> + html +'< / tr> /tbody></table>').firstChild.firstChild);
} else {
throw exc;
};
};
};
另外请注意,IE需要添加
< tbody> $ c将code>< tr>
s添加到< code>< table> < tbody>
使用document.createElement
创建元素,例如:
var table = document.createElement('table');
var tbody = document.createElement('tbody');
var tr = document.createElement('tr');
var td = document.createElement('td');
table.appendChild(tbody);
tbody.appendChild(tr);
tr.appendChild(td);
//等等
-
关键事件代码差异:关键事件代码差异很大,但是如果您查看 Quirksmode 或< JavaScript的疯狂,它不是特定于IE浏览器,Safari和Opera又是不同的。
< h2>只读的innerHTML的问题:
事件区别:
$ ul $ $ $事件
变量:DOM事件不会传递给IE中的函数,可以通过window.event
访问。获得该事件的一种常见方式是使用例如
elm.onmouseover = function(evt){evt = evt || window.event}
默认为window.event
如果evt
未定义。
-
/ li>
鼠标事件差异: IE中的按钮
属性是一个位标志,鼠标按钮:
- Left: 1(
var isLeft = evt.button & 1< / code>)
- 右键: 2(
var isRight = evt.button& $(code>)
-
居中: 4(
var isCenter = evt.button& 4
)
0 ,正如 2
和中心为1
。请注意,正如Peter-Paul Koch 提及,这是非常直观的,因为0
通常意味着'no button'。
offsetX
和offsetY
都是问题,最好在IE中避免它们。在IE中获取offsetX
和offsetY
的更可靠的方法是获取相对定位元素的位置,并从clientX
和
clientY
。
另外请注意,在IE中双击
点击
事件,您需要注册点击
和dblclick
事件到一个函数。双击时,Firefox会触发点击
以及dblclick
,因此需要特定于IE的检测才能具有相同的行为。 在事件处理模型中的区别:专有的IE模型和Firefox模型支持从下到上处理事件,例如,如果 -
Firefox:
附加:elm.addEventListener(type,listener,useCapture [true / false])
Detach :elm.removeEventListener(type,listener,useCapture)
(type
)例如'mouseover'
-
IE: 只能在IE中添加元素上给定类型的单个事件 - 如果添加了多个相同类型的事件,则会引发异常。另外请注意,
this
指的是window
,而不是事件函数中的绑定元素(所以不太有用):
附加:elm.attachEvent(sEvent,fpNotify)
>:elm.detachEvent(sEvent,fpNotify)
(sEvent
)例如<$ c
> -
-
停止由其他监听功能处理的事件 :
Firefox:evt.stopPropagation()
IE:evt.cancelBubble = true
-
从插入字符或停止复选框检查的关键事件:
Firefox:evt.preventDefault()
IE:evt.returnValue = false
注意:只需在keydown
,按键
,<$ c返回false
$ c> mousedown ,mouseup
,点击
和/ code>也会阻止默认值。
获取触发事件的元素:
Firefox:evt.target
IE:srcElement
获取元素鼠标光标远离
evt如果在
是Firefox中的onmouseout
事件中,IE中的.fromElementevt.target
,否则evt.relatedTarget
获取鼠标光标的元素:
evt.toEleme nt
在Firefox中是evt.relatedTarget
,如果在onmouseout
事件中,否则evt.target
evt。
< div>< span>< / span>< / div>
这两个元素中都有事件,那么事件将会在 span
then div
,而不是传统的使用 elm.onclick = function(evt){}
。 捕捉事件通常只在Firefox等支持,这将触发 div
然后 span
事件在自上而下的顺序。 IE具有 elm.setCapture()
和 elm.releaseCapture()
用于将鼠标事件从文档重定向到元素在这种情况下, elm
)在处理其他事件之前,他们有一些性能和其他问题,所以应该避免。 $ b
ul>
I developed some javascript enhanced pages that run fine on recent Firefox and Safari. I missed to check in Internet Explorer, and now I find the pages don't work on IE 6 and 7 (so far). The scripts are somehow not executed, the pages show as if javascript wasn't there, although some javascript is executed. I am using own libraries with dom manipulation, from YUI 2 I use YUI-Loader and the XML-Http-Request, and on one page I use "psupload", which depends on JQuery.
I am installing Microsoft Script Editor from Office XP and will now debug. I will also write specific tests now.
What are the typical failing points of IE? What direction I can keep my eyes open.
I found this page, which shows some differences. visit: Quirksmode
Can you from your experience name some typical things I should look for first?
I will also ask more questions here for specific tasks later, but for now I am interested in your experience why IE usually fails on scripts that run fine in Firefox
Edit: Thank you for all those great answers!
In the meantime I have adapted the whole code so that it also works with Internet Explorer. I integrated jQuery and built my own classes on top of it now. This was my basic mistake, that I did not build all my stuff on jQuery from the beginning. Now I have.
Also JSLint helped me a lot.
And many of the single issues from the different answers helped.
Please feel free to update this list if you see any errors/omissions etc.
Note: IE9 fixes many of the following issues, so a lot of this only applies to IE8 and below and to a certain extent IE9 in quirks mode. For example, IE9 supports SVG, <canvas>
, <audio>
and <video>
natively, however you must enable standards compliance mode for them to be available.
General:
Problems with partially loaded documents: It’s a good idea to add your JavaScript in a
window.onload
or similar event as IE doesn’t support many operations in partially loaded documents.Differing attributes: In CSS, it's
elm.style.styleFloat
in IE vselm.style.cssFloat
in Firefox. In<label>
tags thefor
attribute is accessed withelm.htmlFor
in IE vselm.for
in Firefox. Note thatfor
is reserved in IE soelm['for']
is probably a better idea to stop IE from raising an exception.
Base JavaScript language:
Access characters in strings:
'string'[0]
isn’t supported in IE as it’s not in the original JavaScript specifications. Use'string'.charAt(0)
or'string'.split('')[0]
noting that accessing items in arrays is significantly faster than usingcharAt
with strings in IE (though there's some initial overhead whensplit
is first called.)Commas before the end of objects: e.g.
{'foo': 'bar',}
aren't allowed in IE.
Element-specific issues:
Getting the
document
of an IFrame:- Firefox and IE8+:
IFrame.contentDocument
(IE started supporting this from version 8.) - IE:
IFrame.contentWindow.document
- (
IFrame.contentWindow
refers to thewindow
in both browsers.)
- Firefox and IE8+:
Canvas: Versions of IE before IE9 don't support the
<canvas>
element. IE does support VML which is a similar technology however, and explorercanvas can provide an in-place wrapper for<canvas>
elements for many operations. Be aware that IE8 in standards compliance mode is many times slower and has many more glitches than when in quirks mode when using VML.SVG: IE9 supports SVG natively. IE6-8 can support SVG, but only with external plugins with only some of those plugins supporting JavaScript manipulation.
<audio>
and<video>
: are only supported in IE9.Dynamically creating radio buttons: IE <8 has a bug which makes radio buttons created with
document.createElement
uncheckable. See also How do you dynamically create a radio button in Javascript that works in all browsers? for a way to get around this.Embedded JavaScript in
<a href>
tags andonbeforeunload
conflicts in IE: If there's embedded JavaScript in thehref
part of ana
tag (e.g.<a href="javascript: doStuff()">
then IE will always show the message returned fromonbeforeunload
unless theonbeforeunload
handler is removed beforehand. See also Ask for confirm when closing a tab.<script>
tag event differences:onsuccess
andonerror
aren't supported in IE and are replaced by an IE-specificonreadystatechange
which is fired regardless of whether the download succeeded or failed. See also JavaScript Madness for more info.
Element size/position/scrolling and mouse position:
Getting element size/position: width/height of elements is sometimes
elm.style.pixelHeight/Width
in IE rather thanelm.offsetHeight/Width
, but neither is reliable in IE, especially in quirks mode, and sometimes one gives a better result than the other.elm.offsetTop
andelm.offsetLeft
are often incorrectly reported, leading to finding positions of elements being incorrect, which is why popup elements etc are a few pixels off in a lot of cases.Also note that if an element (or a parent of the element) has a
display
ofnone
then IE will raise an exception when accessing size/position attributes rather than returning0
as Firefox does.Get the screen size (Getting the viewable area of the screen):
- Firefox:
window.innerWidth/innerHeight
- IE standards mode:
document.documentElement.clientWidth/clientHeight
- IE quirks mode:
document.body.clientWidth/clientHeight
- Firefox:
Document scroll position/mouse position: This one is actually not defined by the w3c so is non-standard even in Firefox. To find the
scrollLeft
/scrollTop
of thedocument
:- Firefox and IE in quirks mode:
document.body.scrollLeft/scrollTop
- IE in standards mode:
document.documentElement.scrollLeft/scrollTop
NOTE: Some other browsers use
pageXOffset
/pageYOffset
as well.function getDocScrollPos() { var x = document.body.scrollLeft || document.documentElement.scrollLeft || window.pageXOffset || 0, y = document.body.scrollTop || document.documentElement.scrollTop || window.pageYOffset || 0; return [x, y]; };
In order to get the position of the mouse cursor,
evt.clientX
andevt.clientY
inmousemove
events will give the position relative to the document without adding the scroll position so the previous function will need to be incorporated:var mousepos = [0, 0]; document.onmousemove = function(evt) { evt = evt || window.event; if (typeof evt.pageX != 'undefined') { // Firefox support mousepos = [evt.pageX, evt.pageY]; } else { // IE support var scrollpos = getDocScrollPos(); mousepos = [evt.clientX+scrollpos[0], evt.clientY+scrollpos[1]]; }; };
- Firefox and IE in quirks mode:
Selections/ranges:
<textarea>
and<input>
selections:selectionStart
andselectionEnd
are not implemented in IE, and there's a proprietary "ranges" system in its place, see also Caret position in textarea, in characters from the start.Getting the currently selected text in the document:
- Firefox:
window.getSelection().toString()
- IE:
document.selection.createRange().text
- Firefox:
Getting elements by ID:
document.getElementById
can also refer to thename
attribute in forms (depending which is defined first in the document) so it's best not to have different elements which have the samename
andid
. This dates back to the days whenid
wasn't a w3c standard.document.all
(a proprietary IE-specific property) is significantly faster thandocument.getElementById
, but it has other problems as it always prioritizesname
beforeid
. I personally use this code, falling back with additional checks just to be sure:function getById(id) { var e; if (document.all) { e = document.all[id]; if (e && e.tagName && e.id === id) { return e; }; }; e = document.getElementById(id); if (e && e.id === id) { return e; } else if (!e) { return null; } else { throw 'Element found by "name" instead of "id": ' + id; }; };
Problems with read only innerHTML:
IE does not support setting the innerHTML of
col
,colGroup
,frameSet
,html
,head
,style
,table
,tBody
,tFoot
,tHead
,title
, andtr
elements. Here's a function which works around that for table-related elements:function setHTML(elm, html) { // Try innerHTML first try { elm.innerHTML = html; } catch (exc) { function getElm(html) { // Create a new element and return the first child var e = document.createElement('div'); e.innerHTML = html; return e.firstChild; }; function replace(elms) { // Remove the old elements from 'elm' while (elm.children.length) { elm.removeChild(elm.firstChild); } // Add the new elements from 'elms' to 'elm' for (var x=0; x<elms.children.length; x++) { elm.appendChild(elms.children[x]); }; }; // IE 6-8 don't support setting innerHTML for // TABLE, TBODY, TFOOT, THEAD, and TR directly var tn = elm.tagName.toLowerCase(); if (tn === 'table') { replace(getElm('<table>' + html + '</table>')); } else if (['tbody', 'tfoot', 'thead'].indexOf(tn) != -1) { replace(getElm('<table><tbody>' + html + '</tbody></table>').firstChild); } else if (tn === 'tr') { replace(getElm('<table><tbody><tr>' + html + '</tr></tbody></table>').firstChild.firstChild); } else { throw exc; }; }; };
Also note that IE requires adding a
<tbody>
to a<table>
before appending<tr>
s to that<tbody>
element when creating usingdocument.createElement
, for example:var table = document.createElement('table'); var tbody = document.createElement('tbody'); var tr = document.createElement('tr'); var td = document.createElement('td'); table.appendChild(tbody); tbody.appendChild(tr); tr.appendChild(td); // and so on
Event differences:
Getting the
event
variable: DOM events aren't passed to functions in IE and are accessible aswindow.event
. One common way of getting the event is to use e.g.elm.onmouseover = function(evt) {evt = evt||window.event}
which defaults towindow.event
ifevt
is undefined.Key event code differences: Key event codes vary wildly, though if you look at Quirksmode or JavaScript Madness, it's hardly specific to IE, Safari and Opera are different again.
Mouse event differences: the
button
attribute in IE is a bit-flag which allows multiple mouse buttons at once:- Left: 1 (
var isLeft = evt.button & 1
) - Right: 2 (
var isRight = evt.button & 2
) Center: 4 (
var isCenter = evt.button & 4
)The W3C model (supported by Firefox) is less flexible than the IE model is, with only a single button allowed at once with left as
0
, right as2
and center as1
. Note that, as Peter-Paul Koch mentions, this is very counter-intuitive, as0
usually means 'no button'.offsetX
andoffsetY
are problematic and it's probably best to avoid them in IE. A more reliable way to get theoffsetX
andoffsetY
in IE would be to get the position of the relatively positioned element and subtract it fromclientX
andclientY
.Also note that in IE to get a double click in a
click
event you'd need to register both aclick
anddblclick
event to a function. Firefox firesclick
as well asdblclick
when double clicking, so IE-specific detection is needed to have the same behaviour.
- Left: 1 (
Differences in the event handling model: Both the proprietary IE model and the Firefox model support handling of events from the bottom up, e.g. if there are events in both elements of
<div><span></span></div>
then events will trigger in thespan
then thediv
rather than the order which they're bound if a traditional e.g.elm.onclick = function(evt) {}
was used."Capture" events are generally only supported in Firefox etc, which will trigger the
div
then thespan
events in a top down order. IE haselm.setCapture()
andelm.releaseCapture()
for redirecting mouse events from the document to the element (elm
in this case) before processing other events, but they have a number of performance and other issues so should probably be avoided.Firefox:
Attach:
elm.addEventListener(type, listener, useCapture [true/false])
Detach:elm.removeEventListener(type, listener, useCapture)
(type
is e.g.'mouseover'
without theon
)IE: Only a single event of a given type on an element can be added in IE - an exception is raised if more than one event of the same type is added. Also note that the
this
refers towindow
rather than the bound element in event functions (so is less useful):Attach:
elm.attachEvent(sEvent, fpNotify)
Detach:elm.detachEvent(sEvent, fpNotify)
(sEvent
is e.g.'onmouseover'
)
Event attribute differences:
Stop events from being processed by any other listening functions:
Firefox:
evt.stopPropagation()
IE:evt.cancelBubble = true
Stop e.g. key events from inserting characters or stopping checkboxes from getting checked:
Firefox:
evt.preventDefault()
IE:evt.returnValue = false
Note: Just returningfalse
inkeydown
,keypress
,mousedown
,mouseup
,click
andreset
will also prevent default.Get the element which triggered the event:
Firefox:
evt.target
IE:evt.srcElement
Getting the element the mouse cursor moved away from:
evt.fromElement
in IE isevt.target
in Firefox if in anonmouseout
event, otherwiseevt.relatedTarget
Getting the element the mouse cursor moved to:
evt.toElement
in IE isevt.relatedTarget
in Firefox if in anonmouseout
event, otherwiseevt.target
Note:
evt.currentTarget
(the element to which the event was bound) has no equivalent in IE.
这篇关于Javascript在Firefox上开发的典型原因是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!