动态加载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原先,在应用程序的每2个JS中定义的万事都共享一个大局效能域。随着web应用程序变得越发复杂,JS代码的使用量也早先加强,这一做法会唤起难点,如命名争辩和达州难题。ES6的3个指标是杀鸡取卵效能域难题,也为了使JS应用程序显得有序,于是引进了模块。本文将详细介绍ES6中的模块

 

平常的,当大家要求加载js文件的时候都会利用script标签来兑现,类似于如下代码:

不支持裸导入(不能够透过模块名间接导入)

3个及格的模块标识符必须满意下列原则之一:

  • 四个整机的非相对UCRUISERL。通过 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关键字外,每3个扬言与剧本中的一模一样。因为导出的函数和类注解供给有一个名称,所以代码中的各类函数或类也确确实实有其一名号。除非用default关键字,不然无法用这些语法导出匿名函数或类

  其它,在定义multiply()函数时未尝即时导出它。由于无需总是导出注明,能够导出引用,由此那段代码能够运营。其它,那些示例并未导出subtract()函数,任何未显式导出的变量、函数或类都以模块私有的,不可能从模块外部访问

 

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

暗中认可延迟加载

当网络境况不佳的时候,脚本加载会阻塞浏览器解析 HTML。经常我们能够透过在
script 标签上采纳 defer
属性来化解阻塞难点,可是这也会造成脚本唯有在文书档案解析实现后才实施,同时还要兼任其余延迟脚本的实践种种。暗中认可情形下模块脚本的显示类似于
defer — 它不会堵塞 HTML 的辨析。

动态加载JS函数,聊一聊原生浏览器中的模块。模块脚本的实践队列与应用了 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表示从哪些模块导入给定的绑定,该模块由象征模块路径的字符串钦赐(被称作模块表达符)。浏览器选拔的不二法门格式与传给<script>元素的平等,也正是说,必须把公文增加名也丰裕。另一方面,Nodejs则依照基于文件系统前缀区分本和姑件和包的老规矩。例如,example是一个包而./example.js是一个本半夏件

  当从模块中程导弹入二个绑定时,它就就好像使用const定义的同等。不可能定义另1个同名变量(包括导入另3个同名绑定),也无力回天在import语句前应用标识符或改动绑定的值

【导入单个绑定】

  倘若前面包车型客车示范在贰个名为”example.js”的模块中,大家得以导入并以多样方法选用那些模块中的绑定

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

  即便example.js导出的函数不止一个,但这些示例导入的却唯有sum()函数。借使尝试给sum赋新值,结果是抛出2个不当,因为无法给导入的绑定重新赋值

  为了最棒地合营五个浏览器和Node.js环境,一定要在字符串从前蕴涵/、./或../来代表要导入的文件

【导入八个绑定】

  假使想从示例模块导入多个绑定,则足以肯定地将它们列出如下

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

  在那段代码中,从example模块导入三个绑定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";

  就算在那么些模块中有一个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”)时会回到导出setName()的模块中去履行,并将name设置为”match”。此更改会自动在导入的name绑定上体现。其缘由是,name是导出的name标识符的地面名称。本段代码中所使用的name和模块中程导弹入的name不是同2个

 

而是一直运用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()函数时利用了贰个导入名称来重命名sum()函数(当前上下文中的本地名称)。导入时改变函数的地面名称意味着便是模块导入了add()函数,在时下模块中也从不add()标识符

 

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的任何模块系统中,从模块中程导弹出和导入暗中同意值是3个广泛的做法,该语法被开始展览了优化。模块的暗中同意值指的是透过default关键字钦赐的单个变量、函数或类,只可以为各类模块设置三个私下认可的导出值,导出时往往用到default关键字是一个语法错误

【导出默许值】

  上边是三个运用default关键字的简短示例

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

  那么些模块导出了1个函数作为它的私下认可值,default关键字表示这是贰个默许的导出,由于函数被模块所表示,由此它不供给多少个称谓

  也足以在export default然后添加暗中认可导出值的标识符,就如那样

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

  先定义sum()函数,然后再将其导出为私下认可值,要是急需总括暗中同意值,则可以利用这几个点子。为暗许导出值钦命标识符的第两种方法是使用重命名语法,如下所示

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

  在重命名导出时标识符default具有出色意义,用来提醒模块的私下认可值。由于default是JS中的暗中认可关键字,由此无法将其用于变量、函数或类的名目;然则,能够将其当做属性名称。所以用default来重命超模块是为了尽恐怕与非默许导出的定义一致。倘诺想在一条导出语句中同时钦定多少个导出(包括默许导出),这几个语法分外实用

【导入暗中同意值】

  能够选择以下语法从3个模块导入二个私下认可值

// 导入默认值
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>标签时,浏览器不可能同时读取,必须读取完二个再去读取另一个,造成读取时间大大延长,页面响应缓慢。

模块只进行1遍

一经您利用过ES6的模块,
那么您势必晓得你能够屡屡引入同一模块不过她们只会履行2次。在Html中也一律,
3个UPRADOL模块脚本在三个页面中只会实施叁次。

JavaScript

<!– 1.mjs 执行3次 –> <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是静态加载,所以有一部分语法限制

  壹 、不可能应用表明式和变量等这么些唯有在运营时才能获取结果的语法结构

// 报错
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

分化于普通脚本,跨站引用模块脚本(及其引入)必要遵循CO奥迪Q3S。
这意味着跨源模块脚本必须再次来到有效的COCR-VS头,例如Access-Control-Allow-Origin:*。

JavaScript

<!– CO路虎极光S检验失利,不会履行 –> <script type=”module”
src=”; <!–
引入的模块CORubiconS检验战败,不会执行 –> <script type=”module”>
import ”; addTextToBody(“This will not
execute.”); </script> <!– CO奥迪Q5S检验通过,会实施 –>
<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有默许的导出值,则运用此语法时将不可能定义二个新的暗中同意导出

 

代码如下:

不必要证据

本着同源请求,超越八分之四遵照COCR-VS的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

此处还有2个关于 模块只举办贰回
的坑。当您通过叁个UEvoqueL引入三个模块时,假使一开头你以无凭证的章程呼吁,然后又以有凭据的措施再请求一回,你取得的回来都以无凭证请求的这一次。那就是自家干什么会在第一次呼吁时在UEnclaveL后增加,用于区分四次呼吁。

更新:以上或许相当的慢会改变。
暗中同意处境下,fetch()和模块脚本都会向同一来源的UHavalL发送凭据。

内嵌的时候要越发注意,内容块不要包涵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环境创设一套统一的正经,它只鲜明了语法,并将加运载飞机制抽象到1个未定义的个中方法HostResolveImportedModule中。Web浏览器和Node.js开发者能够透过对个别环境的认知来支配哪些促成HostResolveImportedModule 

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

  即便在ES6面世以前,Web浏览器也有三种办法得以将JS包蕴在Web应用程序中,这几个本子加载的措施分别是

  一 、在<script>成分中通过src属性钦点一个加载代码的地址来加载JS代码文件

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

  3、通过Web Worker或瑟维斯 Worker的措施加载并履行JS代码文件

  为了完全协理模块功能,Web浏览器必须创新这一个机制

美高梅开户网址 ,在<script>中使用模块

  <script>元素的暗中认可行为是将JS文件作为脚本加载,而非作为模块加载,当type属性缺点和失误或带有1个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>

  此示例中的第1个<script>成分运用src属性加载了1个外表的模块文件,它与加载脚本之间的唯一差异是type的值是”module”。第一个<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>

  那三个<script>成分依照它们被内定的一一执行,所以模块module1.js保险会在内联模块前执行,而内联模块保险会在module2.js模块从前实施

  种种模块都得以从二个或多少个别的的模块导入,那会使难题复杂化。由此,首先分析模块以识别全数导入语句;然后,每种导入语句都触发三遍拿走进度(从互连网或从缓存),并且在颇具导入能源都被加载和实践后才会进行当前模块

  用<script
type=”module”>显式引入和用import隐式导入的持有模块都是按需加载并推行的。在那一个示例中,完整的加载顺序如下

  壹 、下载并分析module1.js

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

  三 、解析内联模块

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

  伍 、下载并分析module2.js

  六 、递归下载并分析module2.js中程导弹入的财富

  加载成功后,唯有当文书档案完全被解析之后才会实施此外操作。文书档案解析完结后,会发生以下操作

  ① 、递归执行module1.js中程导弹入的能源

  2、执行module1.js

  三 、递归执行内联模块中导入的能源

  四 、执行内联模块

  ⑤ 、递归执行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第②形成下载(包含其兼具的导入财富),它将先举办;如若module2.js首先完毕下载,那么它将先实施

将模块作为Woker加载

  Worker,例如Web Worker和ServiceWoker,能够在网页上下文之外执行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" });

  在此示例中,给第3个参数字传送入三个目的,其type属性的值为”module”,即依照模块而不是本子的章程加载module.js。(那里的type属性是为了仿效<script>标签的type属性,用以区分模块宁海平调本)全体浏览器中的Worker类型都援助首个参数

  Worker模块日常与Worker脚本一起行使,但也有局地不比。首先,Worker脚本只可以从与引用的网页相同的源加载,可是Worker模块不会完全受限,固然Worker模块具有同等的默许限制,但它们或然能够加载并访问具有分外的跨域能源共享(CO路虎极光S)头的公文;其次,即便Worker脚本能够运用self.importScripts()方法将其余脚本加载到Worker中,但self.importScripts()却平素无法加载Worker模块,因为应该运用import来导入

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

  浏览器需要模块表达符具有以下二种格式之一

  壹 、以/开端的分析为从根目录初步

  二 、以./早先的解析为从当前目录初阶

  ③ 、以../开首的辨析为从父目录开端

  4、URL格式

  例如,假若有3个模块文件位于

// 从 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的CO翼虎S头的安插是不利的)固然没有达成的模块加载器规范将提供解析其余格式的措施,但日前,那一个是浏览器暗中认可情况下唯一能够分析的模块表达符的格式

  由此,一些看起来符合规律的模块表达符在浏览器中其实是无效的,并且会促成错误

// 无效:没有以 / 、 ./ 或 ../ 开始
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在拓宽进程中对模块定义的规范化产出。速龙是三个专业,只定义语法API,而requireJS是实际的兑现。类似于ECMAScript和javascript的涉嫌

  由下边代码可见,AMD的特点是借助前置,对于依靠的模块提前实施

// 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()//不带参数的.wait()方法表示马上运维刚才加载的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.案例
用脚本来实现响应式布局:
代码好难,再等一等。。。。

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

此外,对于跨域的知识点依然不太通晓,前面要细心看。

           //第陆个执行链
          
.script(”)
          
.script(”)

           //第11个执行链
           .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()则优雅地贯彻了那么些效能,小编在高质量JavaScript
加载和举办一文中也大致讲解了那七个核心API的用法。当然,LABjs还有更多的API,本文用实例讲解下LABjs别的API。

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

  两者所能设置的参数完全一致,差别的是,前者是大局设置,效用在颇具的$LAB链上;后者出现在某条链的始发地方(后面接script()、wait()等),该装置只出力在那条链上。该参数能够是多少个包含多少个键值对的对象

  • AlwaysPreserveOrder

  3个布尔值(暗中认可false),假设设置为true,则各样script()后都会暗中同意设置一个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奥迪Q5L的最前方。

  • 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会即刻施行,它能够return2个值,而该值必须是以上说的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

  如上脚本就能在一千ms后实施,那样的效用一般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

  如上代码并没能获得预想的结果(实际上一千ms后联合输出),那时就必要用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脚下正值拓展重写中

参考自:

    

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图