Jakie są typowe przyczyny niepowodzenia Javascript opracowanego dla przeglądarki Firefox w przeglądarce IE? [Zamknięte]

108

Opracowałem kilka ulepszonych stron javascript, które działają dobrze na najnowszych przeglądarkach Firefox i Safari. Brakowało mi sprawdzenia w Internet Explorerze, a teraz stwierdzam, że strony nie działają w IE 6 i 7 (jak dotąd). Skrypty w jakiś sposób nie są wykonywane, strony wyświetlają się tak, jakby nie było javascript, chociaż niektóre javascript są wykonywane. Używam własnych bibliotek z manipulacją domem, od YUI 2 używam YUI-Loader i XML-Http-Request, a na jednej stronie używam "psupload", który zależy od JQuery.

Instaluję program Microsoft Script Editor z pakietu Office XP i będę teraz debugować. Napiszę teraz również konkretne testy.

Jakie są typowe awarie IE? W jakim kierunku mogę mieć otwarte oczy.

Znalazłem tę stronę, na której widać pewne różnice. wizyta: Quirksmode

Czy możesz na podstawie swojego doświadczenia wymienić kilka typowych rzeczy, na które powinienem zwrócić uwagę?

Później zadam tutaj więcej pytań dotyczących konkretnych zadań, ale na razie interesuje mnie twoje doświadczenie, dlaczego IE zwykle zawodzi w skryptach, które działają dobrze w Firefoksie

Edycja: Dziękuję za wszystkie świetne odpowiedzi!

W międzyczasie dostosowałem cały kod tak, aby działał również z Internet Explorerem. Zintegowałem jQuery i zbudowałem teraz na nim własne klasy. To był mój podstawowy błąd, że nie zbudowałem wszystkich swoich rzeczy na jQuery od początku. Teraz mam.

Bardzo pomogło mi też JSLint.

Pomogło też wiele pojedynczych problemów z różnych odpowiedzi.

user89021
źródło
Na razie nie ma problemów z css czy stylizacją, o czym wiedziałem z wcześniejszego kodowania. Tylko problemy z JS - karlthorwald
user89021
1
Najpierw uruchomię teraz JSLint na wszystkich plikach, są takie, których nigdy nie dostosowałem.
user89021
7
„To był mój podstawowy błąd, że nie zbudowałem wszystkich swoich rzeczy na jQuery od samego początku”. - to nie rozwiąże w magiczny sposób wszystkich problemów z różnymi przeglądarkami. Przeszukaj stackoverflow dla jQuery i IE, znajdziesz mnóstwo problemów. Najlepiej nauczyć się samodzielnego tworzenia skryptów w różnych przeglądarkach, więc gdy jQuery lub jedna z miliardów jego szkicowych wtyczek ulegnie awarii, będziesz w stanie zaimplementować prawdziwe działające rozwiązanie dla różnych przeglądarek i będziesz wiedzieć, że działa i dlaczego.
Dagg Nabbit
11
+1 w komentarzu nie powyżej. O DUŻO lepiej unikasz jQuery całkowicie IFF, uczysz się javascript - jQuery jest niezwykle przydatne, jeśli chcesz zrobić coś złożonego szybko i łatwo, ale jeśli się uczysz, uchroni cię przed złożonością zrozumienia, jak właściwie javascript działa - wydaje się, że zbyt wiele osób zna jQuery, ale nie ma pojęcia, jak pisać javascript. Nie popełniłeś błędu, nie bazując na jQuery - teraz masz dużo lepsze zrozumienie własnego kodu niż gdybyś miał.
lucideer

Odpowiedzi:

121

Prosimy o zaktualizowanie tej listy, jeśli zauważysz jakiekolwiek błędy / pominięcia itp.

Uwaga: IE9 rozwiązuje wiele z poniższych problemów, więc wiele z nich dotyczy tylko IE8 i starszych oraz do pewnego stopnia IE9 w trybie dziwactw. Na przykład, IE9 obsługuje SVG, <canvas>, <audio>i <video>natywnie, jednak należy włączyć tryb zgodności ze standardami dla nich dostępne.


Generał:

  • Problemy z częściowo załadowanymi dokumentami: dobrym pomysłem jest dodanie JavaScript w window.onloadlub podobnym wydarzeniu, ponieważ IE nie obsługuje wielu operacji w częściowo załadowanych dokumentach.

  • Różne atrybuty : w CSS jest to elm.style.styleFloatw IE i elm.style.cssFloatFirefox. W <label>tagach foratrybut jest dostępny za pomocą elm.htmlForw IE vs elm.forw Firefox. Zauważ, że forjest to zastrzeżone w IE, więc elm['for']prawdopodobnie lepszym pomysłem jest powstrzymanie IE przed zgłaszaniem wyjątku.


Podstawowy język JavaScript:

  • Dostęp do znaków w ciągach : 'string'[0]nie jest obsługiwany w przeglądarce IE, ponieważ nie jest objęty oryginalnymi specyfikacjami JavaScript. Użyj 'string'.charAt(0)lub 'string'.split('')[0]zauważ, że dostęp do elementów w tablicach jest znacznie szybszy niż używanie charAtz ciągami znaków w IE (chociaż jest pewien początkowy narzut podczas splitpierwszego wywołania).

  • Przecinki przed końcem obiektów: np. {'foo': 'bar',}Nie są dozwolone w IE.


Problemy specyficzne dla elementu:

  • Pobieranie documentramek iFrame :

    • Firefox i IE8 +: IFrame.contentDocument (IE zaczął obsługiwać to od wersji 8 ).
    • TO ZNACZY: IFrame.contentWindow.document
    • ( IFrame.contentWindowodnosi się do windoww obu przeglądarkach).

  • Canvas: wersje IE przed IE9 nie obsługują tego <canvas>elementu. IE obsługuje jednak VML, który jest podobną technologią, a explorercanvas może dostarczać miejscowe opakowanie <canvas>elementów dla wielu operacji. Należy pamiętać, że IE8 w trybie zgodności ze standardami jest wielokrotnie wolniejszy i ma o wiele więcej błędów niż w trybie dziwactw podczas korzystania z VML.

  • SVG: IE9 natywnie obsługuje SVG. IE6-8 może obsługiwać SVG, ale tylko z zewnętrznymi wtyczkami, z których tylko niektóre obsługują manipulację JavaScript.

  • <audio>i <video>: są obsługiwane tylko w przeglądarce IE9.

  • Dynamiczne tworzenie przycisków radiowych: IE <8 ma błąd, który sprawia, że ​​przyciski radiowe utworzone z document.createElementzaznaczeniem nie są możliwe. Zobacz także Jak dynamicznie utworzyć przycisk opcji w Javascript, który działa we wszystkich przeglądarkach? jak to obejść.

  • Osadzony JavaScript w <a href>tagach i onbeforeunloadkonfliktach w IE: Jeśli w hrefczęści atagu jest osadzony JavaScript (np. <a href="javascript: doStuff()">IE zawsze pokaże wiadomość zwróconą z, onbeforeunloadchyba że onbeforeunloadmoduł obsługi zostanie wcześniej usunięty. Zobacz także Pytaj o potwierdzenie przy zamykaniu karty .

  • <script>różnice w zdarzeniach tagów: onsuccess i onerrornie są obsługiwane w IE i są zastępowane przez specyficzne dla IE, onreadystatechangektóre są uruchamiane niezależnie od tego, czy pobieranie zakończyło się powodzeniem, czy niepowodzeniem. Zobacz także JavaScript Madness, aby uzyskać więcej informacji.


Rozmiar / pozycja / przewijanie i pozycja myszy:

  • Pobieranie rozmiaru / pozycji elementu : szerokość / wysokość elementów jest czasami elm.style.pixelHeight/Widthraczej w IE niż elm.offsetHeight/Width, ale żaden nie jest wiarygodny w IE, szczególnie w trybie dziwactw, a czasami jeden daje lepszy wynik niż drugi.

    elm.offsetTopi elm.offsetLeftczęsto są nieprawidłowo zgłaszane, co prowadzi do znalezienia niepoprawnych pozycji elementów, dlatego w wielu przypadkach elementy wyskakujące itp. są oddalone o kilka pikseli.

    Zauważ również, że jeśli element (lub element nadrzędny elementu) ma displayof, noneto IE zgłosi wyjątek podczas uzyskiwania dostępu do atrybutów rozmiaru / pozycji, zamiast zwracać, 0jak robi to Firefox.

  • Uzyskaj rozmiar ekranu (Uzyskiwanie widocznego obszaru ekranu):

    • Firefox: window.innerWidth/innerHeight
    • Tryb standardów IE: document.documentElement.clientWidth/clientHeight
    • Tryb dziwactw IE: document.body.clientWidth/clientHeight

  • Pozycja przewijania dokumentu / pozycja myszy : W rzeczywistości ta pozycja nie jest zdefiniowana przez w3c, więc jest niestandardowa nawet w Firefoksie. Aby znaleźć scrollLeft/ scrollTopz document:

    • Firefox i IE w trybie dziwactw: document.body.scrollLeft/scrollTop
    • IE w trybie standardowym: document.documentElement.scrollLeft/scrollTop
    • UWAGA: Niektóre inne przeglądarki również używają 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];
      };

    Aby uzyskać pozycję kursora myszy, evt.clientXa evt.clientYna mousemoveimprezach da stanowisko w stosunku do dokumentu bez dodawania pozycji przewijania tak poprzednia funkcja musi być włączona:

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

Wybór / zakresy:

  • <textarea>i <input>selekcje : selectionStarti selectionEndnie są zaimplementowane w IE, a zamiast tego istnieje zastrzeżony system „zakresów”, zobacz także pozycję Caret w obszarze tekstowym, w znakach od początku .

  • Pobieranie aktualnie zaznaczonego tekstu w dokumencie:

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


Pobieranie elementów według identyfikatora:

  • document.getElementByIdmoże również odnosić się do nameatrybutu w formularzach (w zależności od tego, który jest zdefiniowany jako pierwszy w dokumencie), więc najlepiej nie używać różnych elementów, które mają takie same namei id. To sięga czasów, kiedy idnie był standardem w3c. document.all( Zastrzeżona własnością IE-specyficzna ) jest znacznie szybsze niż document.getElementById, ale ma inne problemy, jak to zawsze priorytet nameprzed id. Osobiście używam tego kodu, wycofując się z dodatkowymi kontrolami, aby się upewnić:

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

Problemy z wewnętrznym kodem HTML tylko do odczytu:

  • IE ma nie obsługiwać ustawienie innerHTML z col, colGroup, frameSet, html, head, style, table, tBody, tFoot, tHead, title, i trelementy. Oto funkcja, która działa wokół tego dla elementów związanych z tabelami:

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

    Należy również pamiętać, że IE wymaga dodania a <tbody>do a <table>przed dołączeniem <tr>s do tego <tbody>elementu podczas tworzenia document.createElement, na przykład:

    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

Różnice w wydarzeniach:

  • Pobieranie eventzmiennej: zdarzenia DOM nie są przekazywane do funkcji w IE i są dostępne jako window.event. Jednym z powszechnych sposobów uzyskania zdarzenia jest użycie np.
    elm.onmouseover = function(evt) {evt = evt||window.event}
    Wartości domyślnej window.eventif evtjest niezdefiniowane.

  • Kluczowe różnice w kodach zdarzeń: Kody kluczowych zdarzeń są bardzo różne, ale jeśli spojrzysz na Quirksmode lub JavaScript Madness , nie jest to specyficzne dla IE, Safari i Opera znowu się różnią.

  • Mysz różnice zdarzeń:button atrybut w IE jest bit-flaga, która pozwala wielu przycisków myszy na raz:

    • Po lewej: 1 ( var isLeft = evt.button & 1)
    • Po prawej: 2 ( var isRight = evt.button & 2)
    • Środek: 4 ( var isCenter = evt.button & 4)

      Model W3C (obsługiwany przez przeglądarkę Firefox) jest mniej elastyczny niż model IE, z dozwolonym tylko jednym przyciskiem naraz z lewej jako 0, z prawej strony 2i ze środka jako 1. Zauważ, że, jak wspomina Peter-Paul Koch , jest to bardzo sprzeczne z intuicją, ponieważ 0zwykle oznacza „brak przycisku”.

      offsetXi offsetYproblematyczne i prawdopodobnie najlepiej jest ich unikać w IE. Bardziej niezawodnym sposobem uzyskania offsetXi offsetYw IE byłoby uzyskanie pozycji względnie pozycjonowanego elementu i odjęcie go od clientXi clientY.

      Zwróć również uwagę, że w IE, aby uzyskać podwójne kliknięcie w clickzdarzeniu, musisz zarejestrować zarówno a, jak clicki dblclickzdarzenie w funkcji. Firefox uruchamia się clicktak samo, jak dblclickpo dwukrotnym kliknięciu, więc do tego samego zachowania potrzebne jest wykrywanie specyficzne dla IE.

  • Różnice w przypadku przenoszenia modelu: Zarówno zastrzeżonych IE model i model obsługi zdarzeń support Firefox z dołu do góry, na przykład, jeśli istnieją wydarzenia w obu elementów <div><span></span></div>ówczesnych wydarzeń wywoła w span czym się divraczej niż kolejność którym są związane, jeśli zastosowano tradycyjny np elm.onclick = function(evt) {}.

    „Capture” wydarzenia są zazwyczaj obsługiwane tylko w Firefoksie etc, który wywoła divwtedy spanzdarzenia w górę w dół kolejności. IE ma elm.setCapture()i elm.releaseCapture()do przekierowywania zdarzeń myszy z dokumentu do elementu ( elmw tym przypadku) przed przetworzeniem innych zdarzeń, ale mają one szereg problemów z wydajnością i innymi problemami, więc prawdopodobnie należy ich unikać.

    • Firefox:

      Dołącz : elm.addEventListener(type, listener, useCapture [true/false])
      odłącz : elm.removeEventListener(type, listener, useCapture)
      ( typenp. 'mouseover'Bez on)

    • IE: W IE można dodać tylko jedno zdarzenie danego typu na elemencie - wyjątek jest zgłaszany w przypadku dodania więcej niż jednego zdarzenia tego samego typu. Zwróć również uwagę, że w funkcjach zdarzeń thisodwołuje się windowraczej do elementu powiązanego (jest więc mniej przydatne):

      Dołącz : elm.attachEvent(sEvent, fpNotify)
      odłącz : elm.detachEvent(sEvent, fpNotify)
      ( sEventnp. 'onmouseover')

  • Różnice w atrybutach zdarzeń:

    • Zatrzymaj przetwarzanie zdarzeń przez inne funkcje nasłuchujące :

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

    • Zatrzymaj np. Kluczowe zdarzenia przed wstawianiem znaków lub zatrzymaniem zaznaczania pól wyboru:

      Firefox: evt.preventDefault()
      IE: evt.returnValue = false
      Uwaga: Tylko powrocie falsew keydown, keypress, mousedown, mouseup, clicka resettakże zapobiec domyślne.

    • Pobierz element, który wywołał zdarzenie:

      Firefox: evt.target
      IE: evt.srcElement

    • Pobranie elementu, z którego odsunął się kursor myszy: evt.fromElement w IE jest evt.targetw przeglądarce Firefox, jeśli jest w onmouseoutzdarzeniu, w przeciwnym razieevt.relatedTarget

    • Pobranie elementu, do którego został przeniesiony kursor myszy: evt.toElement w IE jest evt.relatedTargetw przeglądarce Firefox, jeśli jest w onmouseoutzdarzeniu, w przeciwnym razieevt.target

    • Uwaga: evt.currentTarget (element, do którego było przypisane zdarzenie) nie ma odpowiednika w IE.

krio
źródło
12
Bardzo, bardzo, bardzo ładna lista! Dziękujemy wszystkim, którzy wnieśli swój wkład :)
cwap
26

Sprawdź również, czy w kodzie nie ma przecinków, takich jak te lub podobne

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

ostatni przecinek (następujący po wartości 2) będzie tolerowany przez przeglądarkę Firefox, ale nie przez IE

Luca Rocchi
źródło
1
Większość dobrych redaktorów powinna to złapać
SeanJA
1
+1, miałem to zbyt często.
David V.
1
Dałbym ci +10, gdybym mógł - to mi się zdarza przez cały czas.
Josh
Aha i dodać do komentarza @ SeanJA: Niedawno przełączyłem się na NetBeans, który to łapie.
Josh,
Straciłem na tym tyle godzin, kiedy pierwszy raz wykonałem jakąś pracę w JS. To pierwsza rzecz, którą sprawdzam! Przeklęte rozszerzenia Textmate pozostawiają przecinki.
Agos,
12

Jeśli będziesz używać jQuery lub YUI, gdy Twój post jest oznaczony tagiem, powinieneś mieć minimalne różnice między przeglądarkami ... po to są frameworki, aby zająć się tymi różnicami między przeglądarkami za Ciebie.

Na przykład spójrz na stronę przechodzenia przez quirksmode DOM , zgodnie z nią IE nie obsługuje większości rzeczy ... podczas gdy prawda, frameworki tak, na przykład IE nie obsługuje elem.childElementCount, ale w jQuery: $(elem).children().size()działa, aby uzyskać tę wartość, w każdej przeglądarce. Przekonasz się, że w bibliotece jest coś, co poradzi sobie z 99% nieobsługiwanych przypadków w różnych przeglądarkach, przynajmniej za pomocą skryptu ... w przypadku CSS może być konieczne przejście do wtyczek do biblioteki, typowym przykładem tego jest zaokrąglenie rogów pracuje w IE ... ponieważ nie ma dla nich wsparcia CSS.

Jeśli jednak zaczniesz robić rzeczy bezpośrednio, na przykład document.XXX(thing), nie jesteś w bibliotece, robisz bezpośrednio javascript (to wszystko jest javascript, ale rozumiesz o co chodzi :), a to może powodować problemy lub nie, w zależności od tego, jak pijany zespół IE był podczas wdrażania tej konkretnej funkcji.

W IE jest bardziej prawdopodobne, że stylizacja wyjdzie dobrze, niż problemy z surowym javascriptem, animacje o kilka pikseli wyłączone i tym podobne rzeczy, o wiele więcej, oczywiście w IE6.

Nick Craver
źródło
Teraz rozumiem lepiej. Tak, ja też robiłem takie rzeczy bezpośrednio. karlthorwald
user89021
1
Jeśli używasz IDE, takiego jak Netbeans, możesz ustawić docelowe przeglądarki dla swojego javascript, a także pomoże, ostrzegając cię, gdy robisz coś, co wydaje się nie być obsługiwane.
SeanJA
10

getElementbyID będzie również pasować do atrybutu name w IE, ale nie w innych przeglądarkach, a IE wybierze tę, którą znajdzie jako pierwszą.

przykład:

<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
GSto
źródło
3
przepraszam za bycie niegrzecznym, ale IE jest naprawdę brzydki
user89021
12
document.getElementByIdOrNameIGuessWhthingMan (id);
JulianR,
5

Jest mnóstwo rzeczy, ale jedną z pułapek, w które wpadałem, było to, że wiele przeglądarek akceptuje JSON bez cytowanych nazw, podczas gdy ie6 i ie7 nie.

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

Edycja : aby wyjaśnić, jest to problem tylko wtedy, gdy wymagany jest rzeczywisty JSON, w przeciwieństwie do literału obiektu. JSON jest podzbiorem składni literału obiektowego i jest pomyślany jako format wymiany danych (podobnie jak XML), dlatego został zaprojektowany tak, aby był trudniejszy.

Jakob
źródło
2
Zauważ, że zależy to od kontekstu, literał obiektu jest w porządku, JSON nie jest ... ale na przykład jQuery w ogóle nie zezwala na nieprawidłowy JSON w ich najnowszej wersji.
Nick Craver
To nie jest mój głos przeciw ... ale powinieneś wyjaśnić to innym, a następnie dać +1 ode mnie.
Nick Craver
5

Obsługa różnych języków JavaScript

IE nie obsługuje (większości) rozszerzeń dodanych do JavaScript od 1.5.

Nowość w wersji 1.6.0

  • Metody Array - indexOf(), lastIndexOf(), every(), filter(), forEach(), map(),some()
  • for each ... in - iteruje wartości zamiast nazw właściwości.

Nowość w wersji 1.7.0

Nowość w 1.8.1

  • Metody tablicowe - reduce(),reduceRight()
  • Skróty do definiowania funkcji.

Niektóre z tych rzeczy wymagają określenia numeru wersji JavaScript do uruchomienia (który zepsuje się w IE), ale niektóre rzeczy, takie jak, [1,2,3].indexOf(2)mogą nie wydawać się tak ważne, dopóki nie spróbujesz go uruchomić w IE

gnarf
źródło
1
JavaScript, o którym tutaj mówisz, to JavaScript (TM) Mozilli, a nie javascript w bardziej ogólnym sensie. Nie wszystkie implementacje ECMAScript / silniki javascript (w tym przypadku MS JScript) powinny być zgodne z JavaScript (TM) Mozilli. ECMAScript jest standardem, a nie JavaScript (TM), a JavaScript (TM) nie jest JavaScriptem. Mam nadzieje że to miało sens.
Dagg Nabbit
Dla mnie ma to sens, ale w wątku dotyczącym kompatybilności między JavaScript i JScript, pomyślałem, że będzie to już zrozumiałe :)
gnarf
Kiedy mówisz "IE nie obsługuje (większości) rozszerzeń dodanych do JavaScript od 1.5.", To brzmi tak, jakbyś mówił, że JavaScript (TM) Mozilli jest standardem, do którego IE powinien stosować się, podczas gdy oczywiście nie jest. Możesz przynajmniej powiedzieć, że JavaScript Mozilli lub podobny ... inna przeglądarka nie obsługuje wszystkich rozszerzeń Mozilli do ECMAScript, takich jak przypisanie destrukcji itp. Pytanie dotyczyło różnic między „większość” javascripta (konkretną implementacją) JScript, a nie różnic między Mozilla JavaScript(TM)i JScript. Lepiej byłoby pokazać, gdzie IE różni się od ES.
Dagg Nabbit
3

Główne różnice między JavaScript w IE i JavaScript w nowoczesnych przeglądarkach (np. Firefox) można przypisać tym samym przyczynom różnic w CSS / (X) HTML między przeglądarkami. W tamtych czasach nie istniał faktyczny standard; IE / Netscape / Opera walczyły w wojnie o wpływy, implementując większość specyfikacji, ale także pomijając niektóre, a także tworząc własne specyfikacje, aby zyskać przewagę nad innymi. Mógłbym kontynuować, ale przeskoczmy do wydania IE8: JavaScript był unikany / pogardzany przez lata, a wraz z rozwojem FF i pogardą dla webcomm, IE zdecydował się skupić głównie na ulepszaniu CSS z IE6 na. I zasadniczo zostawił obsługę DOM w tyle. Obsługa DOM w IE8 może być równie dobrze obsługiwana przez IE6, który został wprowadzony w 2001 roku ... więc obsługa DOM w IE jest prawie dziesięć lat za nowoczesnymi przeglądarkami. Jeśli masz rozbieżności JavaScript charakterystyczne dla silnika układu, najlepiej jest zaatakować go w ten sam sposób, w jaki zajęliśmy się problemami CSS; Kierowanie na tę przeglądarkę. NIE UŻYWAJ PRZEGLĄDARKI PRZEGLĄDARKI, użyj wykrywania funkcji, aby wykryć przeglądarkę / jej poziom obsługi DOM.

JScript nie jest własną implementacją ECMAScript w IE; JScript był odpowiedzią IE na JavaScript firmy Netscape, który powstał przed ECMAScript.

Jeśli chodzi o atrybuty typu w elemencie skryptu, type = "text / javascript" jest domyślnym standardem (przynajmniej w HTML5), więc nie potrzebujesz atrybutu type, chyba że twój skrypt nie jest JavaScript.

O ile IE nie obsługuje innerHTML ... innerHTML została wynaleziona przez IE i nadal NIE jest standardem DOM. Inne przeglądarki przyjęły go, ponieważ jest przydatny, dlatego można go używać w różnych przeglądarkach. Jeśli chodzi o dynamicznie zmieniające się tabele, MSDN mówi, że „ze względu na specyficzną strukturę wymaganą przez tabele, innerText i innerHTML obiektów table i tr są tylko do odczytu”. Nie wiem, ile z tego początkowo było prawdą, ale najwyraźniej współczesne przeglądarki odkryły to, radząc sobie ze złożonością układu tabeli.

Gorąco polecam przeczytanie PPK w JavaScript Jeremy Keith's DOM Scripting Douglas Crockford's JavaScript: The Good Parts i Christian Hellman's Beginning JavaScript with DOM Scripting i Ajax, aby dobrze zrozumieć JavaScript.

Jeśli chodzi o frameworki / biblioteki, jeśli nie masz jeszcze dobrego zrozumienia JavaScript, powinieneś ich unikać. Dwa lata temu wpadłem w pułapkę jQuery i chociaż byłem w stanie dokonać wspaniałych wyczynów, nigdy nie nauczyłem się niczego o poprawnym kodowaniu JavaScript. Z perspektywy czasu jQuery to niesamowity, niesamowity zestaw narzędzi DOM, ale moja niezdolność do nauczenia się prawidłowych zamknięć, prototypowego dziedziczenia itp. Nie tylko cofnęła moją osobistą wiedzę, ale moja praca zaczęła osiągać ogromne hity wydajnościowe, ponieważ nie miałem pojęcia, co robię.

JavaScript to język przeglądarki; Jeśli jesteś inżynierem po stronie klienta / front-endu, niezwykle ważne jest, aby sterować JavaScript. Node.js wprowadza JavaScript w pełnym zakresie, codziennie widzę ogromne postępy w jego rozwoju; JavaScript po stronie serwera będzie standardem w najbliższej przyszłości. Wspominam o tym, aby jeszcze bardziej podkreślić, jak ważny jest teraz i będzie JavaScript.

JavaScript zrobi więcej fal niż Railsy.

Miłego tworzenia skryptów!

Albert
źródło
2
Dobra odpowiedź, chociaż nie zgadzam się na używanie wykrywania funkcji do wykrywania przeglądarki; Używaj wykrywania funkcji tylko do testowania obsługi tych funkcji. Zobacz również przykłady w sekcji Wykrywanie funkcji nie jest wykrywaniem przeglądarki .
Marcel Korpel,
meh. całkowicie się zgadzam z twoim sprzeciwem. dzięki za złapanie tego. Nadal jestem JavaScript n00b, ale w mojej grze nie ma wstydu. „Wykrywanie przeglądarki oparte na funkcjach to bardzo zła praktyka, której należy unikać za wszelką cenę. Proste wykrywanie funkcji jest najlepszą praktyką i prawie w każdym przypadku jest dokładnie tym, czego potrzebujesz”.
Albert
2

Niektóre obiekty natywne są tylko do odczytu, ale tak naprawdę nie wydaje się, że takie są (możesz do nich pisać, ale nie ma to żadnego efektu). Na przykład wspólny zaawansowany skrypt javascript opiera się na rozszerzeniuElement obiektu przez nadpisywanie metod systemowych, powiedzmy, zmianę Element.prototype.appendChild (), aby robił więcej niż dołączanie węzła potomnego - powiedzmy, zainicjuj go danymi rodzica. To zawiedzie po cichu w IE6 - oryginalna metoda zostanie wywołana na nowych obiektach zamiast na nowej.

Niektóre przeglądarki (nie pamiętam teraz, która teraz) uważają znaki nowej linii między tagami HTML za węzły tekstowe, podczas gdy inne nie. Więc childNodes (n), nextSibling (), firstChild () i tym podobne będą zachowywać się zupełnie inaczej.

SF.
źródło
2

Końcowe przecinki w tablicach i literałach obiektów były kiedyś problemem, ostatnio nie były sprawdzane (co oznacza IE8):

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

Spowodowałoby to dodatkowy kod podczas generowania takich struktur po stronie serwera.

npup
źródło
2

Właśnie znalazłem jeden dziś rano, współpracownik ustawił tag skryptu jako: <script type="application/javascript">ponieważ jego autouzupełnianie ide miało to przed „text / javascript”

Ale okazuje się, że IE po prostu ignoruje cały skrypt, jeśli używasz „application / javascript”, musisz użyć „text / javascript”

katjones
źródło
javascript jest domyślny we wszystkich przeglądarkach, więc użyj po prostu<script>
Lauri
2

Niedawno znalazłem dziwne dziwactwo z Internet Explorerem. Używałem YUI i zastępowałem zawartość tabeli body () przez ustawienie innerHTML

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

To działałoby we wszystkich przeglądarkach Z WYJĄTKIEM IE. W końcu odkryłem, że nie można zastąpić innerHTML tabeli w IE. Musiałem utworzyć węzeł za pomocą YUI, a następnie dołączyć ten węzeł.

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

Fajnie było to wymyślić!

Justin
źródło
1
Mam wrażenie, że trzeba to owinąć <tbody>metkami.
Casey Chu,
W oryginalnym kodzie jest faktycznie opakowany w znacznik <tbody>. Wciąż wieje mi w głowie, że IE tego nie lubił. Pamiętam, że czytałem o tym w oficjalnych dokumentach Microsoftu, ale nie mogę teraz znaleźć linku. Przepraszam!
Justin
1

Dodatkowe przecinki i brakujące przecinki były zwykłym problemem w IE, podczas gdy działa płynnie na FF.

Głęboki
źródło
1

IE bardzo surowo podchodzi do braku ";" tak jest zwykle.

Sam3k
źródło
Znajduję wiele z nich, gdy teraz korzystam z jsLinting. Wydaje się, że to ważny punkt.
user89021
1

Cóż to jest warte, natknąłem się właśnie na ten nieprzyjemny problem w <IE9

powiedz, że masz taki kod HTML:

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

iz jakiegoś powodu (miałem dobry) musisz pobrać cały kod HTML z tabeli przed ostatnim zamykającym TR, możesz spróbować czegoś takiego:

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

<IE9 nie zwróci nic (-1) tutaj, ponieważ zmienna tableHtml zawiera wszystkie znaczniki HTML pisane dużymi literami, a lastIndexOf rozróżnia wielkość liter. Aby obejść ten problem, musiałem dorzucić toLowerCase () przed lastIndexOf.

tomfumb
źródło
0

IE nie jest nowoczesną przeglądarką i tylko luźno podąża za ECMAScript.

Obrabować
źródło
0

Wspomniałeś o jQuery, z którym jestem mniej zaznajomiony, ale dla ogólnego odniesienia, a konkretnie w przypadku Prototype, jedną rzeczą, na którą należy zwrócić uwagę, są zastrzeżone słowa / nazwy metod w IE. Wiem, co często mnie dosięga, to:

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

(new Element (tagName, propertyHash) to sposób tworzenia nowych elementów w Protitype). W IE for:musi być 'for':, ponieważ forjest to słowo zastrzeżone. Co ma sens - ale FireFox to toleruje.

Inny przykład:

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

( wrapmetoda w Prototype zawija jeden element w inny) - W IE na obszarach tekstowych wrapjest to właściwość, aElement.wrap() musi być używana zamiast wersji metodowanej

Oto dwa przykłady, które przychodzą mi do głowy z mojego doświadczenia. Opierają się na prototypie, ale głównym problemem nie jest: uważaj na wszelkie metody / etykiety / identyfikatory, które IE uważa za zastrzeżone słowa, ale FireFox lub Safari będą tolerować.

Josh
źródło
0

Faktem jest, że IE nie obsługuje JavaScript ... Obsługuje własną implementację ECMAScript: JScript ... która jest trochę inna ...

xavierm02
źródło
0

Używanie console.log()do wyświetlania błędów w konsoli błędów Firefoksa spowoduje awarię skryptów w IE. Pamiętaj, aby je usunąć podczas testowania w IE.

Erikk Ross
źródło
Uważam, że korzystanie z console.log nie powiedzie się nawet w Firefoksie, jeśli nie masz włączonego FireBuga.
ejel