【078】docute.js的v3.4.8版本在IE11下出现【对象不支持“from”属性或方法】错误的解决办法

本文介绍如何解决Docute.js在IE11浏览器中的兼容性问题,通过添加Array.from的polyfill来避免错误,并提供了一个具体实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了实现根据markdown文件标题自动生成树形菜单的功能,我使用了第三方开源库 docute.js。项目地址:https://github.com/egoist/docute

错误重现

克隆项目

git clone https://github.com/egoist/docute.git

切换tag

git checkout v3.4.8

安装依赖

yarn install

编译

npm run prepublish

编译完成后,项目目录下会出现一个dist文件夹,里面是编译好的文件。其中对我们有用的是: docute.css、docute.js 和 theme-github.css。其中 docute.css 和 docute.js 是该项目必须要有的两个基础文件。 theme-github.css 是用户自定义主题。用户可以根据自己的需要进行修改。把上述三个文件拷贝出来,放到某个目录下(比如E:/dist),同时该目录还要加入两个文件,分别是index.html 和 README.md。

index.html 内容如下:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
  <title>./docs1</title>
  <link rel="stylesheet" href="docute.css">
   <link rel="stylesheet" href="theme-github.css"> 
</head>
<body>
  <div id="app"></div>
  <script src="docute.js"></script>
  <script>
    docute.init({});
  </script>
</body>
</html>

而 README.md 文件是这个开源项目默认要展示的 Markdown 文件。

用任意一个 HTTP 服务器,把 E:/dist 作为项目目录。比如你可以用 nginx 作为 HTTP 服务器。

用 IE 11 打开服务器地址。按 F12 打开控制台。把鼠标放到页面上,用鼠标滚轮滚动一下,就会报错。错误信息如下:

SCRIPT438: 对象不支持“from”属性或方法
文件: docute.js,行: 1,列: 141708

解决方法

产生问题的原因是 IE 11 不支持es6的 Array.form 函数。幸好我们可以利用JS的特性,为 Array 加上form函数。polyfill 方法可以参照这个地址: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/from

在 docute/src 文件夹下面新建一个 polyfill.js 文件,文件内容如下:

// Production steps of ECMA-262, Edition 6, 22.1.2.1
if (!Array.from) {
  Array.from = (function () {
    var toStr = Object.prototype.toString;
    var isCallable = function (fn) {
      return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
    };
    var toInteger = function (value) {
      var number = Number(value);
      if (isNaN(number)) { return 0; }
      if (number === 0 || !isFinite(number)) { return number; }
      return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
    };
    var maxSafeInteger = Math.pow(2, 53) - 1;
    var toLength = function (value) {
      var len = toInteger(value);
      return Math.min(Math.max(len, 0), maxSafeInteger);
    };

    // The length property of the from method is 1.
    return function from(arrayLike/*, mapFn, thisArg */) {
      // 1. Let C be the this value.
      var C = this;

      // 2. Let items be ToObject(arrayLike).
      var items = Object(arrayLike);

      // 3. ReturnIfAbrupt(items).
      if (arrayLike == null) {
        throw new TypeError('Array.from requires an array-like object - not null or undefined');
      }

      // 4. If mapfn is undefined, then let mapping be false.
      var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
      var T;
      if (typeof mapFn !== 'undefined') {
        // 5. else
        // 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
        if (!isCallable(mapFn)) {
          throw new TypeError('Array.from: when provided, the second argument must be a function');
        }

        // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
        if (arguments.length > 2) {
          T = arguments[2];
        }
      }

      // 10. Let lenValue be Get(items, "length").
      // 11. Let len be ToLength(lenValue).
      var len = toLength(items.length);

      // 13. If IsConstructor(C) is true, then
      // 13. a. Let A be the result of calling the [[Construct]] internal method 
      // of C with an argument list containing the single item len.
      // 14. a. Else, Let A be ArrayCreate(len).
      var A = isCallable(C) ? Object(new C(len)) : new Array(len);

      // 16. Let k be 0.
      var k = 0;
      // 17. Repeat, while k < len… (also steps a - h)
      var kValue;
      while (k < len) {
        kValue = items[k];
        if (mapFn) {
          A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
        } else {
          A[k] = kValue;
        }
        k += 1;
      }
      // 18. Let putStatus be Put(A, "length", len, true).
      A.length = len;
      // 20. Return A.
      return A;
    };
  }());
}

docute/src/index.js 文件中,引入 polyfill.js 文件,代码片段如下:

// Polyfills
import 'web-polyfill'
import 'unfetch/polyfill'
import "./polyfill";  // 新引入的polyfill.js 文件 
import 'element-closest'

最后重新编译,即可解决此问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值