Kod nie działa w IE 11, działa dobrze w Chrome


156

Poniższy kod można uruchomić bez problemu w przeglądarce Chrome, ale generuje następujący błąd w przeglądarce Internet Explorer 11.

Obiekt nie obsługuje właściwości lub metody „startedWith”

Przechowuję identyfikator elementu w zmiennej. Jaki jest problem?

function changeClass(elId) {
  var array = document.getElementsByTagName('td');
  
  for (var a = 0; a < array.length; a++) {
    var str = array[a].id;
    
    if (str.startsWith('REP')) {
      if (str == elId) {
        array[a].style.backgroundColor = "Blue";
        array[a].style.color = "white";
      } else {
        array[a].style.backgroundColor = "";
        array[a].style.color = "";
      }
    } else if (str.startsWith('D')) {
      if (str == elId) {
        array[a].style.backgroundColor = "Blue";
        array[a].style.color = "white";
      } else {
        array[a].style.backgroundColor = "";
        array[a].style.color = "";
      }
    }
  }
}
<table>
  <tr>
    <td id="REP1" onclick="changeClass('REP1');">REPS</td>
    <td id="td1">&nbsp;</td>
  </tr>
  <tr>
    <td id="td1">&nbsp;</td>
    <td id="D1" onclick="changeClass('D1');">Doors</td>
  </tr>
  <tr>
    <td id="td1">&nbsp;</td>
    <td id="D12" onclick="changeClass('D12');">Doors</td>
  </tr>
</table>


9
Zamiast tego prawdopodobnie będziesz musiał użyć str.indexOf("REP") == 0IE.
Grant Thomas

1
ES6 nie jest jeszcze standardowym kangax.github.io/compat-table/es6 Istnieje biblioteka podkładek ES6 ułatwiająca przejście github.com/paulmillr/es6-shim Podobnie jak w przypadku ES5 (w tym nie wszystko jest shimmable)
Xotic750

Odpowiedzi:


320

String.prototype.startsWith to standardowa metoda w najnowszej wersji JavaScript, ES6.

Patrząc na poniższą tabelę zgodności, widzimy, że jest obsługiwana na wszystkich obecnych głównych platformach, z wyjątkiem wersji Internet Explorera.

╔═══════════════╦════════╦═════════╦═══════╦═══════════════════╦═══════╦════════╗
    Feature     Chrome  Firefox  Edge   Internet Explorer  Opera  Safari 
╠═══════════════╬════════╬═════════╬═══════╬═══════════════════╬═══════╬════════╣
 Basic Support     41+      17+  (Yes)  No Support            28       9 
╚═══════════════╩════════╩═════════╩═══════╩═══════════════════╩═══════╩════════╝

Musisz się wdrożyć .startsWith. Oto wypełnienie :

if (!String.prototype.startsWith) {
  String.prototype.startsWith = function(searchString, position) {
    position = position || 0;
    return this.indexOf(searchString, position) === position;
  };
}

3
jest inna implementacja w MDN web String.prototype.startsWith = function(search, pos) { return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; };
Docs

1
Mam tendencję do pierwszej realizacji podanej przez @Oka. Jako dodatkowe uściślenie można sprawdzić, czy „pozycja” jest naprawdę numeryczna: pozycja =! IsNaN (parseInt (pozycja))? pozycja: 0;
ErnestV

36

text.indexOf("newString")to najlepsza metoda zamiast startsWith.

Przykład:

var text = "Format";
if(text.indexOf("Format") == 0) {
    alert(text + " = Format");
} else {
    alert(text + " != Format");
}

Dlaczego to najlepsza metoda?
TylerH

1
indexOf Metoda nie zastępuje wartości startedWith, indexOf zwróci wartość, jeśli pasuje do dowolnego miejsca w podanym ciągu, nie sugeruję używania indexOf.
RajKumar Samala

12
indexOfzwraca wartość, ale @Jona sprawdził, czy wartość zwracana jest równa zero (tj. ciąg znaków znajduje się na początku), co oznacza, że jest dobrym zamiennikiem startsWith!
SharpC

Jest to taka sama funkcjonalność, jak w przypadku wypełniacza bez konieczności dodawania wypełnienia lub wprowadzania dodatkowej biblioteki. To doskonałe rozwiązanie - jedyną wadą, jaką widzę, jest być może czytelność kodu - intencja jest bardziej jasna, gdy funkcja nosi nazwę startedWith.
John T

13

Jeśli tak się dzieje w aplikacji Angular 2+, możesz po prostu odkomentować ciąg znaków polyfills w polyfills.ts :

import 'core-js/es6/string';

Dodałem poprawkę polyfill Oka, ale nie działała w mojej aplikacji Angular 5, ale import 'core-js/es6/string';naprawiłem to. Wielkie dzięki!
decebal

5

Zastąp funkcję startedWith przez:

yourString.indexOf(searchString, position) // where position can be set to 0

Będzie to obsługiwać wszystkie przeglądarki, w tym IE

Pozycję można ustawić na 0, aby dopasować ciąg od początku, co oznacza pozycję zerową.


Przydatne rozwiązanie bez konieczności przepisywania prototypów i stosowania polyfillów. Ponadto jest kompatybilny z różnymi przeglądarkami. +1
Sergio A.

2

Jak powiedzieli inni, startWith i endWith są częścią ES6 i nie są dostępne w IE11. Nasza firma zawsze używa biblioteki lodash jako rozwiązania polyfill dla IE11. https://lodash.com/docs/4.17.4

_.startsWith([string=''], [target], [position=0])

0

Chociaż post Oka działa świetnie, może być nieco nieaktualny. Odkryłem, że lodash może sobie z tym poradzić za pomocą jednej funkcji. Jeśli masz zainstalowany lodash, może to zaoszczędzić kilka linii.

Spróbuj:

import { startsWith } from lodash;

. . .

    if (startsWith(yourVariable, 'REP')) {
         return yourVariable;        
    return yourVariable;
       }      
     }

0

Niedawno stanąłem przed problemem. Rozwiązałem za pomocą ^, który jest podobny do startwith w jquery. Mówić,

var str = array[a].id;
if (str.startsWith('REP')) {..........}

możemy użyć

if($("[id^=str]").length){..........}

Tutaj str jest id elementu.


0

Postępuj zgodnie z tą metodą, jeśli pojawia się problem podczas pracy z projektami angular2 +

Szukałem rozwiązania, gdy dostałem ten błąd, i to mnie tu doprowadziło. Ale to pytanie wydaje się być konkretne, ale błąd nie jest, jest to ogólny błąd. Jest to typowy błąd dla programistów kątowych zajmujących się Internet Explorerem.

Miałem ten sam problem podczas pracy z Angular 2+ i został on rozwiązany w kilku prostych krokach.

W najnowszych wersjach Angulara w plikach polyfills znajdują się skomentowane kody. Ts pokazuje wszystkie wypełnienia wymagane do płynnego działania w wersjach Internet Explorer IE09, IE10 i IE11

/** IE9, IE10 and IE11 requires all of the following polyfills. **/
//import 'core-js/es6/symbol';
//import 'core-js/es6/object';
//import 'core-js/es6/function';
//import 'core-js/es6/parse-int';
//import 'core-js/es6/parse-float';
//import 'core-js/es6/number';
//import 'core-js/es6/math';
//import 'core-js/es6/string';
//import 'core-js/es6/date';
//import 'core-js/es6/array';
//import 'core-js/es6/regexp';
//import 'core-js/es6/map';
//import 'core-js/es6/weak-map';
//import 'core-js/es6/set';

Odkomentuj kody i działałoby to doskonale w przeglądarkach IE

/** IE9, IE10 and IE11 requires all of the following polyfills. **/
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';

Ale możesz zauważyć spadek wydajności przeglądarek IE w porównaniu do innych :(

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.