使用 vanilla js 按需加载脚本文件

Jen*_*ell 6 javascript loading

我使用手风琴或标签。单击选项卡时,我想显示地图或需要加载大 javascript 文件的内容。

为了在不需要时不加载大 javascript,我只想在单击选项卡时加载它。

我怎样才能做到这一点?我用手风琴和点击事件创建了一个很好的起点。

  • 我使用 vanilla js(纯 javascript - 没有 jQuery)
  • 我在网页上使用它(不是 nodejs)
  • 如果它适用于现代浏览器,我很好(不需要 IE)

window.addEventListener('DOMContentLoaded', () => {
  document.querySelector('[data-trigger]').addEventListener('click', () => {
    console.log('Load script from file');
    // CDN example - https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/1.12.0/mapbox-gl.js
  });
});
Run Code Online (Sandbox Code Playgroud)
ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

label {
  display: flex;
  align-items: center;
}

label:before {
  content: '';
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M13.172 12l-4.95-4.95 1.414-1.414L16 12l-6.364 6.364-1.414-1.414z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  width: 24px;
  height: 24px;
}

input[type=checkbox] {
  display: none;
}

input[type=checkbox]:checked ~ h2 label:before {
  transform: rotate(90deg);
}

p {
  display: none;
}

input[type=checkbox]:checked ~ h2 ~ p {
  display: block;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>
    <input type="checkbox" id="faq-1">
    <h2 data-trigger>
      <label for="faq-1">Click to load map</label>
    </h2>
    <p>Gummies marzipan croissant chupa chups.</p>
  </li>

  <li>
    <input type="checkbox" id="faq-2">
    <h2>
      <label for="faq-2">Something else</label>
    </h2>
    <p>Cookie bear claw carrot cake croissant.</p>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

msb*_*bit 4

由于您习惯于仅支持现代浏览器,因此您可以使用动态import()函数来加载文件:

window.addEventListener('DOMContentLoaded', () => {
  document.querySelector('[data-trigger]').addEventListener('click', async() => {
    const module = await import('https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/1.12.0/mapbox-gl.js');
    console.log(`module is loaded: ${Object.keys(mapboxgl)}`);
  });
});
Run Code Online (Sandbox Code Playgroud)
ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

label {
  display: flex;
  align-items: center;
}

label:before {
  content: '';
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M13.172 12l-4.95-4.95 1.414-1.414L16 12l-6.364 6.364-1.414-1.414z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  width: 24px;
  height: 24px;
}

input[type=checkbox] {
  display: none;
}

input[type=checkbox]:checked~h2 label:before {
  transform: rotate(90deg);
}

p {
  display: none;
}

input[type=checkbox]:checked~h2~p {
  display: block;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>
    <input type="checkbox" id="faq-1">
    <h2 data-trigger>
      <label for="faq-1">Click to load map</label>
    </h2>
    <p>Gummies marzipan croissant chupa chups.</p>
  </li>

  <li>
    <input type="checkbox" id="faq-2">
    <h2>
      <label for="faq-2">Something else</label>
    </h2>
    <p>Cookie bear claw carrot cake croissant.</p>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

import()返回一个在成功获取时解析的承诺,并在后续调用中立即解析(在我的测试中),因此您不必专门处理该问题。

对于您的特定mapbox-gl脚本,返回的值不会有用,因为该脚本不是作为 ES6 模块编写的,但脚本运行的副作用将就位(在本例中,变量mapboxgl被分配到globalThis) 。在加载的脚本是模块的场景下(export正确使用),可以直接使用解析后的值,避免污染全局命名空间。