聊一聊原生浏览器中的模块,动态加载JS函数
分类:前端技术

聊风流浪漫聊原生浏览器中的模块

2018/07/04 · 底子技能 · 浏览器

初藳出处: 记   

自从ES二零一四杀青以来,大家透过 Babel 等转移工具得以在等级次序中平昔动用【模块】。前端模块化开荒已是不可翻盘,在 ECMAScript module 以前大家经过 requirejs、seajs、LABjs,甚至最先的时候大家透过闭包来兑现模块化开采。近期有个别主流的的浏览器商家已经在他们新版的浏览器中原生补助了【模块】,前日我们就来原生浏览器中的模块到底怎样。

一时原生帮忙模块用法的浏览器有:

  • Safari 10.1
  • Chrome 61
  • Firefox 60
  • Edge 16

要动用原生浏览器的模块,你只须求在 script 标签上增添多少个 type=module 属性, 浏览器就能把这一个剧本(内联脚本可能外联脚本)当作模块来处理。

JavaScript

<script type="module"> import {addTextToBody} from './utils.mjs'; addTextToBody('Modules are pretty cool.'); </script>

1
2
3
4
<script type="module">
  import {addTextToBody} from './utils.mjs';
  addTextToBody('Modules are pretty cool.');
</script>

JavaScript

// utils.mjs export function addTextToBody(text) { const div = document.createElement('div'); div.textContent = text; document.body.appendChild(div); }

1
2
3
4
5
6
// utils.mjs
export function addTextToBody(text) {
  const div = document.createElement('div');
  div.textContent = text;
  document.body.appendChild(div);
}

在线Demo

1.脚本功力
兑现互相之间效率

前方的话

  JS用"分享一切"的主意加载代码,那是该语言中最易出错且轻便令人以为困惑不解的地方。在ES6原先,在应用程序的每贰个JS中定义的一切都分享叁个大局功效域。随着web应用程序变得尤为头昏眼花,JS代码的使用量也起头抓实,那风度翩翩做法会引起难点,如命名冲突和安全主题素材。ES6的二个指标是缓和功用域难题,也为了使JS应用程序显得有序,于是引入了模块。本文将详细介绍ES6中的模块

 

万般的,当大家必要加载js文件的时候都会利用script标签来兑现,肖似于如下代码:

不扶持裸导入(不能通过模块名直接导入)

二个通过海关的模块标记符必得餍足下列规范之生机勃勃:

  • 多个整机的非相对U帕杰罗L。通过 new URL(moduleSpecifier) 使用时不会报错。
  • / 开头。
  • ./ 开头。
  • ../ 开头。

封存其余验证符供以后利用,如导入内置模块。

JavaScript

// 支持: import {foo} from ''; import {foo} from '/utils/bar.mjs'; import {foo} from './bar.mjs'; import {foo} from '../bar.mjs'; // 不支持: import {foo} from 'bar.mjs'; import {foo} from 'utils/bar.mjs';

1
2
3
4
5
6
7
8
// 支持:
import {foo} from 'https://jakearchibald.com/utils/bar.mjs';
import {foo} from '/utils/bar.mjs';
import {foo} from './bar.mjs';
import {foo} from '../bar.mjs';
// 不支持:
import {foo} from 'bar.mjs';
import {foo} from 'utils/bar.mjs';

2.插入脚本的三种情势
行内脚本(Inline Script):最常用的是选拔事件触发on[EventName]
<input type="button" onclick="window.alert("hello,world!")">
<span onmouseover="this.style.backgroundColor='magenta'" onmouseout="this.style.backgroundColor='#00f'" onclick="this.style.visibility='hidden'">Hello world!</span>
或者是javascript伪协议
<a href="javascript:alert('hello world!');return false" >hello</a>
<iframe src="javascript:document.write('<p>Hello world!</p>');"></iframe>
症结:html中会参预多量的代码,不方便人民群众将来的珍惜

概述

  模块是机关运转在从严形式下同期没法退出运营的JS代码。与分享一切布局相反的是,在模块最上部创设的变量不会自行被增多到全局分享功用域,那一个变量仅在模块的头等作用域中留存,並且模块必得导出一些外界代码可以访谈的因素,如变量或函数。模块也得以从任何模块导入绑定

  其它八个模块的表征与作用域关系十分的小,但也很要紧。首先,在模块的顶上部分,this的值是undefined;其次,模块不扶植HTML风格的代码注释,那是从早先时期浏览器余留下来的JS天性

  脚本,也正是其余不是模块的JS代码,则缺少这个特色。模块和别的JS代码之间的差别大概乍生机勃勃看不起眼,不过它们代表了JS代码加载和求值的叁个要害变化。模块真正的魔力到处是仅导出和导入须要的绑定,实际不是将所用东西都放置二个文本。唯有很好地了然了导出和导入才能通晓模块与剧本的分别

 

代码如下:

通过 nomodule 向后非凡

若是当前浏览器扶植 type=module 标签的话会活动忽视 nomodule 标签。那表示你可以将模块揭示给援助模块的浏览器,同一时间可以给不支持模块的浏览器提供包容方案。

JavaScript

<script type="module" src="module.mjs"></script> <script nomodule src="fallback.js"></script>

1
2
<script type="module" src="module.mjs"></script>
<script nomodule src="fallback.js"></script>

在线Demo

内嵌脚本(Internal Script):script成分
<script>
var text="Hello World!";
document.write('<p>' text '</p>');
</script>

导出

  能够用export关键字将有个别己公布的代码揭示给其它模块,在最简便易行的用例中,可以将export放在其余变量、函数或类评释的前方,以将它们从模块导出

// 导出数据
export var color = "red";
export let name = "Nicholas";
export const magicNumber = 7;
// 导出函数
export function sum(num1, num2) {
    return num1   num1;
}
// 导出类
export class Rectangle {
    constructor(length, width) {
        this.length = length;
        this.width = width;
    }
}
// 此函数为模块私有
function subtract(num1, num2) {
    return num1 - num2;
}
// 定义一个函数……
function multiply(num1, num2) {
    return num1 * num2;
}
// ……稍后将其导出
export { multiply };

  在这里个示例中须求小心多少个细节,除了export关键字外,每三个评释与剧本中的一模二样。因为导出的函数和类申明必要有一个称呼,所以代码中的每四个函数或类也确实有其一名称。除非用default关键字,不然不可能用那么些语法导出佚名函数或类

  此外,在定义multiply(卡塔尔函数时不曾当即导出它。由于不须求总是导出证明,能够导出援用,由此这段代码能够运作。别的,这些示例并未导出subtract(卡塔尔函数,任何未显式导出的变量、函数或类都是模块私有的,不能从模块外部访谈

 

<script type="text/javascript" src="example.js"></script>

暗许延迟加载

当网络意况倒霉的时候,脚本加载会窒碍浏览器剖析 HTML。平常大家得以由此在 script 标签上选用 defer 属性来缓慢解决拥塞问题,不过那也会以致脚本唯有在文书档案剖析完结后才奉行,同一时间还要兼任别的延迟脚本的推行种种。私下认可景况下模块脚本的变现相同于 defer — 它不会堵塞 HTML 的拆解分析。

模块脚本的实践队列与使用了 defer 的正规脚本风流洒脱致。

JavaScript

<!-- 那么些剧本履行滞后于… --> <script type="module" src="1.mjs"></script> <!-- …那几个本子… --> <script src="2.js"></script> <!-- …但是早日这一个本子 --> <script defer src="3.js"></script>

1
2
3
4
5
6
<!--  这个脚本执行滞后于… -->
<script type="module" src="1.mjs"></script>
<!-- …这个脚本… -->
<script src="2.js"></script>
<!-- …但是先于这个脚本 -->
<script defer src="3.js"></script>

在线Demo

外联脚本(External Script):也是script成分,可是先把脚本放在多少个js文件中,再经过src属性链接进来
<script src="/path/to/demo.js" ></script>

导入

  从模块中程导弹出的效益能够通过import关键字在另叁个模块中访谈,import语句的三个部分各自是要导入的标记符和标志符应当从哪些模块导入

  那是该语句的骨干情势

import { identifier1, identifier2 } from "./example.js";

  import前边的大括号表示从给定模块导入的绑定(binding卡塔尔(قطر‎,关键字from表示从哪些模块导入给定的绑定,该模块由象征模块路线的字符串内定(被称作模块表明符卡塔尔(英语:State of Qatar)。浏览器选拔的路子格式与传给<script>成分的相似,也正是说,必需把公文增加名也丰盛。另一面,Nodejs则依据基于文件系统前缀区分当麻芋果件和包的惯例。举例,example是多少个包而./example.js是一个本土文件

  当从模块中程导弹入三个绑依期,它就象是使用const定义的均等。不可能定义另三个同名变量(富含导入另八个同名绑定卡塔尔,也不能够在import语句前使用标志符或改变绑定的值

【导入单个绑定】

  假设前边的示范在多个名字为"example.js"的模块中,我们得以导入并以两种艺术选拔这一个模块中的绑定

// 单个导入
import { sum } from "./example.js";
console.log(sum(1, 2)); // 3
sum = 1; // 出错

  即使example.js导出的函数不仅仅二个,但以此示例导入的却独有sum(卡塔尔函数。如若尝试给sum赋新值,结果是抛出三个漏洞非常多,因为不能够给导入的绑定重新赋值

  为了最好地协作五个浏览器和Node.js碰到,必必要在字符串早先包蕴/、./或../来代表要导入的文件

【导入多少个绑定】

  借使想从示例模块导入多个绑定,则能够一览领悟地将它们列出如下

// 多个导入
import { sum, multiply, magicNumber } from "./example.js";
console.log(sum(1, magicNumber)); // 8
console.log(multiply(1, 2)); // 2

  在这里段代码中,从example模块导入3个绑定sum、multiply和magicNumber。之后选择它们,就疑似它们在本地定义的相通

【导入整个模块】

  特殊情形下,可以导入整个模块作为一个纯粹的目的。然后全部的导出都足以看作靶子的质量使用

// 完全导入
import * as example from "./example.js";
console.log(example.sum(1,example.magicNumber)); // 8
console.log(example.multiply(1, 2)); // 2

  在这里段代码中,从example.js中程导弹出的具备绑定被加载到叁个被称作example的指标中。钦赐的导出(sum(卡塔尔(قطر‎函数、mutiply(卡塔尔(قطر‎函数和magicNumber卡塔尔国之后会作为example的属性被访谈。这种导入格式被称作命名空间导入(namespaceimport卡塔尔(قطر‎。因为example.js文件中不真实example对象,故而它看成example.js中有着导出成员的命名空间对象而被创建

  不过,不管在import语句中把四个模块写了多少次,该模块将只进行三回。导入模块的代码实行后,实例化过的模块被保存在内部存款和储蓄器中,只要另四个import语句引用它就可以重复使用它

import { sum } from "./example.js";
import { multiply } from "./example.js";
import { magicNumber } from "./example.js";

  纵然在这里个模块中有3个import语句,但example加载只进行贰回。假诺同贰个应用程序中的别的模块也从example.js导入绑定,那么这一个模块与此代码将接收相仿的模块实例

【导入绑定的三个微妙诡异之处】

  ES6的import语句为变量、函数和类创造的是只读绑定,而不是像符合规律变量同样轻易地援用原始绑定。标志符只有在被导出的模块中能够改革,即就是导入绑定的模块也爱莫能助改造绑定的值

export var name = "huochai";
export function setName(newName) {
    name = newName;
}

  当导入那四个绑定后,setName(卡塔尔国函数能够改造name的值

import { name, setName } from "./example.js";
console.log(name); // "huochai"
setName("match");
console.log(name); // "match"
name = "huochai"; // error

  调用setName("match"卡塔尔(英语:State of Qatar)时会回到导出setName(卡塔尔(英语:State of Qatar)的模块中去实践,并将name设置为"match"。此校勘会自动在导入的name绑定上展现。其缘由是,name是导出的name标记符的地第一名称。本段代码中所使用的name和模块中程导弹入的name不是同叁个

 

不过一贯动用script标签来加载js文件会好似下一些毛病:

内联模块也是延迟加载的

唱过脚本会忽视 defer 可是内联模块总是 defer 的,不管它是或不是引进了动西。

JavaScript

<!-- 那几个本子实施滞后于… --> <script type="module"> addTextToBody("Inline module executed"卡塔尔; </script> <!-- …这个… --> <script src="1.js"></script> <!-- …还应该有这几个… --> <script defer> addTextToBody("Inline script executed"卡塔尔国; </script> <!-- …不过早日那几个. --> <script defer src="2.js"></script>

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 这个脚本执行滞后于… -->
<script type="module">
  addTextToBody("Inline module executed");
</script>
<!-- …这个… -->
<script src="1.js"></script>
<!-- …还有这个… -->
<script defer>
  addTextToBody("Inline script executed");
</script>
<!-- …但是先于这个. -->
<script defer src="2.js"></script>

在线Demo

3.内嵌脚本
蕴含内容类型和情节块

重命名

  一时候,从一个模块导入变量、函数或然类时,恐怕不希望利用它们的原盛名称。幸运的是,能够在导出进程和导入进度中退换导出成分的名称

  若是要运用差异的称呼导出一个函数,则足以用as关键字来内定函数在模块外的名称

function sum(num1, num2) {
    return num1   num2;
}
export { sum as add };

  在这里地,函数sum(卡塔尔(قطر‎是地点名称,add(卡塔尔是导出时选取的称谓。也正是说,当另二个模块要导入这一个函数时,必得使用add那几个名号

import { add } from "./example.js";

  若是模块想使用分歧的称呼来导入函数,也足以应用as关键字

import { add as sum } from "./example.js";
console.log(typeof add); // "undefined"
console.log(sum(1, 2)); // 3

  这段代码导入add(卡塔尔(英语:State of Qatar)函数时使用了二个导入名称来重命名sum(卡塔尔函数(当前上下文中的本地名称卡塔尔(قطر‎。导入时改换函数的本土名称意味着就是模块导入了add(卡塔尔国函数,在当前模块中也从未add(卡塔尔(英语:State of Qatar)标志符

 

1.严苛的读取顺序。由于浏览器遵照<script>在网页中现身的顺序,读取Javascript文件,然后随时运维,导致在三个公文互相信任的状态下,信赖性最小的文书必得放在最前边,依赖性最大的文本必需放在最前面,不然代码会报错。

内联/外联 模块都扶助异步加载

在经常脚本中,async 能让剧本的下载不打断HTML的剖析并在下载完结后赶忙实行。和日常脚本分裂,内联模块脚本协理异步加载的。

相仿的,异步加载的模块只怕不会规行矩步它们在DOM中冒出的逐条施行。

JavaScript

<!-- 这么些会在它引入的剧本加载成功后立时实施 --> <script async type="module"> import {addTextToBody} from './utils.mjs'; addTextToBody('Inline module executed.'卡塔尔国; </script> <!-- 那么些会在其本身以至其引进的剧本加载成功后马上实行 --> <script async type="module" src="1.mjs"></script>

1
2
3
4
5
6
7
<!-- 这个会在它引入的脚本加载完成后立即执行 -->
<script async type="module">
  import {addTextToBody} from './utils.mjs';
  addTextToBody('Inline module executed.');
</script>
<!-- 这个会在其本身以及其引入的脚本加载完成后立即执行 -->
<script async type="module" src="1.mjs"></script>

在线Demo

图片 1

默认值

  由于在诸如CommonJS的别样模块系统中,从模块中导出和导入默许值是四个普及的做法,该语法被开展了优化。模块的默许值指的是透过default关键字钦定的单个变量、函数或类,只可以为各种模块设置八个暗中认可的导出值,导出时频仍使用default关键字是三个语法错误

【导出暗许值】

  上面是一个行使default关键字的粗略示例

export default function(num1, num2) {
    return num1   num2;
}

  这么些模块导出了八个函数作为它的暗中认可值,default关键字表示这是三个暗中同意的导出,由于函数被模块所代表,因此它没有必要一个称号

  也得以在export default其后增加暗许导出值的标志符,就好像这样

function sum(num1, num2) {
    return num1   num2;
}
export default sum;

  先定义sum(卡塔尔(英语:State of Qatar)函数,然后再将其导出为暗许值,假诺急需总结暗中认可值,则足以使用那一个方法。为暗许导出值钦点标识符的第二种办法是行使重命名语法,如下所示

function sum(num1, num2) {
    return num1   num2;
}
export { sum as default };

  在重命名导出时标记符default具备特别意义,用来提醒模块的暗许值。由于default是JS中的默许关键字,因而不可能将其用于变量、函数或类的名目;然而,能够将其看作属性名称。所以用default来重命超模块是为了尽只怕与非暗许导出的概念大器晚成致。如果想在一条导出语句中相同的时候内定三个导出(满含默许导出卡塔尔,这几个语法非常管用

【导入暗中认可值】

  能够动用以下语法从三个模块导入多个暗许值

// 导入默认值
import sum from "./example.js";
console.log(sum(1, 2)); // 3

  这条import语句从模块example.js中程导弹入了暗中同意值,请介意,这里未有行使大括号,与非暗许导入的意况各异。本地名称sum用于表示模块导出的别样私下认可函数,这种语法是最纯粹的,ES6的创制者希望它能够形成web上主流的模块导入方式,何况能够利用已部分对象

  对于导出暗中认可值和朝气蓬勃或多少个非默许绑定的模块,能够用一条语句导入全数导出的绑定

export let color = "red";
export default function(num1, num2) {
    return num1   num2;
}

  能够用以下那条import语句导入color和暗中同意函数

import sum, { color } from "./example.js";
console.log(sum(1, 2)); // 3
console.log(color); // "red"

  用逗号将暗中认可的本土名称与大括号包裹的非暗中同意值分隔开分离

  [注意]在import语句中,暗许值必需排在非暗中同意值以前

  与导出私下认可值一样,也得以在导入暗中同意值时利用重命名语法

// 等价于上个例子
import { default as sum, color } from "example";
console.log(sum(1, 2)); // 3
console.log(color); // "red"

  在此段代码中,暗许导出(export卡塔尔国值被重命名称叫sum,而且还导入了color

 

2.品质难点。浏览器接收"同步方式"加载<script>标签,也即是说,页面会"堵塞"(blocking),等待javascript文件加载成功,然后再运营后边的HTML代码。当存在多少个<script>标签时,浏览器不可能同期读取,必需读取完三个再去读取另一个,形成读取时间大大延长,页面响应缓慢。

模块只进行一遍

假使你接受过ES6的模块, 那么您早晚明白您可以频频引进同一模块可是她们只会实践一遍。在Html中也生龙活虎律, 七个U奥迪Q5L模块脚本在多少个页面中只会实行一遍。

JavaScript

<!-- 1.mjs 施行叁次 --> <script type="module" src="1.mjs"></script> <script type="module" src="1.mjs"></script> <script type="module"> import "./1.mjs"; </script> <!-- 这几个会执行数次 --> <script src="2.js"></script> <script src="2.js"></script>

1
2
3
4
5
6
7
8
9
<!-- 1.mjs 执行一次 -->
<script type="module" src="1.mjs"></script>
<script type="module" src="1.mjs"></script>
<script type="module">
  import "./1.mjs";
</script>
<!-- 这个会执行多次 -->
<script src="2.js"></script>
<script src="2.js"></script>

在线Demo

内嵌脚本

静态加载

   ES6中的模块与node.js中的模块加载不相同,nodeJS中的require语句是运维时加载,而ES6中的import是静态加载,所以有局地语法节制

  1、不能够动用表明式和变量等那几个仅有在运作时技艺获得结果的语法布局

// 报错
import { 'f'   'oo' } from 'my_module';

// 报错
let module = 'my_module';
import { foo } from module;

  2、importexport一声令下只能在模块的顶层,不能够在代码块之中,如不能够在if语句和函数内选取

if (flag) {
    export flag; // 语法错误
}

// 报错
if (x === 1) {
  import { foo } from 'module1';
} else {
  import { foo } from 'module2';
}

function tryImport() {
    import flag from "./example.js"; // 语法错误
}

  以上的写法会报错,是因为在静态分析阶段,这个语法都以无奈获得值的

  那样的宏图,尽管有助于编译器提升功用,但也招致无法在运作时加载模块。在语法上,条件加载就不容许达成。假设import命令要代表 Node 的require格局,那就形成了一个阻力。因为require是运营时加载模块,import指令无法代表require的动态加载功效

const path = './'   fileName;
const myModual = require(path);

  上边的说话正是动态加载,require到底加载哪三个模块,唯有运行时才晓得。import语句做不到这或多或少

 

其临时候大家就能够想到去动态加载JS,动态加载js的落到实处格局相像于如下代码

遵循 CORS

不一样于普通脚本,跨站引用模块脚本(及其引进)须要依据COTiguanS。 那象征跨源模块脚本必需回到有效的CO大切诺基S头,比方Access-Control-Allow-Origin:*。

JavaScript

<!-- CO福特ExplorerS考验战败,不会施行 --> <script type="module" src="; <!-- 引进的模块CO揽胜极光S考验退步,不会施行 --> <script type="module"> import ''; addTextToBody("This will not execute."); </script> <!-- COHighlanderS核准通过,会奉行 --> <script type="module" src=";

1
2
3
4
5
6
7
8
9
<!-- CORS检验失败,不会执行 -->
<script type="module" src="https://….now.sh/no-cors"></script>
<!-- 引入的模块CORS检验失败,不会执行 -->
<script type="module">
  import 'https://….now.sh/no-cors';
  addTextToBody("This will not execute.");
</script>
<!-- CORS检验通过,会执行 -->
<script type="module" src="https://….now.sh/cors"></script>

在线Demo

Classic Script:
type属性暗中同意值是:text/javascript
必须填写合法的Javascript脚本项目(此处省略)
建议不写type

再也导出

  只怕须要再行导出模块已经导入的从头到尾的经过

import { sum } from "./example.js";
export { sum }

  即便如此能够运作,但只通过一条语句也能够做到相符的天职

export { sum } from "./example.js";

  这种情势的export在钦定的模块中查找sum申明,然后将其导出。当然,对于同后生可畏的值也得以不一致的名号导出

export { sum as add } from "./example.js";

  这里的sum是从example.js导入的,然后再用add那么些名字将其导出

  假如想导出另三个模块中的全体值,则能够动用*模式

export * from "./example.js";

  导出一切是辅导出暗中认可值及具备命名导出值,那恐怕会耳濡目染能够从模块导出的剧情。举个例子,倘若example.js有暗许的导出值,则使用此语法时将不可能定义一个新的私下认可导出

 

代码如下:

无需证据

本着同源央求,大多数依照CO景逸SUVS的API必要央求带上凭证(如:cookie),可是 fetch() 和模块脚本是个分歧,他们默许不会带上相关凭证除非您肯定钦定。

设若您想在同源央浼模块脚本时带上凭证,能够安装 crossorigin 属性。如若跨站必要也想带上的话,能够设置 crossorigin="use-credentials",供给小心的是跨站的站点必要在倡议重临头中增多 Access-Control-Allow-Credentials: true

JavaScript

<!-- 有凭证 (cookies) --> <script src="1.js"></script> <!-- 无凭证 --> <script type="module" src="1.mjs"></script> <!-- 有凭证 --> <script type="module" crossorigin src="1.mjs?"></script> <!-- 无凭证 --> <script type="module" crossorigin src="; <!-- 有凭证 --> <script type="module" crossorigin="use-credentials" src=";

1
2
3
4
5
6
7
8
9
10
<!-- 有凭证 (cookies) -->
<script src="1.js"></script>
<!-- 无凭证 -->
<script type="module" src="1.mjs"></script>
<!-- 有凭证  -->
<script type="module" crossorigin src="1.mjs?"></script>
<!-- 无凭证 -->
<script type="module" crossorigin src="https://other-origin/1.mjs"></script>
<!-- 有凭证 -->
<script type="module" crossorigin="use-credentials" src="https://other-origin/1.mjs?"></script>

在线Demo

此间还大概有贰个关于 模块只进行三次 的坑。当您通过二个UENCOREL引进一个模块时,假如后生可畏开首你以无凭证的主意呼吁,然后又以有凭证的诀窍再诉求三次,你拿走的归来都以无凭证乞请的这一次。那便是自小编干什么会在第贰次呼吁时在UPAJEROL后增加,用于区分一回号令。

更新:以上大概非常的慢会改造。 暗许情形下,fetch()和模块脚本都会向平等来源的URL发送凭据。

内嵌的时候要非常注意,内容块不要包蕴script的关闭标签,可以通过改造代码的方法来防止浏览器解析错误:
<script>
document.write('<script src="app.js"></script>');
document.write('<script src="app.js"></sc' 'ript>');
document.write('<script src="app.js"></script>');
</script>

无绑定导入

  某个模块可能不导出任黄岳泰西,相反,它们恐怕只修正全局功能域中的对象。固然模块中的顶层变量、函数和类不会自行地出现在全局意义域中,但那并不表示模块不可能访谈全局功用域。内建目的(如Array和Object卡塔尔的分享定义能够在模块中访问,对那些目的所做的改换将体今后别的模块中

  比如,要向全体数组增加pushAll(卡塔尔方法,则能够定义如下所示的模块

// 没有导出与导入的模块
Array.prototype.pushAll = function(items) {
    // items 必须是一个数组
    if (!Array.isArray(items)) {
        throw new TypeError("Argument must be an array.");
    }
    // 使用内置的 push() 与扩展运算符
    return this.push(...items);
};

  纵然未有别的导出或导入的操作,这也是叁个有效的模块。这段代码不仅可以够当作模块也足以当做脚本。由于它不导出其余事物,由此能够接收简化的导入操作来实践模块代码,况且不导入任何的绑定

import "./example.js";
let colors = ["red", "green", "blue"];
let items = [];
items.pushAll(colors);

  这段代码导入并施行了模块中带有的pushAll(卡塔尔方法,所以pushAll(卡塔尔国被增加到数组的原型,相当于说以往模块中的全体数组都得以运用pushAll(卡塔尔国方法了

  [注意]无绑定导入最有希望被利用于创立polyfill和Shim

 

/*
*@desc:动态加多script
*@param src:加载的js文件的地址
*@param callback:js文件加载成功今后供给调用的回调函数
*@demo:
addDynamicStyle('', function () {
    alert('驴阿妈服务器上的lab.js加载实现'卡塔尔
});
*/
function addDynamicJS(src, callback) {
    var script = document.createElement("script");
    script.setAttribute("type", "text/javascript");
    script.src = src[i];
    script.charset = 'gb2312';
    document.body.appendChild(script);
    if (callback != undefined) {
        script.onload = function () {
            callback();
        }
    }
}

Mime-types

与平时脚本不一致,模块脚本必需提供可行的JavaScript MIME类型,不然它们将不会推行。 HTML标准建议使用 text/javascript

1 赞 1 收藏 评论

图片 2

type类型还是能够设置成数据块, 那样浏览器不做脚本深入分析
<script type="text/plain">
hello world!!
</script>

加载模块

  即便ES6定义了模块的语法,但它并不曾概念如何加载这些模块。那多亏标准复杂性的一个反映,应由分裂的贯彻蒙受来决定。ES6未有品味为具备JS情形创设风姿浪漫套统豆蔻梢头的行业内部,它只规定了语法,并将加运载飞机制抽象到一个未定义的内部方法HostResolveImportedModule中。Web浏览器和Node.js开拓者能够通过对各自情状的体味来支配哪些落到实处HostResolveImportedModule 

【在Web浏览器中利用模块】

  固然在ES6产出早前,Web浏览器也可以有二种办法得以将JS满含在Web应用程序中,这一个本子加载的点子分别是

  1、在<script>元素中通过src属性钦命三个加载代码的地址来加载JS代码文件

  2、将JS代码内嵌到未有src属性的<script>成分中

  3、通过Web Worker或Service Worker的主意加载并奉行JS代码文件

  为了完全援助模块作用,Web浏览器必需立异这几个机制

在<script>中接受模块

  <script>成分的暗中认可行为是将JS文件作为脚本加载,而非作为模块加载,当type属性缺失或含有一个JS内容类型(如"text/javascript"卡塔尔(قطر‎时就能够发生这种情景。<script>成分得以推行内联代码或加载src中钦命的文本,当type属性的值为"module"时扶助加载模块。将type设置为"module"能够让浏览器将享有内联代码或含有在src钦定的文本中的代码根据模块而非脚本的法门加载

<!-- load a module JavaScript file -->
<script type="module" src="module.js"></script>
<!-- include a module inline -->
<script type="module">
  import { sum } from "./example.js";
  let result = sum(1, 2);
</script>

  此示例中的第3个<script>成分运用src属性加载了二个表面包车型地铁模块文件,它与加载脚本之间的唯后生可畏区别是type的值是"module"。第1个<script>成分满含了第一手嵌入在网页中的模块。变量result未有暴光到全局功用域,它只存在于模块中(由<script>成分定义卡塔尔国,因而不会被增加到window作为它的属性

  在Web页面中引进模块的历程看似于引进脚本,相当轻易。不过,模块实际的加载进度却有部分不生机勃勃

  "module"与"text/javascript"这样的内容类型并不相近。JS模块文件与JS脚本文件具备同等的源委类型,因而不能够仅依照剧情类型实行区分。别的,当不可能识别type的值时,浏览器会忽视<script>成分,由此不协助模块的浏览器将机关忽视<script type="module">来提供杰出的向后包容性

Web浏览器中的模块加载顺序

  模块与剧本差异,它是必须要经过的路的,能够通过import关键字来指明其所正视的任何文件,况兼这一个文件必得被加载进该模块才干科学施行。为了扶持该成效,<script type="module">试行时自动应用defer属性

  加载脚本文件时,defer是可选属性加载模块时,它正是必备属性。生龙活虎旦HTML解析器遇到具备src属性的<script type="module">,模块文件便开首下载,直到文书档案被全然剖判模块才会进行。模块根据它们出今后HTML文件中的顺序试行,也正是说,不论模块中含有的是内联代码依然钦赐src属性,第二个<scpipt type="module">总是在第一个在此以前实践

<!-- this will execute first -->
<script type="module" src="module1.js"></script>
<!-- this will execute second -->
<script type="module">
import { sum } from "./example.js";
let result = sum(1, 2);
</script>
<!-- this will execute third -->
<script type="module" src="module2.js"></script>

  那3个<script>成分遵照它们被钦命的顺序实行,所以模块module1.js保险会在内联模块前进行,而内联模块保险会在module2.js模块在此之前施行

  每一种模块都能够从二个或四个其余的模块导入,这会使难点复杂化。因而,首先深入分析模块以识别所有导入语句;然后,每种导入语句都触发一回拿到进程(从网络或从缓存卡塔尔(英语:State of Qatar),並且在具备导入财富都被加载和施行后才会进行业前模块

  用<script type="module">显式引进和用import隐式导入的具备模块都是按需加载并奉行的。在这里个示例中,完整的加载顺序如下

  1、下载并解析module1.js

  2、递归下载并深入分析module1.js中程导弹入的能源

  3、深入解析内联模块

  4、递归下载并深入分析内联模块中程导弹入的财富

  5、下载并深入分析module2.js

  6、递归下载并剖判module2.js中程导弹入的财富

  加载成功后,唯有当文书档案完全被解析之后才会施行其它操作。文书档案剖析达成后,会发生以下操作

  1、递归实行module1.js中程导弹入的能源

  2、执行module1.js

  3、递归实施内联模块中程导弹入的能源

  4、试行内联模块

  5、递归推行module2.js中程导弹入的能源

  6、执行module2.js

  内联模块与其余八个模块唯生龙活虎的两样是,它不必先下载模块代码。不然,加载导入财富和试行模块的相继正是相像的

  [注意]<script type="module">成分会忽略defer属性,因为它执行时defer属性暗许是存在的

Web浏览器中的异步模块加载

  <script>成分上的async属性应用于脚本时,脚本文件将在文书完全下载并深入分析后实行。不过,文书档案中async脚本的顺序不会影响脚本实施的相继,脚本在下载完结后立刻推行,而毋庸等待包涵的文书档案达成深入深入分析

  async属性也足以选用在模块上,在<script type="module">成分上应用async属性会让模块以临近于脚本的点子推行,唯生机勃勃的分别是,在模块实行前,模块中具备的导入能源都必需下载下来。那足以确定保障唯有当模块实行所需的具有财富都下载完结后才实践模块,但不可能确定保障的是模块的推行时机

<!-- no guarantee which one of these will execute first -->
<script type="module" async src="module1.js"></script>
<script type="module" async src="module2.js"></script>

  在此个示例中,七个模块文件被异步加载。只是简短地看那么些代码判别不出哪个模块先进行,如若module1.js首先做到下载(富含其有着的导入能源卡塔尔(英语:State of Qatar),它将先进行;要是module2.js首先产生下载,那么它将先施行

将模块作为Woker加载

  Worker,比如Web Worker和瑟维斯Woker,能够在网页上下文之外推行JS代码。创立新Worker的步骤富含创建二个新的Worker实例(或任何的类卡塔尔(قطر‎,传入JS文件之处。暗中认可的加运载飞机制是遵照剧本的格局加载文件

// 用脚本方式加载 script.js
let worker = new Worker("script.js");

  为了辅助加载模块,HTML规范的开采者向这一个构造函数增多了第二个参数,首个参数是一个对象,其type属性的暗许值为"script"。能够将type设置为"module"来加载模块文件

// 用模块方式加载 module.js
let worker = new Worker("module.js", { type: "module" });

  在那示例中,给第三个参数字传送入二个指标,其type属性的值为"module",即根据模块而不是本子的主意加载module.js。(这里的type属性是为着模仿<script>标签的type属性,用以区分模块粤北河南道情本卡塔尔(قطر‎全数浏览器中的Worker类型都援救第1个参数

  Worker模块平日与Worker脚本一同利用,但也会有局地不风姿浪漫。首先,Worker脚本只可以从与援用的网页相仿的源加载,可是Worker模块不会完全受限,固然Worker模块具备相像的私下认可节制,但它们还能够加载并访问具备方便的跨域能源分享(CO安德拉S卡塔尔国头的公文;其次,就算Worker脚本可以运用self.importScripts(卡塔尔方法将其余脚本加载到Worker中,但self.importScripts(卡塔尔国却一贯不能加载Worker模块,因为应该运用import来导入

【浏览器模块表达符分析】

  浏览器供给模块表达符具备以下两种格式之生龙活虎

  1、以/开始的剖析为从根目录早前

  2、以./初步的剖析为从当前目录开端

  3、以../开端的剖判为从父目录开头

  4、URL格式

  比方,假若有三个模块文件坐落于

// 从 https://www.example.com/modules/example1.js 导入
import { first } from "./example1.js";
// 从 from https://www.example.com/example2.js 导入
import { second } from "../example2.js";
// 从 from https://www.example.com/example3.js 导入
import { third } from "/example3.js";
// 从 from https://www2.example.com/example4.js 导入
import { fourth } from "https://www2.example.com/example4.js";

  此示例中的各类模块表达符都适用于浏览器,富含最后风姿洒脱行中的那多少个完整的U卡宴L(为了支持跨域加载,只需保障www2.example.com的COLANDS头的布署是没有错的卡塔尔固然尚无达成的模块加载器标准将提供深入解析其余格式的格局,但眼前,那些是浏览器暗许景况下唯意气风发能够深入分析的模块表明符的格式

  由此,一些看起来寻常的模块表达符在浏览器中实际是行不通的,并且会产生错误

// 无效:没有以 / 、 ./ 或 ../ 开始
import { first } from "example.js";
// 无效:没有以 / 、 ./ 或 ../ 开始
import { second } from "example/index.js";

  由于这七个模块表明符的格式不得法(贫乏科学的前奏字符卡塔尔国,由此它们不可能被浏览器加载,固然在<script>标签中用作src的值时相互都得以健康办事。<script>标签和import之间的这种行为差距是假意为之

 

如此不会促成页面拥塞,但会促成别的贰个主题材料:那样加载的Javascript文件,不在原始的DOM构造之中,由此在DOM-ready(DOMContentLoaded)事件和window.onload事件中钦点的回调函数对它不行。

Module Script:
ES6中进入了极度重大的表征:模块化,module,能够动态的载入模块信任的别的模块文件
诸如api.js中定义了test和greet函数
下一场在剧本中信任api.js文件,那样浏览器拆解解析到这一句的时候就能活动加载api.js中的内容
<script>
import { test, greet } from "./api.js"
</script>

总结

  下直面英特尔、CMD、CommonJS和ES6的module进行计算相比

  AMD是requireJS在放大进程中对模块定义的标准化产出。Intel是叁个正经,只定义语法API,而requireJS是具体的落到实处。相同于ECMAScript和javascript的涉嫌

  由上面代码可以预知,Intel的特征是依附前置,对于依赖的模块提前实行

// AMD
define(['./a', './b'], function(a, b) {  // 依赖必须一开始就写好
    a.doSomething()    
    // 此处略去 n 行    
    b.doSomething()    
    ...
})

  CMD 是 SeaJS 在加大进程中对模块定义的标准化产出,它的性状是注重就近,对于依附的模块延迟实践

// CMD
define(function(require, exports, module) { 
    var a = require('./a')
     a.doSomething()  
    // 此处略去 n 行   
    var b = require('./b') // 依赖可以就近书写  
    b.doSomething()   
    // ... 
})

  CommonJS标准入眼在NodeJS后端使用,前端浏览器不帮助该标准

// math.js
exports.add = function () {
    var sum = 0, i = 0,args = arguments, l = args.length;
    while (i < l) {
        sum  = args[i  ];
    }
    return sum;
};
// program.js
var math = require('math');
exports.increment = function (val) {
    return math.add(val, 1);
};

  ES6的Module模块主要通过export和import来开展模块的导入和导出

//example.js
export default function(num1, num2) {
    return num1   num2;
}
// 导入默认值
import sum from "./example.js";
console.log(sum(1, 2)); // 3

  

此时我们就能够想到用一些外部函数库来有效的军事拘禁JS加载问题。

4.外联脚本
外联脚本的主意最佳常用:
<script src="app.js" type="text/javascript" charset="UTF-8" crossorign="anoymous" async defer></script>

下边踏入正题说说LAB.js

图片 3

LAB.js

历史观脚本

倘若大家使用古板的法子来加载js的话,写的代码平时会如下方代码所示风格。

图片 4

代码如下:

模块化脚本

<script src="aaa.js"></script>
    <script src="bbb-a.js"></script>
    <script src="bbb-b.js"></script>
    <script type="text/javascript">
        initAaa();
        initBbb();
    </script>
    <script src="ccc.js"></script>
    <script type="text/javascript">
        initCcc();
    </script>

个中相比根本的属性是:async、defer(调整脚本的举办措施)
那是布尔属性,设置之后都得以互相加载脚本,差距是
async是当时实践,defer是HTML剖析完现在施行,纵然八个脾气同时设置,优先async法规

如若大家运用LAB.js的话,要贯彻上述代码功能,则使用如下格局

<script>常规方法:

代码如下:

图片 5

<!--先加载lab.js库-->
    <script src=";
    <script type="text/javascript">
        $LAB
        .script("aaa.js"卡塔尔(قطر‎.wait(卡塔尔(英语:State of Qatar)//不带参数的.wait(卡塔尔(英语:State of Qatar)方法表示立即运转刚才加载的Javascript文件
        .script("bbb-a.js")
        .script("bbb-b.js"卡塔尔国//依次加载aaa.js bbb-a.js bbb-b.js  然后实行initAaa initBbb
        .wait(function (){//带参数的.wait(卡塔尔(قطر‎方法也是当时运营刚才加载的Javascript文件,不过还运营参数中钦命的函数。
            initAaa();
            initBbb();
        })
        .script("ccc.js"卡塔尔国//再加载ccc.js 加载达成ccc.js之后试行initCcc方法
        .wait(function () {
            initCcc();
        });
    </script>

健康办法

能够並且运营多条$LAB链,但是它们之间是一心独立的,海市蜃楼程序关系。借使你要作保多少个Javascript文件在另三个文件今后运营,你只可以把它们写在同三个链操作之中。唯有当有个别脚本是一心毫无干系的时候,你才应该寻思把它们分成不一样的$LAB链,表示它们中间荒诞不经相关涉嫌。

<script defer>:

普通的使用示例

图片 6

代码如下:

defer方式

$LAB
.script("script1.js"卡塔尔国 // script1, script2, and script3 相互不依赖, 能够根据自由的逐个实施
.script("script2.js")
.script("script3.js")
.wait(function(){
    alert("Scripts 1-3 are loaded!");
})
.script("script4.js"卡塔尔//必需等待script1.js,script2.js,script3.js执行完成之后工夫举行
.wait(function(){script4Func();});

<script async>:

代码如下:

图片 7

$LAB
.script("script.js")   
.script({ src: "script1.js", type: "text/javascript" })
.script(["script1.js", "script2.js", "script3.js"])
.script(function(){
    // assuming `_is_IE` defined by host page as true in IE and false in other browsers
    if (_is_IE) {
        return "ie.js"; // only if in IE, this script will be loaded
    }
    else {
        return null; // if not in IE, this script call will effectively be ignored
    }
})

async方式

在决定台看LAB.js的加载音讯

crossorigin:调节脚本跨域的时候的加载特性,守旧脚本和模块脚本会有十分大的分化。
Class Script:
-是否走CORS流程
-是还是不是暴光格外的详细新闻
-调整脚本乞求时是还是不是带走客商授信消息,如cookie等

只要你想调节和测量检验或许说在决定台看各样js加载音讯的话,可以使用$LAB.setGlobalDefaults 方法,具体运用请看代码示例。

图片 8

代码如下:

露马脚分外的对待

<!--先加载游侠客的LAB库  lab.js在网络也足以下载-->
    <script type="text/javascript" src="" charset="gb2312"></script>

Module Script:
-调控脚本伏乞时是还是不是带走顾客授信消息,如cookie等
(模块化脚本固然遇上跨域,是必得走CO汉兰达S流程的)

    <script type="text/javascript">

设置anonymous值,能够不带cookie,提议书写:crossorigin="anonymous"

        $LAB.setGlobalDefaults({ Debug: true }卡塔尔国 //张开调节和测量试验

设置use-credentials,带cookie,书写:
crossorigin="use-credentials"

        $LAB
            //第叁个推行链
           .script('')
           .script('')

5.案例
用脚本来完毕响应式构造:
代码好难,再等一等。。。。

           //第4个履行链
           .wait(function () {
               //console.log(window.$)
               //console.log(window._)
           })

其余,对于跨域的知识点依然不太精晓,后面要过细看。

           //第三个推行链
           .script('')
           .script('')

           //第多个试行链
           .wait(function () {
               // console.log(plugin1Function)
               // console.log(plugin2Function)
           })

           //第三个奉行链
           .script('js/aaa.js')
           .script('js/bbb.js')

           //第八个实行链
           .wait(function () {
               // console.log(module1Function)
               // console.log(module2Function)
           })
    </script>

这时张开调节台,看音讯,如下图所示:

图片 9

 

实例

  //加载大的背景图,无法等背景图先展现出来再推行html代码

  <head>

  {insert_scripts files='LAB.min.js'}

  </head>

  <body>

  <script>

  $LAB.script("xxx/js/sign.min.js")

  .wait(卡塔尔(قطر‎ //马上实施

  </script>

  </body>

 

  //除了背景图还应该有更换图,近年来只用到这两种

  <html>

  <head>

  {insert_scripts files='LAB.min.js'}

  </head>

  <body>

  <script>

  $LAB.script("xxx/xxx/js/jquery.flexslider.min.js")

  .wait(function(){

  //banner 滚动

  $('#js_banner').flexslider({
                namespace:"",
                animation: "fade",
                selector: ".slides > li",
                pauseOnAction:false,
                controlNav:true,
                slideshowSpeed: 5000
            });    
    
            $('#whatsnew_pros').flexslider({
                namespace:"",
                animation: "slide",
                selector: ".slides > li",
                itemWidth: 150,
                pauseOnAction:false,
                controlNav:false,
                animationLoop: true,
                slideshow:false,  
                animationSpeed:50,
                minItems: 4,
                maxItems: 5
            });
            $('#seller_pros').flexslider({
                namespace:"",
                animation: "slide",
                selector: ".slides > li",
                itemWidth: 150,
                pauseOnAction:false,
                controlNav:false,
                animationLoop: true,
                slideshow:false,  
                animationSpeed: 50,
                minItems: 4,
                maxItems: 5
            });
            $('#specials_pros').flexslider({
                namespace:"",
                animation: "slide",
                selector: ".slides > li",
                itemWidth: 150,
                pauseOnAction:false,
                controlNav:false,
                animationLoop: true,
                slideshow:false,  
                animationSpeed: 50,
                minItems: 4,
                maxItems: 5
            });
            
            $("#seller_pros").hide();
            $("#specials_pros").hide();
            $("#whatsnew_pros").show();

  })

  </script>

  </body>
  </html>

JavaScript文件加载器LABjs API详细解释

  在《高性能JavaScript》生龙活虎书中提到了LABjs以此用来加载JavaScript文件的类库,LABjs是Loading And Blocking JavaScript的缩写,看名就能够猜到其意义,加载和窒碍JavaScript,而它的API script(卡塔尔和wait(卡塔尔(英语:State of Qatar)则高贵地促成了那七个效果与利益,作者在高品质JavaScript 加载和实行一文中也轻便讲明了这两在那之中央API的用法。当然,LABjs还也许有越来越多的API,本文用实例讲明下LABjs别的API。

$LAB.setGlobalDefaults() & $LAB.setOptions()

  两个所能设置的参数完全风姿洒脱致,区别的是,前面三个是全局设置,成效在具备的$LAB链上;前面一个出今后某条链的起来地点(前面接script(卡塔尔、wait(卡塔尔等),该装置只效力在此条链上。该参数能够是叁个包蕴五个键值对的对象

  • AlwaysPreserveOrder

  二个布尔值(暗中认可false),假设设置为true,则每一个script(卡塔尔(英语:State of Qatar)后都会默许设置贰个wait(卡塔尔,使得链上的台本四个个推行。

图片 10

$LAB
  .setOptions({AlwaysPreserveOrder:true}) // tells this chain to implicitly "wait" on 
                                          // execution (not loading) between each script
  .script("script1.js") // script1, script2, script3, and script4 *DO* depend on each 
  .script("script2.js") // other, and will execute serially in order after all 4 have have
  .script("script3.js") // loaded in parallel
  .script("script4.js")
  .wait(function(){script4Func();});

图片 11

  • UseLocalXHR

  一个布尔值(暗中同意true),假如是true的话,LABjs会用XHR Ajax去预加载同域的剧本文件。值得注意的是,只使用在老式的Webkit浏览器(那多少个既无法利用ordered-async也不能够落到实处真正的预加载的浏览器),并且同域的情事下,该装置才起效(不然直接无视)

  • CacheBust & AllowDuplicates

  LABjs对于缓存有风流倜傥对奇异的管理(关于缓存,能够参见笔者前边的意气风发篇小说浏览器缓存机制浅析),举个例子如下代码:

$LAB.script('index.js');

  超级粗略对啊?第一次载入,未有任何难点,HTTP200从server端下载。不过f5后:图片 12

  (二零一五-8-3 这几个难题不怎么好奇,临时HTTP304,一时HTTP200from cache 小编也在github上询问了小编 LABjs reads from cache when f5,回复的光景意思是cache和labjs未有别的关系,只和服务器和浏览器设置有关)

  居然是从缓存读取的!那便是服务端的改变,对它不起效果!而常常情状下f5后是会向服务器发送央浼的,假使服务端文件并没有退换重临HTTP304读取缓存,假诺改变了文件一贯load新的。针对这些标题大家能够动用CacheBust选项:

$LAB.setGlobalDefaults({CacheBust: true})
$LAB.script('index.js');

  那样就会保障每便都从服务端读取文件(不曾读取缓存)。

  还应该有二个问题,对于多少个相符的恳求,LABjs私下认可只会推行三次:

$LAB.script('index.js').script('index.js');
$LAB.script('index.js');

  实际上index.js这么些文件只进行了二回!假如index.js里的代码是打字与印刷hello world,也便是说只会被打字与印刷三遍。如何做到能打字与印刷贰回?用AllowDuplicates:

$LAB.setGlobalDefaults({AllowDuplicates: true})
$LAB.script('index.js').script('index.js');
$LAB.script('index.js');

  实际上上边的代码,固然会实行一回index.js,可是央浼只有叁遍,别的多少个都以缓存读取,何况如前方所说,假设服务端修正了,也会从缓存读取,那太骇然了。所以AllowDuplicates能够兼容CacheBust使用

$LAB.setGlobalDefaults({AllowDuplicates: true, CacheBust: true})
$LAB.script('index.js').script('index.js');
$LAB.script('index.js');

图片 13

  其实正是带了意气风发串代表呼吁唯意气风发的字符串,这在ajax央求中很广阔。

  • BasePath

  三个字符串(默许空串),会将那一个字符串加在每一个script(卡塔尔里的U悍马H2L的最前面。

  • Debug

  二个布尔值(默许false),如若翻开debug选项的话,会在调整台打字与印刷新闻,必要小心的是,独有利用了LAB-debug.min.js或然LAB.src.js该接收才work。

$LAB.script() & $LAB.wait()

  script(卡塔尔(قطر‎里的参数能够是众多格局,比方字符串(文件的绝对路线也许相对路径)、对象(src、type、charset src必需)、数组或然措施(恐怕前面三个们的整合),更加多demo能够参照Example 8 below。前三者很好领会,这里大概提下参数为function的意况,当script(卡塔尔(قطر‎里的参数是个无名的function的时候,该function会马上施行,它能够return一个值,而该值必需是上述说的string、object恐怕array情势,相当于给该script(卡塔尔国赋值了。

图片 14

$LAB
  .script(function(){
    // assuming `_is_IE` defined by host page as true in IE and false in other browsers 
    if (_is_IE) {
      return "ie.js"; // only if in IE, this script will be loaded
    }
    else {
      return null; // if not in IE, this script call will effectively be ignored
    }
  })
  .script("script1.js")
  .wait();

图片 15

$LAB.queueScript() & $LAB.queueWait() & $LAB.runQueue() & $LAB.sandbox()

  script(卡塔尔(قطر‎和wait(卡塔尔会使得脚本立时实践(除非设置机械漏刻),可是queueScript(卡塔尔国和queueWait(卡塔尔能使得脚本在随性所欲时刻实行,实践的时候带上runQueue(卡塔尔就能够了。

图片 16

var a = $LAB.queueScript('index.js').queueWait(function() {
  console.log('hello world');
});

setTimeout(function() {
  a.runQueue()
}, 1000);

图片 17

  如上脚本就会在1000ms后施行,那样的法力通常script(卡塔尔(قطر‎同盟反应计时器也能促成,不过在今后某一不确准期刻施行就丰盛了(举例说大器晚成段钦定代码后)。若是有多个链要在现在某时刻实行呢?

图片 18

var a = $LAB.queueScript('index.js').queueWait(function() {
  console.log('hello world');
});

setTimeout(function() {
  a.runQueue()
}, 1000);

var b = $LAB.queueScript('index2.js').queueWait(function() {
  console.log('hello world');
});

setTimeout(function() {
  b.runQueue()
}, 2000);

图片 19

  如上代码并未能拿到预想的结果(实际上1000ms后协作输出),当时就必要用sandbox(卡塔尔(قطر‎创制四个新的实例。

图片 20

var a = $LAB.queueScript('index.js').queueWait(function() {
  console.log('hello world');
});

setTimeout(function() {
  a.runQueue()
}, 1000);

var b = $LAB.sandbox().queueScript('index2.js').queueWait(function() {
  console.log('hello world');
});

setTimeout(function() {
  b.runQueue()
}, 2000);

图片 21

$LAB.noConflict() 

  使用noConflict(卡塔尔会将近些日子版本的LABjs回滚到旧的版本。(二零一四-08-04 这些解释应该是错的)

 

  read more from  LAB documentation

github LAB.js 2.0.3及以下版本版本

       3.0脚下正值举行重写中

参考自:

    

本文由pc28.am发布于前端技术,转载请注明出处:聊一聊原生浏览器中的模块,动态加载JS函数

上一篇:网易和淘宝移动,Web移动端适配总结 下一篇:没有了
猜你喜欢
热门排行
精彩图文