สาเหตุทั่วไปที่ Javascript พัฒนาบน Firefox ล้มเหลวบน IE คืออะไร [ปิด]


108

ฉันพัฒนาหน้าเว็บที่ปรับปรุงด้วยจาวาสคริปต์ซึ่งทำงานได้ดีบน Firefox และ Safari ล่าสุด ฉันพลาดที่จะตรวจสอบใน Internet Explorer และตอนนี้ฉันพบว่าหน้าต่างๆไม่ทำงานบน IE 6 และ 7 (จนถึงตอนนี้) สคริปต์ไม่ได้ถูกเรียกใช้งานหน้าเว็บจะแสดงราวกับว่าไม่มีจาวาสคริปต์แม้ว่าจะมีการเรียกใช้จาวาสคริปต์บางตัวก็ตาม ฉันใช้ไลบรารีของตัวเองที่มีการจัดการ Dom จาก YUI 2 ฉันใช้ YUI-Loader และ XML-Http-Request และในหนึ่งเพจฉันใช้ "psupload" ซึ่งขึ้นอยู่กับ JQuery

ฉันกำลังติดตั้ง Microsoft Script Editor จาก Office XP และตอนนี้จะทำการดีบัก ฉันจะเขียนการทดสอบเฉพาะในตอนนี้

จุดล้มเหลวทั่วไปของ IE คืออะไร? ทิศทางใดที่ฉันสามารถลืมตาได้

ฉันพบหน้านี้ซึ่งแสดงความแตกต่างบางอย่าง เยี่ยมชม: Quirksmode

จากประสบการณ์ของคุณสามารถตั้งชื่อสิ่งทั่วไปที่ฉันควรมองหาก่อนได้ไหม

ฉันจะถามคำถามเพิ่มเติมที่นี่สำหรับงานเฉพาะในภายหลัง แต่ตอนนี้ฉันสนใจในประสบการณ์ของคุณว่าทำไม IE ถึงล้มเหลวในสคริปต์ที่ทำงานได้ดีใน Firefox

แก้ไข:ขอบคุณสำหรับคำตอบที่ดีเหล่านั้น!

ในระหว่างนี้ฉันได้ปรับรหัสทั้งหมดเพื่อให้ใช้งานกับ Internet Explorer ได้ ฉันรวม jQuery และสร้างคลาสของตัวเองไว้ด้านบนแล้ว นี่เป็นข้อผิดพลาดพื้นฐานของฉันที่ฉันไม่ได้สร้างเนื้อหาทั้งหมดบน jQuery ตั้งแต่เริ่มต้น ตอนนี้ฉันมี.

นอกจากนี้ JSLint ยังช่วยฉันได้มาก

และหลายประเด็นเดียวจากคำตอบที่แตกต่างกันช่วยได้


ไม่มีปัญหากับ css หรือการจัดแต่งทรงผมอย่างที่ฉันรู้จากการเข้ารหัสก่อนหน้านี้ เฉพาะปัญหา JS - karlthorwald
user89021

1
ก่อนอื่นฉันจะเรียกใช้ JSLint ในไฟล์ทั้งหมดมีบางไฟล์ที่ฉันไม่เคยปรับเปลี่ยน
user89021

7
"นี่เป็นข้อผิดพลาดพื้นฐานของฉันที่ฉันไม่ได้สร้างเนื้อหาทั้งหมดบน jQuery ตั้งแต่เริ่มต้น" - จะไม่สามารถแก้ปัญหาข้ามเบราว์เซอร์ทั้งหมดของคุณได้อย่างน่าอัศจรรย์ ค้นหา stackoverflow สำหรับ jQuery และ IE คุณจะพบปัญหามากมาย ดีที่สุดในการเรียนรู้การเขียนสคริปต์ข้ามเบราว์เซอร์ด้วยตัวคุณเองดังนั้นเมื่อ jQuery หรือหนึ่งในปลั๊กอินร่างนับพันล้านล้มเหลวคุณจะสามารถใช้โซลูชันข้ามเบราว์เซอร์ที่ใช้งานได้จริงและรู้ว่ามันใช้งานได้และทำไม
Dagg Nabbit

11
+1 ไม่มีความคิดเห็นด้านบน คุณไกลกว่าที่จะหลีกเลี่ยง jQuery โดยสิ้นเชิง IFF คุณกำลังเรียนรู้ javascript - jQuery มีประโยชน์อย่างเหลือเชื่อหากคุณต้องการทำสิ่งที่ซับซ้อนให้เสร็จอย่างรวดเร็วและง่ายดาย แต่ถ้าคุณกำลังเรียนรู้มันจะป้องกันคุณจากความซับซ้อนในการทำความเข้าใจว่าจาวาสคริปต์เป็นอย่างไร ใช้งานได้ - หลายคนดูเหมือนจะรู้จัก jQuery แต่ยังไม่มีเบาะแสวิธีการเขียนจาวาสคริปต์ คุณไม่ได้ทำผิดที่ไม่ได้สร้าง jQuery มา แต่เดิมตอนนี้คุณมีความเข้าใจเกี่ยวกับโค้ดของคุณเองดีกว่าที่คุณมี
lucideer

คำตอบ:


121

โปรดอย่าลังเลที่จะอัปเดตรายการนี้หากคุณพบข้อผิดพลาด / การละเว้นอื่น ๆ

หมายเหตุ: IE9 แก้ไขปัญหาต่อไปนี้ได้หลายอย่างดังนั้นส่วนใหญ่จึงใช้ได้กับ IE8 และต่ำกว่าเท่านั้นและ IE9 ในระดับหนึ่งในโหมดแปลก ๆ ยกตัวอย่างเช่น IE9 สนับสนุน SVG, <canvas>, <audio>และ<video>โดยกำเนิด แต่คุณต้องเปิดใช้งานโหมดการปฏิบัติตามมาตรฐานสำหรับพวกเขาจะสามารถใช้ได้


ทั่วไป:

  • ปัญหาเกี่ยวกับเอกสารที่โหลดบางส่วน:เป็นความคิดที่ดีที่จะเพิ่ม JavaScript ของคุณในwindow.onloadเหตุการณ์ที่คล้ายกันเนื่องจาก IE ไม่รองรับการทำงานจำนวนมากในเอกสารที่โหลดบางส่วน

  • แอตทริบิวต์ที่แตกต่างกัน : ใน CSS elm.style.styleFloatอยู่ใน IE เทียบกับelm.style.cssFloatใน Firefox ใน<label>แท็กforแอตทริบิวต์ถูกเข้าถึงด้วยelm.htmlForใน IE เทียบกับelm.forใน Firefox โปรดทราบว่าforสงวนไว้ใน IE ดังนั้นจึงelm['for']เป็นความคิดที่ดีกว่าที่จะหยุด IE จากการเพิ่มข้อยกเว้น


ภาษา JavaScript พื้นฐาน:

  • เข้าถึงอักขระในสตริง : 'string'[0]ไม่รองรับใน IE เนื่องจากไม่อยู่ในข้อกำหนดดั้งเดิมของ JavaScript ใช้'string'.charAt(0)หรือ'string'.split('')[0]สังเกตว่าการเข้าถึงรายการในอาร์เรย์นั้นเร็วกว่าการใช้charAtกับสตริงใน IE อย่างมาก (แม้ว่าจะมีค่าใช้จ่ายเริ่มต้นเมื่อsplitถูกเรียกครั้งแรกก็ตาม)

  • จุลภาคก่อนจุดสิ้นสุดของวัตถุ:เช่น{'foo': 'bar',}ไม่อนุญาตให้ใช้ใน IE


ปัญหาเฉพาะองค์ประกอบ:

  • การรับdocumentIFrame :

    • Firefox และ IE8 +: IFrame.contentDocument (IE เริ่มรองรับสิ่งนี้ตั้งแต่เวอร์ชัน 8 )
    • IE: IFrame.contentWindow.document
    • ( IFrame.contentWindowหมายถึงwindowในเบราว์เซอร์ทั้งสอง)

  • Canvas:เวอร์ชันของ IE ก่อน IE9 ไม่รองรับ<canvas>องค์ประกอบนี้ IE รองรับVMLซึ่งเป็นเทคโนโลยีที่คล้ายคลึงกันและexplorercanvasสามารถจัดเตรียม wrapper ในตำแหน่งสำหรับ<canvas>องค์ประกอบสำหรับการดำเนินการต่างๆ โปรดทราบว่า IE8 ในโหมดการปฏิบัติตามมาตรฐานนั้นช้ากว่าหลายเท่าและมีข้อบกพร่องมากกว่าเมื่ออยู่ในโหมดแปลก ๆ เมื่อใช้ VML

  • SVG: IE9 รองรับ SVG โดยกำเนิด IE6-8 สามารถรองรับ SVG ได้ แต่เฉพาะกับปลั๊กอินภายนอกที่มีปลั๊กอินบางตัวเท่านั้นที่รองรับการจัดการ JavaScript

  • <audio>และ<video>:รองรับเฉพาะใน IE9

  • การสร้างปุ่มตัวเลือกแบบไดนามิก: IE <8 มีจุดบกพร่องซึ่งทำให้ปุ่มตัวเลือกที่สร้างขึ้นโดยไม่สามารถdocument.createElementเลือกได้ ดูเพิ่มเติมคุณสร้างปุ่มตัวเลือกแบบไดนามิกใน Javascript ที่ทำงานในทุกเบราว์เซอร์ได้อย่างไร เพื่อหาวิธีแก้ปัญหานี้

  • ฝังตัว JavaScript ใน<a href>แท็กและonbeforeunloadความขัดแย้งใน IE:หากมีการฝัง JavaScript ในhrefส่วนหนึ่งของaแท็ก (เช่น<a href="javascript: doStuff()">นั้นเสมอ IE จะแสดงข้อความกลับมาจากonbeforeunloadเว้นแต่onbeforeunloadจัดการจะถูกลบออกก่อนดูเพิ่มเติม. ขอยืนยันเมื่อปิดแท็บ

  • <script>ความแตกต่างของเหตุการณ์แท็ก: onsuccessและonerrorไม่ได้รับการสนับสนุนใน IE และถูกแทนที่ด้วย IE-specific onreadystatechangeซึ่งจะเริ่มทำงานไม่ว่าการดาวน์โหลดจะสำเร็จหรือล้มเหลว ดูJavaScript Madnessสำหรับข้อมูลเพิ่มเติม


ขนาดองค์ประกอบ / ตำแหน่ง / การเลื่อนและตำแหน่งเมาส์:

  • การรับขนาด / ตำแหน่งขององค์ประกอบ: ความกว้าง / ความสูงขององค์ประกอบบางครั้งelm.style.pixelHeight/Widthอยู่ใน IE มากกว่าelm.offsetHeight/Widthแต่ก็ไม่น่าเชื่อถือใน IE โดยเฉพาะอย่างยิ่งในโหมดนิสัยใจคอและบางครั้งก็ให้ผลลัพธ์ที่ดีกว่าอีกองค์ประกอบหนึ่ง

    elm.offsetTopและelm.offsetLeftมักจะได้รับการรายงานที่ไม่ถูกต้องซึ่งนำไปสู่การค้นหาตำแหน่งขององค์ประกอบที่ไม่ถูกต้องซึ่งเป็นสาเหตุที่ทำให้องค์ประกอบป๊อปอัปและอื่น ๆ ปิดพิกเซลเพียงไม่กี่พิกเซลในหลาย ๆ กรณี

    นอกจากนี้ยังทราบว่าถ้าเป็นองค์ประกอบ (หรือผู้ปกครองขององค์ประกอบหนึ่ง) มีdisplayของnoneแล้ว IE จะเพิ่มข้อยกเว้นเมื่อมีการเข้าถึงขนาด / ตำแหน่งแอตทริบิวต์แทนที่จะกลับ0เป็น Firefox ไม่

  • รับขนาดหน้าจอ (รับพื้นที่ดูได้ของหน้าจอ):

    • Firefox: window.innerWidth/innerHeight
    • โหมดมาตรฐาน IE: document.documentElement.clientWidth/clientHeight
    • IE quirks โหมด: document.body.clientWidth/clientHeight

  • ตำแหน่งเลื่อนเอกสาร / ตำแหน่งเมาส์ : อันนี้ไม่ได้กำหนดโดย w3c จริง ๆ ดังนั้นจึงไม่ได้มาตรฐานแม้แต่ใน Firefox ในการค้นหาscrollLeft/ scrollTopของdocument:

    • Firefox และ IE ในโหมด quirks: 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];
      };

    เพื่อให้ได้ตำแหน่งของเคอร์เซอร์ของเมาส์evt.clientXและevt.clientYในmousemoveเหตุการณ์ต่างๆจะให้ตำแหน่งที่สัมพันธ์กับเอกสารโดยไม่ต้องเพิ่มตำแหน่งเลื่อนดังนั้นจึงต้องรวมฟังก์ชันก่อนหน้านี้ไว้ด้วย:

    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]];
     };
    };

การเลือก / ช่วง:

  • <textarea>และ<input>เลือก : selectionStartและselectionEndไม่ได้ดำเนินการใน IE และมีกรรมสิทธิ์ "ช่วง" ระบบในสถานที่ที่เห็นตำแหน่งของแป้นพิมพ์ใน textarea ในตัวละครจากจุดเริ่มต้น

  • รับข้อความที่เลือกในปัจจุบันในเอกสาร:

    • Firefox: 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;
     };
    };

ปัญหาเกี่ยวกับการอ่าน 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;
      };
     };
    };

    นอกจากนี้ทราบว่า IE ต้องเพิ่ม<tbody>ไป<table>ก่อนที่จะต่อท้าย<tr>เพื่อที่<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

ความแตกต่างของเหตุการณ์:

  • การรับeventตัวแปร:เหตุการณ์ DOM จะไม่ถูกส่งไปยังฟังก์ชันใน IE และสามารถเข้าถึงได้ในรูปแบบwindow.event. วิธีหนึ่งในการรับเหตุการณ์คือการใช้เช่น
    elm.onmouseover = function(evt) {evt = evt||window.event}
    ซึ่งเป็นค่าเริ่มต้นwindow.eventหากevtไม่ได้กำหนดไว้

  • ความแตกต่างของรหัสเหตุการณ์สำคัญ:รหัสเหตุการณ์สำคัญแตกต่างกันไปอย่างมากแม้ว่าคุณจะดูQuirksmodeหรือJavaScript 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 clickและdblclickเหตุการณ์ในฟังก์ชัน Firefox จะยิงclickเช่นเดียวกับdblclickเมื่อดับเบิลคลิกดังนั้นการตรวจจับเฉพาะ IE จึงจำเป็นต้องมีลักษณะการทำงานเหมือนกัน

  • ความแตกต่างในกรณีที่มีรูปแบบการจัดการ:ทั้งสองรูปแบบที่เป็นกรรมสิทธิ์ของ IE และ Firefox รุ่นการจัดการการสนับสนุนของเหตุการณ์ที่เกิดขึ้นมาจากด้านล่างขึ้นเช่นหากมีเหตุการณ์ในองค์ประกอบทั้งสองของ<div><span></span></div>เหตุการณ์ที่เกิดขึ้นแล้วจะเรียกในspan แล้วdivมากกว่าเพื่อที่พวกเขากำลัง ผูกไว้ถ้าใช้เช่นelm.onclick = function(evt) {}เดิม

    โดยทั่วไปเหตุการณ์ "จับภาพ" ได้รับการสนับสนุนใน Firefox และอื่น ๆ เท่านั้นซึ่งจะทริกเกอร์เหตุการณ์divนั้นตามลำดับspanจากบนลงล่าง IE มีelm.setCapture()และelm.releaseCapture()สำหรับการเปลี่ยนเส้นทางเหตุการณ์เมาส์จากเอกสารไปยังองค์ประกอบ ( elmในกรณีนี้) ก่อนที่จะประมวลผลเหตุการณ์อื่น ๆ แต่ก็มีปัญหาด้านประสิทธิภาพและปัญหาอื่น ๆ อีกหลายประการดังนั้นจึงควรหลีกเลี่ยง

    • Firefox:

      แนบ : 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

    • หยุดเช่นเหตุการณ์สำคัญจากการแทรกอักขระหรือหยุดการตรวจสอบช่องทำเครื่องหมาย:

      Firefox: evt.preventDefault()
      IE: evt.returnValue = false
      หมายเหตุ:เพียงแค่กลับมาfalseในkeydown, keypress, mousedown, mouseup, clickและresetยังจะป้องกันไม่ให้ค่าเริ่มต้น

    • รับองค์ประกอบที่ทำให้เกิดเหตุการณ์:

      Firefox: evt.target
      IE: evt.srcElement

    • ทำให้เคอร์เซอร์ของเมาส์ถูกย้ายออกจากองค์ประกอบ: evt.fromElementใน IE อยู่evt.targetใน Firefox หากอยู่ในonmouseoutเหตุการณ์อย่างอื่นevt.relatedTarget

    • การย้ายเคอร์เซอร์ของเมาส์ไปที่องค์ประกอบ: evt.toElementใน IE อยู่evt.relatedTargetใน Firefox หากอยู่ในonmouseoutเหตุการณ์อย่างอื่นevt.target

    • หมายเหตุ: evt.currentTarget (องค์ประกอบที่เหตุการณ์ถูกผูกไว้) ไม่มีค่าเทียบเท่าใน IE


12
มากมากรายการที่ดีมาก! ขอบคุณทุกคนที่อุดหนุน :)
cwap

26

ตรวจสอบเครื่องหมายจุลภาคเช่นสิ่งเหล่านี้หรือคล้ายกันหากมีในรหัสของคุณ

var o={
'name1':'value1',
'name2':'value2',
} 

เครื่องหมายจุลภาคสุดท้าย (ค่าต่อไปนี้ 2) จะถูกยอมรับโดย Firefox แต่ไม่ใช่ IE


1
บรรณาธิการที่ดีส่วนใหญ่ควรจับเรื่องนี้
SeanJA

1
+1 ฉันมีอันนี้บ่อยเกินไป
David V.

1
ฉันจะให้คุณ +10 ถ้าทำได้สิ่งนี้เกิดขึ้นกับฉันตลอดเวลา
Josh

โอ้และเพื่อเพิ่มความคิดเห็นของ @ SeanJA: ฉันเพิ่งเปลี่ยนไปใช้ NetBeans ซึ่งจับสิ่งนี้ได้
Josh

ฉันเสียเวลาไปหลายชั่วโมงกับเรื่องนี้ในครั้งแรกที่ฉันทำงาน JS ตอนนี้เป็นสิ่งแรกที่ฉันตรวจสอบ! คำสาปเส็งเคร็งการขยาย Textmate ทิ้งลูกน้ำไว้รอบ ๆ
Agos

12

หากคุณยึดติดกับการใช้ jQuery หรือ YUI เมื่อโพสต์ของคุณถูกแท็กคุณควรมีความแตกต่างน้อยที่สุดระหว่างเบราว์เซอร์ ... นั่นคือสิ่งที่เป็นกรอบสำหรับดูแลความแตกต่างข้ามเบราว์เซอร์เหล่านี้ให้กับคุณ

ตัวอย่างเช่นดูที่หน้า traversal quirksmode DOMตามที่ IE ไม่รองรับสิ่งต่างๆส่วนใหญ่ ... ในขณะที่เป็นจริงเฟรมเวิร์กทำเช่น IE ไม่รองรับelem.childElementCountแต่ใน jQuery: $(elem).children().size()ทำงานเพื่อรับค่านี้ ในทุกเบราว์เซอร์ คุณจะพบว่ามีบางอย่างในไลบรารีเพื่อจัดการ 99% ของกรณีที่ไม่รองรับในเบราว์เซอร์อย่างน้อยก็ด้วยสคริปต์ ... ด้วย CSS คุณอาจต้องย้ายไปที่ปลั๊กอินสำหรับไลบรารีตัวอย่างทั่วไปของสิ่งนี้คือการทำให้มุมโค้งมน ทำงานใน IE ... เนื่องจากไม่มีการรองรับ CSS สำหรับสิ่งนี้

อย่างไรก็ตามหากคุณเริ่มทำสิ่งต่างๆโดยตรงเช่นแสดงdocument.XXX(thing)ว่าคุณไม่ได้อยู่ในไลบรารีคุณกำลังทำจาวาสคริปต์โดยตรง (เป็นจาวาสคริปต์ทั้งหมด แต่คุณได้รับประเด็น :) และสิ่งนี้อาจทำให้เกิดปัญหาหรือไม่ขึ้นอยู่กับว่า เมาทีม IE คือเมื่อใช้ฟังก์ชันนั้น

ด้วย IE คุณมีแนวโน้มที่จะล้มเหลวในการจัดแต่งทรงผมออกมาทางขวามากกว่าปัญหาจาวาสคริปต์ดิบ, ภาพเคลื่อนไหวไม่กี่พิกเซลออกและจัดเรียงของสิ่งนั้นมากมากขึ้นดังนั้นใน IE6 แน่นอน


ฉันเข้าใจดีขึ้นแล้ว ใช่ฉันทำสิ่งนั้นโดยตรงด้วย karlthorwald
user89021

1
หากคุณใช้ IDE เช่น Netbeans คุณสามารถตั้งค่าเบราว์เซอร์เป้าหมายสำหรับจาวาสคริปต์ของคุณได้และยังช่วยเตือนคุณเมื่อคุณทำสิ่งที่ดูเหมือนจะไม่ได้รับการสนับสนุน
SeanJA

10

getElementbyID จะจับคู่กับแอตทริบิวต์ name ใน IE ด้วย แต่ไม่ใช่เบราว์เซอร์อื่นและ 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

3
ขอโทษที่หยาบคาย แต่ IE น่าเกลียดจริงๆ
user89021

12
document.getElementByIdOrNameIGuessWhateverMan (id);
JulianR

5

มีหลายสิ่งหลายอย่าง แต่กับดักอย่างหนึ่งที่ฉันเคยตกหลุมคือเบราว์เซอร์จำนวนมากยอมรับ JSON โดยไม่มีชื่อที่ยกมาในขณะที่ ie6 และ ie7 ไม่ทำ

{ name: "Jakob" } // will often work, but not in ie6/ie7
{ "name": "Jakob" } // Better!

แก้ไข : เพื่อชี้แจงว่านี่เป็นเพียงปัญหาเมื่อจำเป็นต้องใช้ JSON จริงซึ่งตรงข้ามกับอ็อบเจ็กต์ลิเทอรัล JSON เป็นชุดย่อยของไวยากรณ์ตัวอักษรของออบเจ็กต์และหมายถึงรูปแบบการแลกเปลี่ยนข้อมูล (เช่น XML) ซึ่งเป็นเหตุผลว่าทำไมจึงออกแบบมาให้เลือกได้


2
โปรดทราบว่าสิ่งนี้ขึ้นอยู่กับบริบทออบเจ็กต์ลิเทอรัลใช้ได้ดี JSON ไม่ใช่ ... แต่ตัวอย่างเช่น jQuery ไม่อนุญาตให้ใช้ JSON ที่ไม่ถูกต้องเลยในรีลีสล่าสุด
Nick Craver

ไม่ใช่การลงคะแนนของฉัน ... แต่คุณควรชี้แจงให้คนอื่นเข้าใจแล้ว +1 จากฉัน
Nick Craver

5

การสนับสนุน JavaScript ที่แตกต่างกัน

IE ไม่รองรับ (ส่วนใหญ่) ส่วนขยายที่เพิ่มใน JavaScript ตั้งแต่ 1.5

ใหม่ใน 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


1
JavaScript ที่คุณกำลังพูดถึงที่นี่คือ JavaScript (TM) ของ mozilla ไม่ใช่ javascript ในความหมายทั่วไป ไม่ควรใช้ ECMAScript ทั้งหมด / เอ็นจิน javascript (MS JScript ในกรณีนี้) ควรเป็นไปตาม JavaScript (TM) ของ mozilla ECMAScript เป็นมาตรฐานไม่ใช่ JavaScript (TM) และ JavaScript (TM) ไม่ใช่ javascript ฉันหวังว่ามันจะสมเหตุสมผล
Dagg Nabbit

มันสมเหตุสมผลสำหรับฉัน แต่ในเธรดเกี่ยวกับความเข้ากันได้ระหว่าง JavaScript และ JScript ฉันคิดว่าคงจะเข้าใจแล้ว :)
gnarf

เมื่อคุณพูดว่า "IE ไม่รองรับ (ส่วนใหญ่) ส่วนขยายที่เพิ่มลงใน JavaScript ตั้งแต่ 1.5" ดูเหมือนว่าคุณกำลังพูดว่า JavaScript (TM) ของ mozilla เป็นมาตรฐานที่ IE ควรปฏิบัติตามซึ่งแน่นอนว่าไม่ใช่ อย่างน้อยคุณอาจจะบอกว่าของ Mozilla JavaScript หรือเบราว์เซอร์ที่คล้ายกัน ... อื่น ๆ ไม่สนับสนุนส่วนขยายทั้งหมดของ Mozilla เพื่อ ECMAScript เช่น destructuring มอบหมาย ฯลฯ คำถามที่เป็นเรื่องเกี่ยวกับความแตกต่างระหว่าง 'ที่สุด' javascriptและ (การดำเนินงานที่เฉพาะเจาะจง) JScriptไม่แตกต่างระหว่างMozilla JavaScript(TM)และJScript. อาจจะดีกว่าถ้าแสดงว่า IE เบี่ยงเบนจาก ES ไปที่ใด
Dagg Nabbit

3

ความแตกต่างที่สำคัญระหว่าง JavaScript ใน IE และ JavaScript ในเบราว์เซอร์สมัยใหม่ (เช่น Firefox) อาจมาจากสาเหตุเดียวกันที่อยู่เบื้องหลังความแตกต่างของ CSS / (X) HTML cross-browser ย้อนกลับไปในวันนั้นไม่มีมาตรฐานโดยพฤตินัย IE / Netscape / Opera ต่อสู้กับสงครามสนามหญ้าโดยใช้ข้อกำหนดส่วนใหญ่ แต่ยังละเว้นบางอย่างรวมถึงการกำหนดคุณสมบัติเฉพาะเพื่อให้ได้เปรียบซึ่งกันและกัน ฉันสามารถพูดต่อไปได้ แต่ให้ข้ามไปที่การเปิดตัว IE8: JavaScript ถูกหลีกเลี่ยง / ดูถูกมาหลายปีและด้วยการเพิ่มขึ้นของ FF และการดูถูกของ webcomm IE เลือกที่จะมุ่งเน้นไปที่การพัฒนา CSS จาก IE6 เป็นส่วนใหญ่ และโดยพื้นฐานแล้วทิ้งการสนับสนุน DOM ไว้เบื้องหลัง การสนับสนุน DOM ของ IE8 อาจเป็นของ IE6 ซึ่งเปิดตัวในปี 2544 .... ดังนั้นการสนับสนุน DOM ของ IE จึงอยู่เบื้องหลังเบราว์เซอร์สมัยใหม่เกือบทศวรรษ หากคุณมีความคลาดเคลื่อนของ JavaScript โดยเฉพาะกับเลย์เอาต์เอ็นจิ้นคุณทางออกที่ดีที่สุดคือโจมตีด้วยวิธีเดียวกับที่เราแก้ไขปัญหา CSS กำหนดเป้าหมายเบราว์เซอร์นั้น อย่าใช้ BROWSER SNIFFING ให้ใช้การตรวจจับคุณสมบัติเพื่อดักจับเบราว์เซอร์ของคุณ / ระดับการรองรับ DOM

JScript ไม่ใช่การใช้งาน ECMAScript ของ IE เอง JScript เป็นคำตอบของ IE สำหรับ JavaScript ของ Netscape ซึ่งทั้งสองอย่างนี้เกิดขึ้นก่อน ECMAScript

สำหรับประเภทแอตทริบิวต์ในองค์ประกอบสคริปต์ type = "text / javascript" เป็นมาตรฐานเริ่มต้น (อย่างน้อยก็ใน HTML5) ดังนั้นคุณจึงไม่จำเป็นต้องมีแอตทริบิวต์ type เว้นแต่สคริปต์ของคุณจะไม่ใช่ JavaScript

เท่าที่ IE ไม่รองรับ innerHTML ... innerHTML ถูกคิดค้นโดย IE และทุกวันนี้ก็ยังไม่ใช่มาตรฐาน DOM เบราว์เซอร์อื่น ๆ ได้นำมาใช้เพราะมีประโยชน์ซึ่งเป็นเหตุผลที่คุณสามารถใช้งานข้ามเบราว์เซอร์ได้ สำหรับตารางที่มีการเปลี่ยนแปลงแบบไดนามิก MSDN กล่าวว่า "เนื่องจากโครงสร้างเฉพาะที่ตารางต้องการคุณสมบัติinnerTextและinnerHTMLของตารางและวัตถุ tr เป็นแบบอ่านอย่างเดียว" ฉันไม่รู้ว่าในตอนแรกนั้นเป็นจริงแค่ไหน แต่เห็นได้ชัดว่าเบราว์เซอร์สมัยใหม่ได้คิดออกในขณะที่จัดการกับความซับซ้อนของเค้าโครงตาราง

ฉันขอแนะนำให้อ่านPPK บน JavaScript DOM Scripting ของ Jeremy Keith JavaScriptของ Douglas Crockford : ส่วนที่ดี และJavaScript เริ่มต้นของ Christian Hellman ด้วย DOM Scripting และ Ajaxเพื่อให้เข้าใจ JavaScript อย่างชัดเจน

เท่าที่เกี่ยวข้องกับ Frameworks / Libraries หากคุณยังไม่เข้าใจ JavaScript อย่างชัดเจนคุณควรหลีกเลี่ยง 2 ปีที่แล้วฉันตกอยู่ในกับดัก jQuery และในขณะที่ฉันสามารถดึงเอาความสามารถที่ยอดเยี่ยมออกมาได้ แต่ฉันก็ไม่เคยเรียนรู้อะไรเกี่ยวกับการเข้ารหัส JavaScript อย่างถูกต้อง ในการมองย้อนกลับไป jQuery เป็น DOM Toolkit ที่น่ากลัว แต่ความล้มเหลวของฉันในการเรียนรู้การปิดที่เหมาะสมการสืบทอดต้นแบบ ฯลฯ ไม่เพียง แต่ทำให้ความรู้ส่วนตัวของฉันกลับมางานของฉันเริ่มได้รับความนิยมอย่างมากเพราะฉันไม่มีเงื่อนงำอะไรเลย

JavaScript เป็นภาษาของเบราว์เซอร์ หากคุณเป็นวิศวกรฝั่งไคลเอ็นต์ / ฟรอนต์เอนด์สิ่งสำคัญที่สุดคือคุณต้องสั่ง JavaScript Node.js นำ JavaScript แบบเต็มเอียงฉันเห็นความก้าวหน้าครั้งใหญ่ในการพัฒนาทุกวัน JavaScript ฝั่งเซิร์ฟเวอร์จะเป็นมาตรฐานในอนาคตอันใกล้นี้ ฉันกำลังพูดถึงสิ่งนี้เพื่อเน้นย้ำถึงความสำคัญของ JavaScript ในตอนนี้และจะเป็นอย่างไร

JavaScript จะสร้าง wave ได้มากกว่า Rails

Happy Scripting!


2
คำตอบที่ดีแม้ว่าฉันจะไม่เห็นด้วยกับการใช้การตรวจจับคุณสมบัติเพื่อดักจับเบราว์เซอร์ ใช้การตรวจจับคุณสมบัติเพื่อทดสอบการรองรับคุณสมบัติเหล่านั้นเท่านั้น นอกจากนี้ยังเห็นตัวอย่างในการตรวจสอบคุณสมบัติไม่ได้การตรวจสอบเบราว์เซอร์
Marcel Korpel

ฉัน. ฉันเห็นด้วยอย่างยิ่งกับความไม่เห็นด้วยของคุณ ขอบคุณที่จับได้ ฉันยังคงเป็น JavaScript n00b แต่เกมของฉันไม่มีความละอาย "การตรวจจับเบราว์เซอร์ที่ใช้คุณลักษณะเป็นแนวทางปฏิบัติที่ไม่ดีอย่างยิ่งที่ควรหลีกเลี่ยงโดยเสียค่าใช้จ่ายทั้งหมดการตรวจจับคุณลักษณะแบบตรงเป็นแนวทางปฏิบัติที่ดีที่สุดและในเกือบทุกกรณีคือสิ่งที่คุณต้องการ"
albert

2

ออบเจ็กต์เนทีฟบางตัวเป็นแบบอ่านอย่างเดียวโดยที่ดูเหมือนจะไม่เป็นเช่นนั้นจริงๆ (คุณสามารถเขียนถึงมันได้ แต่ไม่มีผลใด ๆ ) ตัวอย่างเช่นจาวาสคริปต์ขั้นสูงทั่วไปจะขึ้นอยู่กับการขยายElementออบเจ็กต์โดยการลบล้างเมธอดของระบบเช่นการเปลี่ยน Element.prototype.appendChild () เพื่อทำมากกว่าการต่อท้ายโหนดลูก - กล่าวเริ่มต้นด้วยข้อมูลของผู้ปกครอง สิ่งนี้จะล้มเหลวโดยไม่โต้ตอบใน IE6 - วิธีการเดิมจะถูกเรียกใช้กับวัตถุใหม่แทนที่จะเป็นวิธีใหม่

เบราว์เซอร์บางตัว (ตอนนี้ฉันจำไม่ได้แล้ว) ถือว่าการขึ้นบรรทัดใหม่ระหว่างแท็ก HTML เป็นโหนดข้อความในขณะที่บางเบราว์เซอร์ไม่ทำ ดังนั้น childNodes (n), nextSibling (), firstChild () และสิ่งที่คล้ายกันจะทำงานแตกต่างกันมาก


2

การลากเครื่องหมายจุลภาคในอาร์เรย์และตัวอักษรของวัตถุเคยเป็นปัญหาไม่ได้ตรวจสอบเมื่อเร็ว ๆ นี้ (หมายถึง IE8):

var a = [ 1, 2, 3, ];
var o = { a:1, b:2, c:3, };

สิ่งนี้จะทำให้เกิดรหัสพิเศษบางอย่างเมื่อสร้างโครงสร้างดังกล่าวฝั่งเซิร์ฟเวอร์


2

ฉันเพิ่งพบเมื่อเช้านี้เพื่อนร่วมงานคนหนึ่งตั้งแท็กสคริปต์เป็น: <script type="application/javascript">เพราะการเติมข้อความอัตโนมัติในอุดมคติของเขามีก่อน "text / javascript"

แต่ปรากฎว่า IE ไม่สนใจสคริปต์ทั้งหมดหากคุณใช้ "application / javascript" คุณต้องใช้ "text / javascript"


javascript เป็นค่าเริ่มต้นในทุกเบราว์เซอร์ดังนั้นให้ใช้<script>
Lauri

2

เมื่อวันก่อนฉันพบเรื่องแปลก ๆ แปลก ๆ กับ Internet Explorer ฉันใช้ YUI และแทนที่เนื้อหาของตัวตาราง () โดยการตั้งค่า innerHTML

Y.one('#elementId').set('innerHTML', '<tr><td>Column 1</td></tr>');

สิ่งนี้ใช้ได้กับทุกเบราว์เซอร์ยกเว้น IE ในที่สุดฉันก็ค้นพบว่าคุณไม่สามารถแทนที่ innerHTML ของตารางใน IE ได้ ฉันต้องสร้างโหนดโดยใช้ YUI แล้วต่อท้ายโหนดนั้น

var myNode = Y.node.create('<tr><td>Column 1</td></tr>');
Y.one('#elementId').append(myNode);

นั่นเป็นเรื่องสนุกที่จะคิดออก!


1
ฉันมีความรู้สึกว่าคุณต้องห่อด้วย<tbody>แท็ก
Casey Chu

ในโค้ดดั้งเดิมมันถูกรวมไว้ในแท็ก <tbody> มันยังคงทำให้ฉันคิดว่า IE ไม่ชอบ ฉันจำได้ว่าอ่านในเอกสารอย่างเป็นทางการของ Microsoft แต่ตอนนี้ฉันหาลิงค์ไม่เจอ ขออภัย!
Justin

1

เครื่องหมายจุลภาคพิเศษและเครื่องหมายจุลภาคที่ขาดหายไปเคยเป็นปัญหาปกติใน IE ในขณะที่ทำงานได้อย่างราบรื่นบน FF


1

IE เข้มงวดมากเกี่ยวกับการหายไป ";" ก็มักจะเป็นเช่นนั้น


ฉันพบสิ่งเหล่านี้มากมายในขณะที่ฉันกำลัง jsLinting อยู่ ดูเหมือนจะเป็นจุดสำคัญ
user89021

1

สำหรับสิ่งที่คุ้มค่าฉันเพิ่งเจอปัญหาที่น่ารังเกียจนี้ใน <IE9

บอกว่าคุณมี html แบบนี้:

<table><tr><td>some content...</td></tr></table>

และด้วยเหตุผลบางอย่าง (ฉันมีดี) คุณต้องดึง HTML ทั้งหมดในตารางก่อนปิด TR ครั้งสุดท้ายคุณอาจลองทำสิ่งนี้:

var tableHtml = document.getElementById('thetable').innerHTML;
var fragment = tableHtml.substring(0, tableHtml.lastIndexOf('</tr>'));

<IE9 จะไม่คืนค่าอะไรเลย (-1) ที่นี่เนื่องจากตัวแปร tableHtml มีแท็ก html ทั้งหมดที่อยู่ด้านบนและ lastIndexOf เป็นกรณีที่คำนึงถึงตัวพิมพ์เล็กและใหญ่ ในการหลีกเลี่ยงสิ่งนี้ฉันต้องโยน toLowerCase () ก่อน lastIndexOf



0

คุณพูดถึง jQuery ซึ่งฉันไม่ค่อยคุ้นเคย แต่สำหรับการอ้างอิงทั่วไปและโดยเฉพาะกับ Prototype สิ่งหนึ่งที่ต้องระวังคือคำสงวน / ชื่อวิธีการใน IE ฉันรู้ว่าสิ่งที่ทำให้ฉันมักจะเป็นเช่น:

someElement.appendChild(new Element('label',{ **for**: someInput.id }).update( someLabelText );

(องค์ประกอบใหม่ (tagName, propertyHash) คือการสร้างองค์ประกอบใหม่ใน Protitype) ใน IE for:ต้องเป็น'for':เพราะforเป็นคำสงวน ซึ่งสมเหตุสมผล - แต่ FireFox จะทนต่อสิ่งนี้

ตัวอย่างอื่น:

someElement.wrap('div').addClassName('someClass')

( wrapวิธีการใน Prototype จะรวมองค์ประกอบหนึ่งไว้ในอีกองค์ประกอบหนึ่ง) - ใน IE บน textareas wrapเป็นคุณสมบัติและElement.wrap()ต้องใช้แทนเวอร์ชันวิธีการ

นี่คือสองตัวอย่างที่อยู่ในใจจากประสบการณ์ของฉัน พวกเขาขึ้นอยู่กับต้นแบบ แต่ปัญหาหลักไม่ใช่: ระวังวิธีการ / ป้ายกำกับ / ตัวระบุใด ๆ ที่ IE พิจารณาคำสงวน แต่ FireFox หรือ Safari จะยอม


0

ความจริงก็คือ IE ไม่รองรับ JavaScript ... มันสนับสนุนการใช้งาน ECMAScript: JScript ของเขาเอง ... ซึ่งแตกต่างกัน ...


0

การใช้console.log()เพื่อแสดงข้อผิดพลาดไปยังคอนโซลข้อผิดพลาดของ Firefox จะทำให้สคริปต์ของคุณล้มเหลวใน IE อย่าลืมนำสิ่งเหล่านั้นออกไปเมื่อคุณทดสอบใน IE


ฉันเชื่อว่าการใช้ console.log จะล้มเหลวแม้ใน Firefox หากคุณไม่ได้เปิด FireBug
ejel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.