Javascript在Firefox上开发的典型原因是什么? [英] What are the typical reasons Javascript developed on Firefox fails on IE?

查看:257
本文介绍了Javascript在Firefox上开发的典型原因是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发了一些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 vs elm .style.cssFloat 在Firefox中。在< label> 标记中,对属性的访问是通过 elm.htmlFor 和Firefox中的 elm.for 。请注意,的在IE中保留,所以 elm ['for >)可能是阻止IE升级一个例外。



    $ b

    基本的JavaScript语言:


    $ b

    • 访问字符串中的字符'string'[0] 在IE中不受支持,因为它不在原始的JavaScript规范中。使用'string'.charAt(0)'string'.split('')[0] 注意到访问数组中的项目要比在IE中使用 charAt 和字符串要快得多(尽管当 split 是第一个)


    • 对象结束之前的逗号: {'foo':'bar',} 在IE中是不允许的。




      特定元素的问题:


    • 获取IFrame的文档


    • 画布:IE9之前的版本不支持 < canvas> 元素。 IE确实支持 VML 这是一个类似的技术,然而, explorercanvas 可以为< canvas> 元素提供原地包装为许多操作。请注意,在使用VML的标准模式下,IE8的速度要慢许多倍,并且比使用怪异模式时还要多出许多的毛刺。

    • / strong> IE9本地支持SVG。 IE6-8可以支持SVG,但只能使用外部插件一些支持JavaScript操作的插件。
    • < audio> 和<$ c仅在IE9中支持$ c>< video> 动态创建单选按钮: IE< 8有一个错误,它使用 document.createElement 创建的单选按钮不可检查。另见如何在Javascript中动态创建一个单选按钮,并在所有浏览器中工作?以解决这个问题。

    • >嵌入式JavaScript在< a href> 标记和 onbeforeunload IE中的冲突: a 标记的 href 部分中(例如< a href =javascript: doStuff()> 那么IE将总是显示从 onbeforeunload 返回的消息,除非 onbeforeunload 处理程序。另见关闭标签时询问确认

      a>。
    • code> onsuccess onerror 是不支持在IE中,并被一个特定于IE的 onreadystatechange 所取代,无论下载是成功还是失败,都会被触发。另请参阅 JavaScript疯狂获取更多信息。
      元素大小/位置/滚动和鼠标位置:


        $ b



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

          elm.offsetTop elm.offsetLeft 错误地报告,导致元素的位置不正确,这就是为什么在很多情况下弹出元素等几个像素关闭。另外请注意,如果元素(或元素的父元素)的显示 none 那么IE在访问大小/位置属性时会引发一个异常,而不像Firefox那样返回 0

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


          • Firefox: window.innerWidth / innerHeight
          • IE标准模式: document.documentElement.clientWidth / clientHeight
          • IE quirks模式: strong> document.body.clientWidth / clientHeight



        • 文档滚动位置/鼠标位置:这个实际上并不是由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;
              };
              };







            • < h2>只读的innerHTML的问题:


              • 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; x elm .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> < 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);
                //等等







              事件区别:

              $ ul $ $ $ 事件变量
              :DOM事件不会传递给IE中的函数,可以通过 window.event 访问。获得该事件的一种常见方式是使用例如
              elm.onmouseover = function(evt){evt = evt || window.event}
              默认为 window.event 如果 evt 未定义。
            • 关键事件代码差异:关键事件代码差异很大,但是如果您查看 Quirksmode 或< JavaScript的疯狂,它不是特定于IE浏览器,Safari和Opera又是不同的。

/ 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模型支持从下到上处理事件,例如,如果< div>< span>< / span>< / div> 这两个元素中都有事件,那么事件将会在 span then div ,而不是传统的使用 elm.onclick = function(evt){} 。 捕捉事件通常只在Firefox等支持,这将触发 div 然后 span 事件在自上而下的顺序。 IE具有 elm.setCapture() elm.releaseCapture()用于将鼠标事件从文档重定向到元素在这种情况下, elm )在处理其他事件之前,他们有一些性能和其他问题,所以应该避免。


      • 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
        >


      • 事件属性的区别:
        $ b

        • 停止由其他监听功能处理的事件
          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如果在 onmouseout 事件中,IE中的.fromElement 是Firefox中的 evt.target ,否则 evt.relatedTarget


        • 获取鼠标光标的元素: evt.toEleme nt 在Firefox中是 evt.relatedTarget ,如果在 onmouseout 事件中,否则 evt.target


        • evt。



        • 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 vs elm.style.cssFloat in Firefox. In <label> tags the for attribute is accessed with elm.htmlFor in IE vs elm.for in Firefox. Note that for is reserved in IE so elm['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 using charAt with strings in IE (though there's some initial overhead when split 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 the window in both browsers.)

          • 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 and onbeforeunload conflicts in IE: If there's embedded JavaScript in the href part of an a tag (e.g. <a href="javascript: doStuff()"> then IE will always show the message returned from onbeforeunload unless the onbeforeunload handler is removed beforehand. See also Ask for confirm when closing a tab.

          • <script> tag event differences: onsuccess and onerror aren't supported in IE and are replaced by an IE-specific onreadystatechange 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 than elm.offsetHeight/Width, but neither is reliable in IE, especially in quirks mode, and sometimes one gives a better result than the other.

            elm.offsetTop and elm.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 of none then IE will raise an exception when accessing size/position attributes rather than returning 0 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

          • 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 the document:

            • 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 and evt.clientY in mousemove 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]];
             };
            };
            


          Selections/ranges:

          • <textarea> and <input> selections: selectionStart and selectionEnd 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


          Getting elements by ID:

          • document.getElementById can also refer to the name attribute in forms (depending which is defined first in the document) so it's best not to have different elements which have the same name and id. This dates back to the days when id wasn't a w3c standard. document.all (a proprietary IE-specific property) is significantly faster than document.getElementById, but it has other problems as it always prioritizes name before id. 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, and tr 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 using document.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 as window.event. One common way of getting the event is to use e.g.
            elm.onmouseover = function(evt) {evt = evt||window.event}
            which defaults to window.event if evt 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 as 2 and center as 1. Note that, as Peter-Paul Koch mentions, this is very counter-intuitive, as 0 usually means 'no button'.

              offsetX and offsetY are problematic and it's probably best to avoid them in IE. A more reliable way to get the offsetX and offsetY in IE would be to get the position of the relatively positioned element and subtract it from clientX and clientY.

              Also note that in IE to get a double click in a click event you'd need to register both a click and dblclick event to a function. Firefox fires click as well as dblclick when double clicking, so IE-specific detection is needed to have the same behaviour.

          • 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 the span then the div 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 the span events in a top down order. IE has elm.setCapture() and elm.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 the on)

            • 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 to window 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 returning false in keydown, keypress, mousedown, mouseup, click and reset 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 is evt.target in Firefox if in an onmouseout event, otherwise evt.relatedTarget

            • Getting the element the mouse cursor moved to: evt.toElement in IE is evt.relatedTarget in Firefox if in an onmouseout event, otherwise evt.target

            • Note: evt.currentTarget (the element to which the event was bound) has no equivalent in IE.

          这篇关于Javascript在Firefox上开发的典型原因是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆