Le code ne fonctionne pas dans IE 11, fonctionne bien dans Chrome

156

Le code suivant peut être exécuté sans problème dans Chrome, mais génère l'erreur suivante dans Internet Explorer 11.

L'objet ne prend pas en charge la propriété ou la méthode 'startsWith'

Je stocke l'ID de l'élément dans une variable. Quelle est la solution?

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>

Bhushan Dhamdhere
la source
9
Vous devrez probablement utiliser str.indexOf("REP") == 0pour IE à la place.
Grant Thomas
1
ES6 n'est pas encore un standard kangax.github.io/compat-table/es6 Il existe une bibliothèque de shim ES6 pour aider à la transition github.com/paulmillr/es6-shim Tout comme pour ES5 (y compris tout n'est pas shimmable)
Xotic750

Réponses:

320

String.prototype.startsWith est une méthode standard de la version la plus récente de JavaScript, ES6.

En regardant le tableau de compatibilité ci-dessous, nous pouvons voir qu'il est pris en charge sur toutes les principales plates-formes actuelles, à l' exception des versions d'Internet Explorer.

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

Vous devrez .startsWithvous mettre en œuvre . Voici le polyfill :

if (!String.prototype.startsWith) {
  String.prototype.startsWith = function(searchString, position) {
    position = position || 0;
    return this.indexOf(searchString, position) === position;
  };
}
Oka
la source
3
il y a une autre implémentation chez MDN web docs String.prototype.startsWith = function(search, pos) { return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; };
oCcSking
1
J'ai tendance à la première implémentation donnée par @Oka. Tout comme un raffinement supplémentaire, on pourrait tester pour "position" étant vraiment numérique: position =! IsNaN (parseInt (position))? position: 0;
ErnestV
36

text.indexOf("newString")est la meilleure méthode au lieu de startsWith.

Exemple:

var text = "Format";
if(text.indexOf("Format") == 0) {
    alert(text + " = Format");
} else {
    alert(text + " != Format");
}
Jona
la source
Pourquoi est-ce la meilleure méthode?
TylerH
1
indexOf Méthode en ne remplaçant pas pour startsWith, indexOf retournera une valeur si elle correspond à n'importe quel endroit de la chaîne donnée, je ne suggère pas d'utiliser indexOf.
RajKumar Samala
12
indexOffait valeur de retour, mais @Jona a vérifié que la valeur de retour est zéro (la chaîne est au début), ce qui signifie qu'il est un bon remplacement pour startsWith!
SharpC
C'est la même fonctionnalité que le polyfill sans avoir à ajouter un polyfill ou à apporter une bibliothèque supplémentaire. C'est une excellente solution - le seul inconvénient que je peux voir est peut-être la lisibilité du code - l'intention est plus claire lorsque la fonction est nommée startsWith.
John T
13

Si cela se produit dans l'application Angular 2+, vous pouvez simplement décommenter les polyfills de chaîne dans polyfills.ts :

import 'core-js/es6/string';
Vitaliy Ulantikov
la source
J'ai ajouté le correctif polyfill d'Oka, mais cela n'a pas fonctionné pour moi sur mon application Angular 5, mais je l'ai import 'core-js/es6/string';corrigé. Merci beaucoup!
decebal
5

Remplacez la fonction startsWith par:

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

Cela prendra en charge tous les navigateurs, y compris IE

La position peut être définie sur 0 pour la correspondance de chaîne à partir du début signifiant la position 0.

Pantalon Harshit
la source
Solution utile sans avoir à réécrire des prototypes ni à utiliser des polyfills. De plus, il est largement compatible entre les navigateurs. +1
Sergio A.
2

Comme d'autres l'ont dit, beginWith et endsWith font partie de ES6 et ne sont pas disponibles dans IE11. Notre société utilise toujours la bibliothèque lodash comme solution polyfill pour IE11. https://lodash.com/docs/4.17.4

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

Bien que le poste d'Oka fonctionne très bien, il est peut-être un peu obsolète. J'ai compris que lodash pouvait y faire face avec une seule fonction. Si vous avez installé lodash, cela pourrait vous faire gagner quelques lignes.

Essayez simplement:

import { startsWith } from lodash;

. . .

    if (startsWith(yourVariable, 'REP')) {
         return yourVariable;        
    return yourVariable;
       }      
     }
TheGabornator
la source
0

J'ai aussi récemment fait face au problème. J'ai résolu en utilisant ^ qui est similaire à startwith in jquery. Dire,

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

on peut utiliser

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

Ici, str est l'identifiant de l'élément.

Apprentissage des utilisateurs
la source
0

Suivez cette méthode si un problème survient lorsque vous travaillez avec des projets angular2 +

Je cherchais une solution quand j'ai eu cette erreur, et cela m'a amené ici. Mais cette question semble être spécifique mais l'erreur ne l'est pas, c'est une erreur générique. Il s'agit d'une erreur courante pour les développeurs angulaires traitant d'Internet Explorer.

J'ai eu le même problème en travaillant avec angular 2+, et il a été résolu en quelques étapes simples.

Dans les dernières versions Angular, il y a des codes commentés dans le polyfills.ts montre tous les polyfills requis pour le bon fonctionnement des versions d'Internet Explorer IE09, IE10 et 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';

Décommentez les codes et cela fonctionnerait parfaitement dans les navigateurs 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';

Mais vous pourriez voir une baisse des performances dans les navigateurs IE par rapport aux autres :(

jithin john
la source