IE 11中代码无法运行,但在Chrome中可以正常工作。

164
以下代码可以在Chrome中正常运行,但在Internet Explorer 11中会出现以下错误。

对象不支持属性或方法“startsWith”

我将元素的ID存储在变量中。问题是什么?

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>


10
对于IE浏览器,你可能需要使用str.indexOf("REP") == 0 - Grant Thomas
1
ES6 还不是一个标准 https://kangax.github.io/compat-table/es6/ 有一个 ES6 shim 库来帮助过渡 https://github.com/paulmillr/es6-shim/ 就像 ES5 一样(包括并非所有内容都可以 shimmable)。 - Xotic750
8个回答

334

String.prototype.startsWith 是 JavaScript 最新版本 ES6 中的标准方法。

从下面的兼容性表格可以看出,它在所有当前主要平台上都得到了支持,除了 Internet Explorer 版本。

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

你需要自己实现 .startsWith 方法。这里有一个 polyfill

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

3
MDN Web Docs中有另一种实现方法:String.prototype.startsWith = function(search, pos) { return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; }; 这段代码的作用是充当 "startsWith" 方法的 polyfill。 - oCcSking
1
我倾向于使用@Oka提供的第一种实现。只是作为额外的改进,可以测试“position”是否真正为数字: position = !isNaN(parseInt(position)) ? position : 0; - ErnestV

40

text.indexOf("newString")是比startsWith更好的方法。

示例:

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

为什么这是最佳方法? - TylerH
1
indexOf方法并不是startsWith的替代品,如果匹配字符串中的任何位置,则indexOf将返回值,我不建议使用indexOf。 - Raj Kumar Samala
13
indexOf确实会返回值,但@Jona已经检查了返回值为零(即字符串在开头),这意味着它“startsWith”的很好替代品! - SharpC
这与使用polyfill或引入额外库相同的功能。这是一个很好的解决方案-唯一的缺点可能是代码可读性-当函数命名为startsWith时,意图更加清晰。 - John T

14

如果这是在 Angular 2+ 应用程序中发生的情况,您可以只需在 polyfills.ts 文件中取消注释字符串 polyfills:

import 'core-js/es6/string';

我添加了Oka的polyfill修复,但在我的Angular 5应用程序上它没有起作用,但是import 'core-js/es6/string';解决了问题。非常感谢! - decebal
看起来 polyfill 已经移动到 import 'core-js/es/string';。我使用的是 Angular 10。不过 import 'core-js/stable/string/starts-with'; 似乎更好。 - Richard

7

将startsWith函数替换为:

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

这将支持所有浏览器,包括IE。

位置可以设置为0,表示从开头进行字符串匹配,即第0个位置。


有用的解决方案,无需重写原型或使用 polyfills。此外,在各种浏览器中都具有广泛的兼容性。+1 - Sergio A.

2

正如其他人所说,startsWith和endsWith是ES6的一部分,而在IE11中不可用。我们公司总是使用lodash库作为IE11的polyfill解决方案。https://lodash.com/docs/4.17.4

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

0

虽然Oka的帖子很好用,但可能有点过时了。我发现lodash可以用一个函数解决它。如果你已经安装了lodash,这可能会为你节省几行代码。

只需尝试:

import { startsWith } from lodash;

. . .

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

0

我最近也遇到了这个问题。我使用了类似于jquery中的startwith的^来解决它。比如说,

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

我们可以使用

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

这里,str 是元素的 id。


0

如果在使用Angular2+项目时遇到问题,请按照以下方法操作

我在寻找解决方案时遇到了这个错误,并且它把我带到了这里。但是这个问题似乎很具体,但是错误并非如此,它是一个通用的错误。这是Angular开发人员在处理Internet Explorer时常见的错误。

当我使用Angular 2+工作时,我遇到了同样的问题,并且只需要几个简单的步骤就解决了。

在最新版本的Angular中,在 polyfills.ts 中有一些注释代码,显示了在Internet Explorer版本IE09、IE10和IE11中顺畅运行所需的所有Polyfills。

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

取消代码注释,它将在 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';

但是你可能会在IE浏览器中看到性能下降,与其他浏览器相比 :(


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接