在Firefox上开发Javascript的典型原因是什么?

use*_*021 108 javascript firefox jquery yui

我开发了一些javascript增强页面,可以在最近的Firefox和Safari上正常运行.我错过了检查Internet Explorer,现在我发现这些页面在IE 6和7上都不起作用(到目前为止).脚本以某种方式不执行,页面显示好像javascript不存在,虽然执行了一些javascript.我使用自己的库与DOM操作,从YUI 2我使用YUI-装载机和XML-HTTP请求,并在一个页面上我用"psupload",它依赖于JQuery的.

我正在从Office XP安装Microsoft脚本编辑器,现在将进行调试.我现在也会写具体的测试.

IE的典型失败点是什么?我可以睁开眼睛的方向.

我找到了这个页面,显示了一些差异.访问:Quirksmode

您可以从您的经验中找到一些我应该首先寻找的典型事物吗?

我稍后会在这里提出更多有关具体任务的问题,但是现在我对你的经验感兴趣,为什么IE通常会在Firefox中运行正常的脚本失败

编辑:谢谢你们所有这些伟大的答案!

与此同时,我调整了整个代码,以便它也适用于Internet Explorer.我现在整合了jQuery并构建了我自己的类.这是我的基本错误,我从一开始就没有在jQuery上构建所有的东西.我现在有.

JSLint也帮助了我很多.

许多来自不同答案的单一问题都有所帮助.

cry*_*ryo 120

如果您发现任何错误/遗漏等,请随时更新此列表.

注意: IE9修复了以下许多问题,所以很多这只适用于IE8及以下版本,并且在某种程度上适用于怪异模式下的IE9.例如,IE9支持SVG, <canvas>,<audio><video>原生,但是你必须让符合标准的模式为他们提供.


一般:

  • 部分加载文档的问题:window.onloadIE或类似事件中添加JavaScript是个好主意,因为IE不支持部分加载文档中的许多操作.

  • 不同的属性:在CSS中,它elm.style.styleFloat在IE中与elm.style.cssFloatFirefox中.在<label>标签中for,elm.htmlFor在IE elm.for中使用Firefox 和Firefox 访问该属性.请注意,这for是在IE中保留的,因此elm['for']阻止IE引发异常可能是一个更好的主意.


基础JavaScript语言:

  • 访问字符串中的字符:'string'[0]IE不支持,因为它不在原始JavaScript规范中.使用'string'.charAt(0)'string'.split('')[0]注意到访问数组中的项目要比使用charAtIE中的字符串快得多(尽管split首次调用时会有一些初始开销.)

  • 对象结束前的逗号:例如{'foo': 'bar',},IE中不允许使用.


元素特定问题:

  • 获得documentIFrame:

    • Firefox和IE8 + :( IFrame.contentDocument IE 从版本8开始支持此功能.)
    • IE: IFrame.contentWindow.document
    • (IFrame.contentWindow指的window是两种浏览器.)

  • Canvas: IE9之前的IE版本不支持该<canvas>元素.IE确实支持类似技术的VML,并且explorercanvas可以<canvas>为许多操作的元素提供就地包装器.请注意,在使用VML时,标准兼容模式下的IE8要慢很多,并且比使用怪癖模式时有更多的故障.

  • SVG: IE9原生支持SVG.IE6-8可以支持SVG,但只能使用外部插件,其中只有一些插件支持JavaScript操作.

  • <audio><video>:仅在IE9中受支持.

  • 动态创建单选按钮: IE <8有一个错误,使得单选按钮创建时document.createElement无法检查.另请参阅如何在Javascript中动态创建适用于所有浏览器的单选按钮?为了解决这个问题.

  • 在IE 中的<a href>标签和onbeforeunload冲突中嵌入JavaScript :如果标签的href一部分中嵌入了JavaScript a(例如,<a href="javascript: doStuff()">IE将始终显示从中返回的消息,onbeforeunload除非onbeforeunload事先删除处理程序.另请参阅关闭选项卡时请求确认.

  • <script>标记事件差异: onsuccess并且onerror在IE中不受支持,并且由特定于IE的内容替换onreadystatechange,无论下载是成功还是失败,都会触发.有关详细信息,另请参阅JavaScript Madness.


元素大小/位置/滚动和鼠标位置:

  • 获取元素大小/位置:元素的宽度/高度有时elm.style.pixelHeight/Width在IE而不是elm.offsetHeight/Width,但在IE中都不可靠,尤其是在怪癖模式中,有时一个比另一个更好.

    elm.offsetTop并且elm.offsetLeft经常被错误地报告,导致找到元素的位置不正确,这就是为什么弹出元素等在很多情况下几个像素关闭的原因.

    另请注意,如果元素(或元素的父元素)具有一个display,none那么IE将在访问大小/位置属性时引发异常,而不是0像Firefox那样返回.

  • 获取屏幕大小(获取屏幕的可视区域):

    • 火狐: window.innerWidth/innerHeight
    • IE标准模式: document.documentElement.clientWidth/clientHeight
    • IE怪癖模式: document.body.clientWidth/clientHeight

  • 文档滚动位置/鼠标位置:这个实际上没有被w3c定义,所以即使在Firefox中也是非标准的.找到scrollLeft/ scrollTopdocument:

    • Firefox和IE在怪癖模式下: document.body.scrollLeft/scrollTop
    • IE在标准模式下: document.documentElement.scrollLeft/scrollTop
    • 注意:其他一些浏览器也使用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];
      };
      
      Run Code Online (Sandbox Code Playgroud)

    为了获得鼠标光标的位置,evt.clientX并且evt.clientYmousemove事件中将给出相对于文档的位置而不添加滚动位置,因此需要合并先前的函数:

    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]];
     };
    };
    
    Run Code Online (Sandbox Code Playgroud)

选择/范围:

  • <textarea><input>选择:selectionStartselectionEnd没有在IE中实现,并且在它的位置有一个专有的"范围"系统,请参见textarea中的插入位置,从一开始就是字符.

  • 获取文档中当前选定的文本:

    • 火狐: window.getSelection().toString()
    • IE: document.selection.createRange().text


按ID获取元素:

  • document.getElementById也可以引用name表单中的属性(取决于文档中首先定义的属性),因此最好不要使用具有相同name和的相同元素id.这可以追溯到id不是w3c标准的日子.document.all(一个专有的IE特定属性)明显快于document.getElementById,但它有其他问题,因为它总是优先考虑name之前id.我个人使用这段代码,为了确保可以退回额外的检查:

    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;
     };
    };
    
    Run Code Online (Sandbox Code Playgroud)

只读innerHTML的问题:

  • IE浏览器不支持的设置的innerHTML col,colGroup,frameSet,html,head,style,table,tBody,tFoot,tHead,title,和tr元件.这是一个针对表相关元素的函数:

    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;
      };
     };
    };
    
    Run Code Online (Sandbox Code Playgroud)

    还要注意的是IE需要添加一个<tbody>到一个<table>附加之前<tr>s到该<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);
    // and so on
    
    Run Code Online (Sandbox Code Playgroud)

事件差异:

  • 获取event变量: DOM事件不会传递给IE中的函数,并且可以作为window.event.获取事件的一种常见方法是使用例如if undefined定义的
    elm.onmouseover = function(evt) {evt = evt||window.event}
    默认值.window.eventevt

  • 关键事件代码差异:关键事件代码变化很大,但是如果你看一下QuirksmodeJavaScript Madness,它几乎不是特定于IE,Safari和Opera再次不同.

  • 鼠标事件差异:button IE中的属性是一个位标志,允许一次使用多个鼠标按钮:

    • 左: 1(var isLeft = evt.button & 1)
    • 右: 2(var isRight = evt.button & 2)
    • 中心: 4(var isCenter = evt.button & 4)

      W3C模型(由Firefox支持)不如IE模型灵活,只有一个按钮允许一次使用左0,右2和中心1.请注意,正如Peter-Paul Koch所提到的,这是非常反直觉的,因为0通常意味着"没有按钮".

      offsetX并且offsetY问题,最好在IE中避免使用它们.更可靠的方式来获得的offsetX,并offsetY在IE浏览器将获得位置相对定位的元素和减去它clientXclientY.

      另请注意,在IE中要在click事件中双击,您需要将a clickdblclick事件都注册到函数中.Firefox的火灾click以及dblclick双击的,所以IE特定需要检测到具有相同的行为.

  • 在事件处理的不同模式:无论是专有的IE模型和事件从下往上火狐模型的支持处理,例如,如果有在这两个元素的事件<div><span></span></div>,然后事件将触发在span 随后div而不是它们是秩序如果使用传统的例如,elm.onclick = function(evt) {}则绑定.

    "捕捉"事件通常只支持在Firefox等,这将触发div,则span事件中自上而下的顺序.在处理其他事件之前,IE具有elm.setCapture()并且elm.releaseCapture()用于将鼠标事件从文档重定向到元素(elm在这种情况下),但是它们具有许多性能和其他问题,因此应该避免.

    • 火狐:

      :elm.addEventListener(type, listener, useCapture [true/false])
      卸下:elm.removeEventListener(type, listener, useCapture)
      (type是例如'mouseover'on)

    • IE:在IE中只能添加元素上给定类型的单个事件 - 如果添加了多个相同类型的事件,则会引发异常.还要注意,事件函数中this引用的window不是绑定元素(因此不太有用):

      :elm.attachEvent(sEvent, fpNotify)
      卸下:elm.detachEvent(sEvent, fpNotify)
      (sEvent例如是'onmouseover')

  • 事件属性差异:

    • 阻止事件被任何其他侦听功能处理:

      Firefox: evt.stopPropagation()
      IE: evt.cancelBubble = true

    • 停止例如插入字符的关键事件或停止检查复选框:

      火狐浏览器: evt.preventDefault()
      IE: evt.returnValue = false
      注意:只是返回falsekeydown,keypress,mousedown,mouseup,click并且reset也可以防止违约.

    • 获取触发事件的元素:

      Firefox: evt.target
      IE: evt.srcElement

    • 获取元素鼠标光标远离: evt.fromElement在IE中evt.target,如果在某个onmouseout事件中,则在Firefox中,否则evt.relatedTarget

    • 获取鼠标光标移动到的元素: evt.toElement在IE中evt.relatedTarget,如果在某个onmouseout事件中,则在Firefox中,否则evt.target

    • 注意:( evt.currentTarget绑定事件的元素)在IE中没有等效项.

  • 非常非常非常好的清单!感谢所有贡献:) (12认同)

Luc*_*chi 26

还要检查代码中是否包含这些或类似的逗号

var o={
'name1':'value1',
'name2':'value2',
} 
Run Code Online (Sandbox Code Playgroud)

Firefox可以容忍最后一个逗号(在value2之后),但IE不会容忍

  • JSLint捕获它们 (2认同)

Nic*_*ver 12

如果你坚持使用jQuery或YUI作为你的帖子被标记,你应该在浏览器之间有最小的差异......这就是框架的用途,为你处理这些跨浏览器的差异.

举一个例子,看一下quirksmode DOM遍历页面,根据它IE不支持大多数事情......虽然如此,框架确实如例如IE不支持elem.childElementCount,但在jQuery中:$(elem).children().size()用于获取此值,在每个浏览器中.您会发现库中有一些东西可以处理跨浏览器99%的不支持案例,至少使用脚本...使用CSS您可能需要移动到库的插件,这个常见的例子就是获得圆角在IE中工作...因为它没有CSS支持.

然而,如果你直接开始做的事情,比如document.XXX(thing),你在图书馆不是,你直接做的JavaScript(这是所有的JavaScript,但你明白了吧:),而这可能会或可能不会造成问题,这取决于如何IE团队实施该特定功能时喝醉了.

与IE浏览器你就更有可能失败的造型现身权不是原始的JavaScript问题,动画一小部分像素以及诸如此类的事情,很多更因此在课程的IE6.


GSt*_*Sto 10

getElementbyID也将与IE中的name属性匹配,但不会与其他浏览器匹配,IE将首先选择它找到的任何一个.

例:

<script>
 var foo = document.getElementById('bar');
</script>

....
<input name="bar" type="text" />  //IE will get this element
<span id="bar"> Hello, World! </span>  //FF,Safari,Chrome will get this element
Run Code Online (Sandbox Code Playgroud)

  • document.getElementByIdOrNameIGuessWhateverMan(ID); (12认同)
  • 抱歉粗鲁,但IE真的很难看 (3认同)

Jak*_*kob 5

有很多东西,但我曾经陷入过的一个陷阱是许多浏览器接受没有引用名称的JSON,而ie6和ie7则没有.

{ name: "Jakob" } // will often work, but not in ie6/ie7
{ "name": "Jakob" } // Better!
Run Code Online (Sandbox Code Playgroud)

编辑:为了澄清,这只是一个问题,当需要实际的JSON时,而不是对象文字.JSON是对象文字语法的一个子集,它是一种数据交换格式(如XML),这就是为什么它被设计为更挑剔的原因.

  • 请注意,这取决于上下文,对象文字很好,JSON不是......但是例如jQuery在其最新版本中根本不允许使用无效的JSON. (2认同)

gna*_*arf 5

不同的JavaScript支持

从1.5开始,IE不支持(大部分)添加到JavaScript的扩展.

1.6的新功能

  • 阵列方法- ,indexOf(),lastIndexOf(),every(),filter(),,forEach()map()some()
  • for each ... in - 迭代值而不是属性名称.

1.7的新功能

1.8的新功能

  • 数组方法 - reduce(),reduceRight()
  • 用于定义函数的快捷方式.

其中一些要求你指定要运行的JavaScript的版本号(在IE下会破坏),但有些事情[1,2,3].indexOf(2)可能看起来不是那么大,直到你尝试在IE中运行它


归档时间:

查看次数:

7018 次

最近记录:

10 年,9 月 前