O código não está sendo executado no IE 11, funciona bem no Chrome

156

O código a seguir pode ser executado sem problemas no Chrome, mas gera o seguinte erro no Internet Explorer 11.

O objeto não suporta a propriedade ou o método 'beginWith'

Estou armazenando a identificação do elemento em uma variável. Qual é o 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
fonte
9
Você provavelmente precisará usar o str.indexOf("REP") == 0IE.
Grant Thomas
1
O ES6 ainda não é um padrão kangax.github.io/compat-table/es6 Existe uma biblioteca de shim ES6 para ajudar na transição github.com/paulmillr/es6-shim Assim como no ES5 (incluindo nem tudo é shimmable)
Xotic750

Respostas:

320

String.prototype.startsWith é um método padrão na versão mais recente do JavaScript, ES6.

Observando a tabela de compatibilidade abaixo, podemos ver que ela é suportada em todas as principais plataformas atuais, exceto nas versões do Internet Explorer.

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

Você precisará se implementar .startsWith. Aqui está o polyfill :

if (!String.prototype.startsWith) {
  String.prototype.startsWith = function(searchString, position) {
    position = position || 0;
    return this.indexOf(searchString, position) === position;
  };
}
Oka
fonte
3
há outra implementação em docs web MDN String.prototype.startsWith = function(search, pos) { return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; };
oCcSking
1
Tendo em conta a primeira implementação dada pelo @Oka. Assim como um refinamento adicional, pode-se testar se a "posição" é realmente numérica: position =! IsNaN (parseInt (position))? posição: 0;
ErnestV 15/01/19
36

text.indexOf("newString")é o melhor método em vez de startsWith.

Exemplo:

var text = "Format";
if(text.indexOf("Format") == 0) {
    alert(text + " = Format");
} else {
    alert(text + " != Format");
}
Jona
fonte
Por que é o melhor método?
TylerH
1
O método indexOf não substitui o beginWith, indexOf retornará valor se corresponder a qualquer lugar em uma determinada string, não sugiro usar indexOf.
precisa saber é o seguinte
12
indexOfretorna valor, mas @Jona verificou que o valor retornado é zero (ou seja, a string está no início), o que significa que é um bom substituto para startsWith!
SharpC
Essa é a mesma funcionalidade que o polyfill sem precisar adicionar um polyfill ou trazer uma biblioteca extra. É uma excelente solução - a única desvantagem que posso ver é talvez a legibilidade do código - a intenção é mais clara quando a função é denominada beginWith.
John T
13

Se isso estiver acontecendo no aplicativo Angular 2+, você pode apenas descomentar polyfills de string em polyfills.ts :

import 'core-js/es6/string';
Vitaliy Ulantikov
fonte
Adicionei a correção de polyfill do Oka, mas ela não funcionou para mim no meu aplicativo Angular 5, mas a corrigi import 'core-js/es6/string';. Muito Obrigado!
Decebal
5

Substitua a função beginWith por:

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

Isso suportará todos os navegadores, incluindo o IE

A posição pode ser definida como 0 para correspondência de string desde o início, significando a 0ª posição.

Harshit Pant
fonte
Solução útil sem precisar reescrever protótipos nem usar polyfills. Além disso, é amplamente compatível entre os navegadores. +1
Sergio A.
2

Como já foi dito, beginWith e endsWith fazem parte do ES6 e não estão disponíveis no IE11. Nossa empresa sempre usa a biblioteca lodash como uma solução de polyfill para o IE11. https://lodash.com/docs/4.17.4

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

Enquanto o post de Oka está funcionando muito bem, pode estar um pouco desatualizado. Eu descobri que lodash pode lidar com isso com uma única função. Se você tiver o lodash instalado, poderá economizar algumas linhas.

Apenas tente:

import { startsWith } from lodash;

. . .

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

Eu também recentemente enfrentei o problema. Eu resolvi usando ^, que é semelhante ao iniciar com jquery. Dizer,

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

podemos usar

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

Aqui, str é id do elemento.

Aprendizado do Usuário
fonte
0

Siga este método se houver algum problema ao trabalhar com projetos angular2 +

Eu estava procurando uma solução quando recebi esse erro, e ele me trouxe aqui. Mas esta questão parece ser específica, mas o erro não é, é um erro genérico. Este é um erro comum para desenvolvedores angulares que lidam com o Internet Explorer.

Eu tive o mesmo problema ao trabalhar com o angular 2+, e ele foi resolvido apenas com algumas etapas simples.

Nas versões mais recentes do Angular, existem códigos comentados no polyfills.ts mostra todos os polyfills necessários para o bom funcionamento nas versões IE09, IE10 e IE11 do Internet Explorer

/** 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';

Remova o comentário dos códigos e funcionaria perfeitamente nos 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';

Mas você pode observar uma queda no desempenho nos navegadores IE em comparação com outros :(

jithin john
fonte