El código no se ejecuta en IE 11, funciona bien en Chrome

156

El siguiente código se puede ejecutar sin problemas en Chrome, pero arroja el siguiente error en Internet Explorer 11.

El objeto no es compatible con la propiedad o el método 'comienza con'

Estoy almacenando la ID del elemento en una variable. ¿Cual es el problema?

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
fuente
9
Es probable que deba usar str.indexOf("REP") == 0para IE en su lugar.
Grant Thomas
1
ES6 todavía no es un estándar kangax.github.io/compat-table/es6 Hay una biblioteca de shim ES6 para ayudar a la transición github.com/paulmillr/es6-shim Al igual que para ES5 (incluso no todo es shimmable)
Xotic750

Respuestas:

320

String.prototype.startsWith es un método estándar en la versión más reciente de JavaScript, ES6.

Mirando la tabla de compatibilidad a continuación, podemos ver que es compatible con todas las plataformas principales actuales, excepto las versiones de Internet Explorer.

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

Tendrá que implementarlo .startsWithusted mismo. Aquí está el polyfill :

if (!String.prototype.startsWith) {
  String.prototype.startsWith = function(searchString, position) {
    position = position || 0;
    return this.indexOf(searchString, position) === position;
  };
}
Oka
fuente
3
hay otra implementación en los documentos web de MDN String.prototype.startsWith = function(search, pos) { return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; };
oCcSking
1
Tiendo a la primera implementación dada por @Oka. Al igual que un refinamiento adicional, uno podría probar que la "posición" sea realmente numérica: position =! IsNaN (parseInt (position))? posición: 0;
ErnestV
36

text.indexOf("newString")Es el mejor método en lugar de startsWith.

Ejemplo:

var text = "Format";
if(text.indexOf("Format") == 0) {
    alert(text + " = Format");
} else {
    alert(text + " != Format");
}
Jona
fuente
¿Por qué es el mejor método?
TylerH
1
El método indexOf no reemplaza el inicio Con, indexOf devolverá el valor si coincide con alguna parte de la cadena dada, no sugiero usar indexOf.
RajKumar Samala
12
indexOfsí devuelve el valor, pero @Jona ha comprobado que el valor de retorno es cero (es decir, la cadena está al principio), lo que significa que es un buen reemplazo para startsWith!
SharpC
Esta es la misma funcionalidad que el polyfill sin tener que agregar un polyfill o traer una biblioteca adicional. Es una solución excelente, el único inconveniente que puedo ver es quizás la legibilidad del código, la intención es más clara cuando la función se llama comienza con.
John T
13

Si esto sucede en la aplicación Angular 2+, puede simplemente descomentar los polyfills de cadenas en polyfills.ts :

import 'core-js/es6/string';
Vitaliy Ulantikov
fuente
Agregué la corrección polyfill de Oka, pero no funcionó para mí en mi aplicación Angular 5, pero la import 'core-js/es6/string';arreglé. ¡Muchas gracias!
decebal
5

Reemplace la función beginWith con:

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

Esto será compatible con todos los navegadores, incluido IE

La posición se puede establecer en 0 para la coincidencia de cadenas desde el inicio, lo que significa la posición 0.

Harshit Pant
fuente
Solución útil sin tener que reescribir prototipos ni usar polyfills. Además, es ampliamente compatible entre los navegadores. +1
Sergio A.
2

Como otros han dicho, comienza con y termina con son parte de ES6 y no están disponibles en IE11. Nuestra empresa siempre usa la biblioteca lodash como una solución de polyfill para IE11. https://lodash.com/docs/4.17.4

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

Si bien la publicación de Oka está funcionando muy bien, podría estar un poco desactualizada. Descubrí que lodash puede abordarlo con una sola función. Si tiene instalado lodash, puede ahorrarle algunas líneas.

Sólo inténtalo:

import { startsWith } from lodash;

. . .

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

También me enfrenté recientemente al problema. Resolví usando ^, que es similar a comenzar con in jquery. Decir,

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

nosotros podemos usar

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

Aquí, str es id del elemento.

Aprendizaje del usuario
fuente
0

Siga este método si surge un problema al trabajar con proyectos de angular2 +

Estaba buscando una solución cuando recibí este error, y me trajo aquí. Pero esta pregunta parece ser específica, pero el error no lo es, es un error genérico. Este es un error común para los desarrolladores angulares que trabajan con Internet Explorer.

Tuve el mismo problema mientras trabajaba con angular 2+, y se resolvió con solo unos simples pasos.

En las últimas versiones de Angular, hay códigos comentados en polyfills.ts muestra todos los polyfills necesarios para el correcto funcionamiento en las versiones de Internet Explorer IE09, IE10 e 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';

Descomenta los códigos y funcionaría perfectamente en los navegadores 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';

Pero es posible que vea una disminución del rendimiento en los navegadores IE en comparación con otros :(

jithin john
fuente