Firefox에서 개발 된 Javascript가 IE에서 실패하는 일반적인 이유는 무엇입니까? [닫은]


108

최근 Firefox와 Safari에서 잘 실행되는 자바 스크립트 강화 페이지를 개발했습니다. Internet Explorer에서 확인하는 것을 놓 쳤고 이제 IE 6 및 7 (지금까지)에서 페이지가 작동하지 않습니다. 스크립트는 어떻게 든 실행되지 않고 일부 javascript가 실행되지만 페이지는 javascript가없는 것처럼 표시됩니다. dom 조작이있는 자체 라이브러리를 사용하고 있습니다. YUI 2에서 YUI-Loader와 XML-Http-Request를 사용하고 한 페이지에서 JQuery에 따라 "psupload"를 사용합니다.

Office XP에서 Microsoft Script Editor를 설치 중이며 이제 디버그합니다. 이제 구체적인 테스트도 작성하겠습니다.

IE의 일반적인 실패 지점은 무엇입니까? 내 눈을 뜨고있을 수있는 방향.

몇 가지 차이점을 보여주는이 페이지를 찾았습니다. 방문 : Quirksmode

당신의 경험을 통해 내가 먼저 찾아야 할 몇 가지 전형적인 것들을 말할 수 있습니까?

또한 나중에 특정 작업에 대해 여기에서 더 많은 질문을 할 것이지만 지금은 Firefox에서 정상적으로 실행되는 스크립트에서 IE가 일반적으로 실패하는 이유에 관심이 있습니다.

편집 : 모든 훌륭한 답변에 감사드립니다!

그 동안 Internet Explorer에서도 작동하도록 전체 코드를 조정했습니다. 이제 jQuery를 통합하고 그 위에 자체 클래스를 구축했습니다. 이것은 처음부터 jQuery에 모든 것을 구축하지 않은 기본적인 실수였습니다. 지금 나 한테있어.

또한 JSLint는 저를 많이 도왔습니다.

그리고 다른 답변의 많은 단일 문제가 도움이되었습니다.


이전 코딩에서 알 수 있듯이 지금까지 CSS 또는 스타일링에는 문제가 없습니다. JS 문제 만-karlthorwald
user89021 2010

1
먼저 모든 파일에 대해 JSLint를 먼저 실행할 것입니다.
user89021 2010

7
"처음부터 jQuery에 모든 것을 구축하지 않았다는 기본적인 실수였습니다." -브라우저 간 문제를 모두 마술처럼 해결하지는 못합니다. jQuery 및 IE에 대한 stackoverflow를 검색하면 수많은 문제를 찾을 수 있습니다. 크로스 브라우저 스크립팅을 직접 배우는 것이 가장 좋습니다. 그러면 jQuery 또는 수십억 개의 스케치 플러그인 중 하나가 실패 할 때 실제 작동하는 크로스 브라우저 솔루션을 구현할 수 있고 작동하는 이유와 그 이유를 알 수 있습니다.
Dagg Nabbit

11
+1 위의 댓글 없음. jQuery를 완전히 피하는 것이 훨씬 낫습니다. 자바 스크립트를 배우는 중입니다. 복잡한 작업을 빠르고 쉽게 수행하려는 경우 jQuery가 매우 유용하지만 실제로 자바 스크립트를 이해하는 복잡성으로부터 보호 할 수 있습니다. 작동합니다-너무 많은 사람들이 jQuery를 알고있는 것 같지만 자바 스크립트를 작성하는 방법에 대한 단서가 없습니다. 원래 jQuery에서 빌드하지 않은 실수를 한 것이 아닙니다. 이제 자신이 가지고있는 것보다 자신의 코드를 훨씬 더 잘 이해할 수 있습니다.
lucideer 2010-07-24

답변:


121

오류 / 누락 등이 있으면이 목록을 업데이트하십시오.

참고 : IE9는 다음과 같은 많은 문제를 해결하므로이 중 상당수는 IE8 이하 및 쿼크 모드의 IE9에만 적용됩니다. 예를 들어, IE9는 SVG를 지원 <canvas>, <audio>그리고 <video>기본적으로, 그러나 당신이해야한다 표준 준수 모드를 활성화 그들이 사용할 수에 대한.


일반:

  • 부분적으로로드 된 문서의 문제 :window.onload IE는 부분적으로로드 된 문서에서 많은 작업을 지원하지 않으므로 JavaScript를 또는 유사한 이벤트 에 추가하는 것이 좋습니다 .

  • 다른 속성 : CSS에서는 elm.style.styleFloatIE와 elm.style.cssFloatFirefox에 있습니다. 에 <label>태그 for속성에 액세스 할 수 elm.htmlForIE에 대 elm.forFirefox에서. 참고 forIE에 예약되어 있습니다 그래서 elm['for']아마 예외를 발생에서 IE를 막을 수있는 더 좋은 생각이다.


기본 JavaScript 언어 :

  • 문자열의 문자 액세스 : 'string'[0]원래 JavaScript 사양이 아니기 때문에 IE에서는 지원되지 않습니다. 사용 '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.)

  • 캔버스 : IE9 이전 버전의 IE는 <canvas>요소를 지원하지 않습니다 . IE는 유사한 기술인 VML 을 지원 하지만 explorercanvas<canvas>많은 작업을 위한 요소에 대한 내부 래퍼를 제공 할 수 있습니다 . 표준 준수 모드의 IE8은 VML을 사용할 때 쿼크 모드에있을 때보 다 몇 배 더 느리고 결함이 더 많습니다.

  • SVG : IE9는 기본적으로 SVG를 지원합니다. IE6-8은 SVG를 지원할 수 있지만 JavaScript 조작을 지원하는 일부 플러그인 만있는 외부 플러그인 에서만 가능합니다.

  • <audio><video>: IE9에서만 지원됩니다.

  • 라디오 버튼을 동적으로 생성 : IE <8에는 라디오 버튼을 document.createElement체크 할 수 없게 만드는 버그가 있습니다. 참조 동적으로 모든 브라우저에서 작동하는 자바 스크립트의 라디오 버튼을 만들려면 어떻게해야합니까? 이 문제를 해결할 수있는 방법이 있습니다.

  • <a href>태그에 포함 된 JavaScript 및 onbeforeunloadIE의 충돌 : 태그 의 href일부에 포함 된 JavaScript가있는 경우 a(예 : 핸들러가 미리 제거 되지 않는 <a href="javascript: doStuff()">한 IE는 항상 반환 된 메시지를 표시합니다 . 탭을 닫을 때 확인 요청을 참조 하십시오 .onbeforeunloadonbeforeunload

  • <script>태그 이벤트의 차이는 : onsuccessonerrorIE에서 지원되지 않습니다와 IE 전용으로 대체됩니다 onreadystatechange에 관계없이 다운로드가 성공 또는 실패 여부에 발생합니다. 자세한 내용은 JavaScript Madness 를 참조하십시오.


요소 크기 / 위치 / 스크롤 및 마우스 위치 :

  • 요소 크기 / 위치 가져 오기 : 요소의 너비 / 높이는 때때로 elm.style.pixelHeight/WidthIE가 아닌 IE elm.offsetHeight/Width에 있지만 IE, 특히 쿼크 모드에서는 신뢰할 수 없으며 때로는 하나가 다른 것보다 더 나은 결과를 제공합니다.

    elm.offsetTop그리고 elm.offsetLeft종종 잘못보고되어 요소의 위치가 잘못된 것을 발견하게되는데, 이것이 팝업 요소 등이 많은 경우에 몇 픽셀 떨어져있는 이유입니다.

    또한, 요소 (또는 요소의 부모)가있는 경우 참고 displaynone한 다음 크기 / 위치 특성을 액세스하는 대신 복귀시 IE가 예외를 발생시킬 것이다 0파이어 폭스처럼.

  • 화면 크기 가져 오기 ( 화면 의 가시 영역 가져 오기) :

    • Firefox : window.innerWidth/innerHeight
    • IE 표준 모드 : document.documentElement.clientWidth/clientHeight
    • IE 쿼크 모드 : document.body.clientWidth/clientHeight

  • 문서 스크롤 위치 / 마우스 위치 : 이것은 실제로 w3c에 의해 정의되지 않았으므로 Firefox에서도 표준이 아닙니다. 찾기하려면 scrollLeft/ scrollTop의를 document:

    • 쿼크 모드의 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];
      };

    위해서는 마우스 커서의 위치를 얻기 위해, 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>선택 : selectionStartselectionEndIE에서 구현하고, 또한 참조 그 자리에 독점 "범위"시스템 거기되지 않습니다 처음부터 문자, 텍스트 영역에 캐럿 위치 .

  • 문서에서 현재 선택된 텍스트 가져 오기 :

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


ID로 요소 가져 오기 :

  • document.getElementById또한 name양식 의 속성을 참조 할 수도 있습니다 (문서에서 처음 정의 된 항목에 따라 다름). 따라서 동일한 name및 을 갖는 다른 요소를 사용하지 않는 것이 가장 좋습니다 id. 이것은 idw3c 표준이 아니었던 시절로 거슬러 올라갑니다 . document.all( 독점적 인 IE 특정 속성 )은보다 훨씬 빠르지 만 이전에 document.getElementById항상 우선 순위를 정하기 때문에 다른 문제가 있습니다 . 저는 개인적으로이 코드를 사용하고, 확인하기 위해 추가 검사를합니다.nameid

    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 는를 사용하여 만들 때 해당 요소에 s를 추가하기 전에 <tbody>에 a <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에서 그들을 피하기 위해 아마 가장 좋습니다. 더 신뢰할 수있는 방법은을 얻을 수 offsetXoffsetYIE에서하는 것 위치 얻을 상대적 위치 요소와에서 빼기 clientXclientY.

      또한 IE에서 click이벤트를 두 번 클릭 하려면 a clickdblclick이벤트를 함수에 모두 등록해야 합니다. 두 번 클릭 할 때 click와 마찬가지로 Firefox가 실행 dblclick되므로 동일한 동작을 유지하려면 IE 별 감지가 필요합니다.

  • 경우에 차이가 모델을 처리 : 이있는 경우 독점 IE 모델과 아래에서 위로 이벤트의 파이어 폭스 모델 지원 처리 모두를, 예를 들어, 두 요소의 이벤트 <div><span></span></div>다음 이벤트는에 트리거 span 다음div 들이있어보다는 순서를 전통적인 예가 elm.onclick = function(evt) {}사용 된 경우 바인딩 됩니다.

    "캡처"이벤트는 일반적으로 단지 트리거하는 등 파이어 폭스에서 지원됩니다 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에 추가 될 수 있습니다. 동일한 유형의 이벤트가 둘 이상 추가되면 예외가 발생합니다. 또한 이벤트 함수에서 바인딩 된 요소 thiswindow아닌 참조를 참조 하므로 유용하지 않습니다.

      첨부 : 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, clickreset도 기본을 방지 할 수 있습니다.

    • 이벤트를 트리거 한 요소를 가져옵니다.

      Firefox : evt.target
      IE : evt.srcElement

    • 마우스 커서가 멀어지는 요소 가져 오기 : 이벤트에 있으면 evt.fromElementIE evt.target에서 Firefox에 onmouseout, 그렇지 않으면evt.relatedTarget

    • 마우스 커서가 이동 한 요소 가져 오기 : 이벤트에 있으면 evt.toElementIE evt.relatedTarget에서 Firefox에 onmouseout, 그렇지 않으면evt.target

    • 참고 : evt.currentTarget (이벤트가 바인딩 된 요소) IE에는 해당 요소가 없습니다.


12
아주, 아주, 아주 좋은 목록! :) 기여 모두에게 감사합니다
cwap

26

코드에 이와 유사한 쉼표가 있는지도 확인하십시오.

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

마지막 쉼표 (다음 값 2)는 Firefox에서 허용되지만 IE에서는 허용되지 않습니다.


1
대부분의 훌륭한 편집자는 이것을 잡을 것입니다
SeanJA 2010

1
+1, 나는 이것을 너무 자주 받았습니다.
David V.

1
할 수만 있다면 +10을 드리겠습니다.
Josh

아 그리고 @SeanJA의 의견에 추가하려면 : 나는 최근에 이것을 잡는 NetBeans로 전환했습니다.
Josh

처음 JS 작업을 할 때 너무 많은 시간을 잃었습니다. 이제 제가 가장 먼저 확인하는 것이 있습니다! 쉼표를 남기고 엉뚱한 Textmate 확장을 저주하십시오.
Agos 2010-06-09

12

게시물에 태그가 지정 될 때 jQuery 또는 YUI를 사용하는 경우 브라우저간에 최소한의 차이가 있어야합니다 ... 그것이 이러한 브라우저 간 차이점을 처리하기위한 프레임 워크입니다.

예를 들어 quirksmode DOM traversal page를 보세요. IE는 대부분의 것을 지원하지 않습니다. 사실이지만 프레임 워크는 예를 들어 IE가 지원하지 않지만 elem.childElementCountjQuery $(elem).children().size()에서는이 값을 가져옵니다. 모든 브라우저에서. 적어도 스크립트를 사용하여 브라우저 전체에서 지원되지 않는 케이스의 99 %를 처리 할 수있는 라이브러리가 있음을 알 수 있습니다 .CSS를 사용하면 라이브러리 용 플러그인으로 이동해야 할 수 있습니다. IE에서 작업하는 것은 CSS 지원이 없기 때문입니다.

그러나, 같은 일을 직접 시작 document.XXX(thing)하면 라이브러리에 있지 않고 직접 자바 스크립트를 수행하고 있습니다 (모두 자바 스크립트이지만 요점을 얻습니다 :).이 방법에 따라 문제가 발생할 수도 있고 그렇지 않을 수도 있습니다. IE 팀은 특정 기능을 구현할 때 취했습니다.

IE를 사용하면 원시 자바 스크립트 문제, 애니메이션이 몇 픽셀 떨어져있는 것보다 올바르게 나오는 스타일링에 실패 할 가능성이 더 높습니다 . 물론 IE6 에서는 훨씬 더 그렇습니다.


이제 더 잘 이해합니다. 예, 저도 직접 그런 일을했습니다. karlthorwald
user89021 2010

1
Netbeans와 같은 IDE를 사용하는 경우 자바 스크립트의 대상 브라우저를 설정할 수 있으며 지원되지 않는 것으로 보이는 작업을 수행 할 때 경고하여 도움이됩니다.
SeanJA 2010

10

getElementbyID는 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는 정말 못
생겼습니다

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는 1.5 이후 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 에서 실행하기 전까지는 그다지 큰 문제가 아닌 것 같습니다.


1
여기서 말하는 자바 스크립트는 좀 더 일반적인 의미의 자바 스크립트가 아니라 모질라의 자바 스크립트 (TM)입니다. 모든 ECMAScript 구현 / JavaScript 엔진 (이 경우 MS JScript)이 mozilla의 JavaScript (TM)를 따라야하는 것은 아닙니다. ECMAScript는 JavaScript (TM)가 아닌 표준이며 JavaScript (TM)는 javascript가 아닙니다. 이해가 되셨기를 바랍니다.
Dagg Nabbit

나에게는 이해가되지만 JavaScript와 JScript 간의 호환성에 대한 스레드에서 이미 이해 될 것이라고 생각했습니다. :)
gnarf

"IE는 1.5 이후 JavaScript에 추가 된 확장을 (대부분) 지원하지 않습니다."라고 말하면 Mozilla의 JavaScript (TM)가 IE가 준수해야하는 표준이라고 말하는 것처럼 들립니다. 물론 그렇지 않은 경우에도 마찬가지입니다. 당신은 적어도 문제는 '가장'의 차이점에 대해이었다 모질라의 자바 스크립트 또는 유사한 ... 다른 브라우저 등의 과제를 destructuring처럼 ECMAScript를에 모질라의 확장을 지원하지 않는 말할 수 javascript및 (특정 구현) JScript,하지의 차이 Mozilla JavaScript(TM)JScript. IE가 ES에서 벗어나는 위치를 표시하는 것이 더 나을 수 있습니다.
Dagg Nabbit

3

IE의 JavaScript와 최신 브라우저 (예 : Firefox)의 JavaScript 간의 주요 차이점은 CSS / (X) HTML 크로스 브라우저의 차이점 뒤에있는 동일한 이유 때문일 수 있습니다. 과거에는 사실상의 표준이 없었습니다. IE / Netscape / Opera는 대부분의 사양을 구현하면서 영역 전쟁을 벌였지 만 일부를 생략하고 서로의 이점을 얻기 위해 독점 사양을 만들었습니다. 나는 길게 계속할 수 있지만 IE8의 릴리스로 건너 뛰도록하자 : JavaScript는 수년 동안 피하고 / 경멸 당했고, FF의 부상과 webcomm의 경멸로 IE는 주로 IE6에서 CSS를 발전시키는 데 집중하기로 결정했습니다. 그리고 기본적으로 DOM 지원을 남겨 두었습니다. IE8의 DOM 지원은 2001 년에 출시 된 IE6 일 수도 있습니다. 따라서 IE의 DOM 지원은 최신 브라우저에 비해 거의 10 년 뒤입니다. 레이아웃 엔진에 특정한 JavaScript 불일치가있는 경우 CSS 문제를 처리 한 것과 동일한 방식으로 공격하는 것이 가장 좋습니다. 해당 브라우저를 타겟팅합니다. 브라우저 스니핑을 사용하지 말고 기능 감지를 사용하여 브라우저 / 그것의 DOM 지원 수준을 스니핑하십시오.

JScript는 IE의 ECMAScript 구현이 아닙니다. JScript는 Netscape의 JavaScript에 대한 IE의 대답이었습니다. 둘 다 ECMAScript 이전에 존재하게되었습니다.

스크립트 요소의 유형 속성에 관해서는 type = "text / javascript"가 기본 표준 (적어도 HTML5에서는)이므로 스크립트가 JavaScript가 아닌 경우 유형 속성이 필요하지 않습니다.

IE가 innerHTML을 지원하지 않는 한 ... innerHTML은 IE에 의해 발명되었으며 오늘날에도 여전히 DOM 표준이 아닙니다. 유용하기 때문에 다른 브라우저에서이를 채택했기 때문에 크로스 브라우저에서 사용할 수 있습니다. 동적으로 테이블을 변경하는 한 MSDN은 "테이블에 필요한 특정 구조 때문에 테이블 및 tr 개체 의 innerTextinnerHTML 속성은 읽기 전용입니다."라고 말합니다. 처음에는 그것이 얼마나 사실 이었는지는 모르겠지만, 현대 브라우저는 테이블 레이아웃의 복잡성을 처리하면서 그것을 알아 냈습니다.

JavaScript에 대한 강력한 이해를 얻으려면 JavaScript Jeremy Keith의 DOM 스크립팅 Douglas Crockford의 JavaScript : The Good Parts 및 Christian Hellman의 Beginning JavaScript with DOM Scripting 및 Ajax 에서 PPK를 읽는 것이 좋습니다 .

프레임 워크 / 라이브러리에 관한 한, 아직 JavaScript에 대한 강한 이해가 없다면 피해야합니다. 2 년 전 나는 jQuery 함정에 빠졌고 웅장한 업적을 이룰 수 있었지만 JavaScript를 올바르게 코딩하는 것에 대해 전혀 배운 적이 없습니다. 돌이켜 보면 jQuery는 끔찍한 DOM 툴킷이지만 적절한 클로저, 프로토 타입 상속 등을 배우지 못해 개인적인 지식을 되찾았을뿐만 아니라 내가하고있는 실마리가 없었기 때문에 내 작업이 엄청난 성능 타격을 받기 시작했습니다.

JavaScript는 브라우저의 언어입니다. 클라이언트 측 / 프론트 엔드 엔지니어 인 경우 JavaScript를 명령하는 것이 가장 중요합니다. Node.js는 JavaScript를 완전히 기울이고 있습니다. 매일 개발 과정에서 엄청난 발전이 이루어지고 있습니다. 서버 측 JavaScript는 가까운 장래에 표준이 될 것입니다. JavaScript가 현재 얼마나 중요한지, 앞으로도 앞으로 더 중요해질 것임을 더욱 강조하기 위해 이것을 언급하고 있습니다.

JavaScript는 Rails보다 더 많은 파도를 만들 것입니다.

즐거운 스크립팅!


2
좋은 대답이지만 브라우저를 스니핑하기 위해 기능 감지를 사용하는 데 동의하지는 않습니다. 기능 감지를 사용하여 해당 기능의 지원 여부를 테스트하십시오 . 기능 감지는 브라우저 감지가 아님 의 예도 참조하십시오 .
Marcel Korpel

meh. 나는 당신의 의견 불일치에 전적으로 동의합니다. 잡아 주셔서 감사합니다. 나는 여전히 JavaScript n00b이지만 내 게임에는 부끄러운 것이 없습니다. "기능 기반 브라우저 감지는 어떤 대가를 치르더라도 피해야하는 매우 나쁜 관행입니다. 직접적인 기능 감지는 모범 사례이며 거의 모든 경우에 정확히 필요한 것입니다."
albert 2010-07-26

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">했습니다. ide 자동 완성이 "text / javascript"앞에 있기 때문입니다 .

그러나 "application / javascript"를 사용하는 경우 IE는 전체 스크립트를 무시하는 것으로 나타났습니다. "text / javascript"를 사용해야합니다.


javascript는 모든 브라우저에서 기본값이므로 사용하십시오<script>
Lauri

2

얼마 전 Internet Explorer에서 이상한 점을 발견했습니다. 나는 YUI를 사용하고 있었고 innerHTML을 설정하여 테이블 본문 ()의 내용을 대체했습니다.

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

이것은 IE를 제외한 모든 브라우저에서 작동합니다. 마침내 IE에서 테이블의 innerHTML을 바꿀 수 없다는 것을 발견했습니다. 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 2010

1

그만한 가치가 나는 <IE9 에서이 불쾌한 문제를 만났습니다.

다음과 같은 HTML이 있다고 가정하십시오.

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

그리고 어떤 이유로 (나는 좋은 것을 가지고 있었다) 마지막 TR을 닫기 전에 테이블의 모든 HTML을 검색해야합니다. 다음과 같은 것을 시도 할 수 있습니다.

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

<IE9는 tableHtml 변수에 대문자로 된 모든 html 태그가 포함되어 있고 lastIndexOf는 대소 문자를 구분하므로 여기서 아무것도 반환하지 않습니다 (-1). 이 문제를 해결하려면 lastIndexOf 전에 toLowerCase ()를 던져야했습니다.


0

IE는 최신 브라우저가 아니며 ECMAScript를 느슨하게 따릅니다.


0

내가 덜 익숙하지만 일반적인 참조, 특히 Prototype과 관련하여주의해야 할 jQuery를 언급 한 경우, IE의 예약어 / 메서드 이름을주의해야합니다. 나는 종종 나를 얻는 것이 다음과 같은 것을 압니다.

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

(new Element (tagName, propertyHash)는 Protitype에서 새로운 요소가 생성되는 방식입니다). IE에서는 예약어 이므로 for:이어야합니다 . 그것은 완전히 의미가 있지만 FireFox는 이것을 허용합니다.'for':for

다른 예시:

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

( wrapPrototype 의 메서드는 한 요소를 다른 요소로 래핑합니다.)-IE의 텍스트 영역에서 wrap속성이며 Element.wrap()메서드 화 된 버전 대신 사용해야합니다.

이것은 내 경험에서 떠오르는 두 가지 예입니다. 프로토 타입을 기반으로하지만 핵심 문제는 아닙니다. IE가 예약어를 고려하지만 FireFox 또는 Safari가 허용하는 모든 메서드 / 레이블 / 식별자를 조심하십시오.


0

사실 IE는 JavaScript를 지원하지 않습니다 ... 그것은 ECMAScript의 자신의 구현을 지원합니다 : JScript ... 약간 다릅니다 ...


0

console.log()Firefox 오류 콘솔에 오류를 출력하는 데 사용하면 IE에서 스크립트가 실패합니다. IE에서 테스트 할 때 빼는 것을 기억해야합니다.


FireBug가 켜져 있지 않으면 Firefox에서도 console.log 사용이 실패 할 것이라고 생각합니다.
ejel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.