关于RequireJS的简单介绍即使用方法,requirejs简单介绍

require和 sea的源码深入分析,小编事先的博客有写过,
后天自个儿想分享的是四个很简短的主导代码(不带注释和空行大约60行),
未有容错判定。

贰个颇为简约的requirejs完毕格局,requirejs达成

require和 sea的源码深入分析,笔者事先的博客有写过,
今日自家想共享的是叁个很简短的骨干代码(不带注释和空行大致60行),
未有容错推断。

require.js

require函数达成用一句话回顾:

逐个加载require的模块,然后监测script的onload事件,剖断全部模块加载成功,执行require的callback,
假使只带三个参数且不是数组,正是加载成功后return 模块。

 

//标记已经加载成功的个数
var REQ_TOTAL = 0;
//模块导出
window.exports = {};
//记录各个模块的顺序
var exp_arr = [];

//判断是否数组
function isArray(param) {
  return param instanceof Array;
}

//require 真正实现
function require(arr, callback) {

  var req_list;

  if(isArray(arr)) {
    req_list = arr;
  } else {
    req_list = [arr];
  }
  var req_len = req_list.length;

  //模块逐个加载
  for(var i=0;i<req_len;i++) {
    var req_item = req_list[i];

    var $script = createScript(req_item, i);

    var $node = document.querySelector('head');

    (function($script) {
      //检测script 的onload事件
      $script.onload = function() {
        REQ_TOTAL++;

        var script_index = $script.getAttribute('index');

        exp_arr[script_index] = exports;

        window.exports = {};

        //所有链接加载成功后,执行callback
        if(REQ_TOTAL == req_len) {
          callback && callback.apply(exports, exp_arr);


        }

      }

      $node.appendChild($script);
    })($script);

  }

}

//创建一个script标签
function createScript(src, index) {
  var $script = document.createElement('script');

  $script.setAttribute('src', src);
  $script.setAttribute('index', index);

  return $script;
}

 然后写了2个导出模块的js文件, 只写了最轻松易行的exports达成

define.js

exports.define = {
  topic: 'my export',
  desc: 'this is other way to define ',
  sayHello: function() {
    console.log('topic ' + this.topic + this.desc);
  }
}

define2.js

exports.define = {
  name: 'xm',
  age: 22,
  info: function() {
    console.log('topic ' + this.name + this.age);
  }
}

接下来测量试验demo非常的粗略

//测试demo
 require(['../res/define.js', '../res/define2.js'], function(def, def2) {
   def.define.sayHello();

   def2.define.info();
 });

如上正是笔者为大家带来的三个颇为简约的requirejs达成格局全体内容了,希望大家多多协助帮客之家~

require和 sea的源码深入分析,笔者事先的博客有写过,
前日作者想共享的是贰个很简单的基本代码(不…

/**
 * require
 * @author Heekei
 * @version 0.2.1
 * 
 * @description 异步加载外部js,可回调
 * @param {Object} setting 配置项
 * @param {Object=} setting.depends 依赖文件数组,可选
 * @param {String} setting.url  外部js地址
 * @param {Function=} setting.callback 回调函数,可选
 * @param {Boolean=} setting.defer  是否在DomContentLoaded之前运行,默认为false(注:如果depends具有强依赖性,请将defer设置为true)
 */
var require = function (setting) {
    var _this = this;
    if (require.loaded.indexOf(setting.url) !== -1) return;
    require[setting.url] = {};
    require[setting.url].Timer = null;
    // 加载依赖文件
    if (setting.depends) {
        // 标记依赖文件正在加载
        require[setting.url].dependsLoading = true;

        // 检查依赖文件是否已经加载过
        for (var x in setting.depends) {
            if (require.loaded.indexOf(setting.depends[x]) !== -1) {
                setting.depends.splice(x, 1)
            }
        }

        // 记录正在加载的依赖到数组【加载中的依赖】
        require[setting.url].loadingDepends = setting.depends;

        // 设置主JS的依赖文件的长度
        require[setting.url].dLen = setting.depends.length;

        // 定时检查依赖是否加载完毕
        require[setting.url].Timer = setInterval(function () {
            if (require[setting.url].dependsLoading === false) { // 依赖文件加载完毕
                // 加载主JS
                require({
                    url: setting.url,
                    callback: setting.callback
                })
                clearInterval(require[setting.url].Timer) // 清除定时器
            }
        }, 0)

        // 循环加载依赖文件
        for (var d = 0; d < require[setting.url].dLen; d++) {
            require({
                url: setting.depends[d],
                callback: function () {
                    // 加载完成后,将该依赖文件从【加载中的依赖】数组中删除
                    require[setting.url].loadingDepends.splice(require[setting.url].loadingDepends.indexOf(this.url), 1)

                    // 如果【加载中的依赖】为空,将“依赖加载中”的状态标记为false
                    if (require[setting.url].loadingDepends.length == 0) require[setting.url].dependsLoading = false;
                }
            })

        }

        // 退出函数,保证主JS在加载依赖文件的过程中不进行加载
        return;
    }

    var script = document.createElement("script"); // 加载JS文件

    // 触发回调
    if (script.readyState) { //IE 
        script.onreadystatechange = function () {
            if (script.readyState == "loaded" ||
                script.readyState == "complete") {
                script.onreadystatechange = null;
                console.log(setting.url + " has loaded");
                isLoaded = true;
                if (typeof setting.callback === "function") {
                    setting.callback();
                }
            }
        };
    } else { //Others 
        script.onload = function () {
            console.log(setting.url + " has loaded");
            if (typeof setting.callback === "function") {
                setting.callback();
            }
        };
    }

    script.src = setting.url + "?" + Math.random();

    if (setting.defer) {
        script.defer = "defer";
    }
    require.loaded.push(setting.url);
    document.head.appendChild(script);
}
require.loaded = []

关于RequireJS的简约介绍即利用办法,requirejs简要介绍

RequireJS介绍

RequireJS
是一个JavaScript模块加载器。它特别适合在浏览器中运用。使用RequireJS加载模块化脚本将坚实代码的加载速度和品质。

兼容性

浏览器(browser) 是否兼容
IE 6+ 兼容 ✔
Firefox 2+ 兼容 ✔
Safari 3.2+ 兼容 ✔
Chrome 3+ 兼容 ✔
Opera 10+ 兼容 ✔

优点

金玉锦绣js文件的异步加载,防止网页失去响应

管住模块之间的借助,便于代码的编写和保卫安全

极快上手

step 1

引入require.js

require()中的依赖是叁个数组,即便独有一个重视,你也亟须接纳数组来定义

第贰个参数是回调函数(callback),能够用来化解模块之间的借助

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="require.js"></script>
    <script type="text/javascript">
      require(["js/a"], function(){
        alert("load finished");
      });
    </script>
  </head>
  <body>
   body
  </body>
</html>

step 2

require.config是用来布署模块加载地方

即使一定的任务比较长,能够采取 baseUrl : “js”,则paths中就不用写js了

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="require.js"></script>
    <script type="text/javascript">
      require.config({
        paths : {
          "jquery" : ["http://vs.thsi.cn/js/jquery-1.7.2.min", "js/jquery"],
          "a" : "js/a"        
        }
      });

      require(["jquery", "a"], function(){
        alert("load finished");
      });
    </script>
  </head>
  <body>
   body
  </body>
</html>

step 3

step
第22中学另行出现了require.config配置,假设各样页面中都加入配置,就显得非常小好了,requirejs提供了一种叫”主数据”的作用

始建四个main.js把step 第22中学require.config放到main.js中

<script data-main="js/main" src="js/require.js"></script>

step 4

经过require加载的模块一般都亟需符合英特尔标准即采纳define来表达模块,可是有时要求加载非AMD标准的js,那时候就须要用到另五个效果:shim

require.config({
  shim: {
    "underscore" : {
      exports : "_";
    },
    "jquery.form" : ["jquery"]
  }
});
require(["jquery", "jquery.form"], function($){
  $(function(){
    $("#form").ajaxSubmit({...});
  })
});

以上正是小编为我们带来的关于RequireJS的简要介绍即采用方式全体内容了,希望我们多多协理帮客之家~

RequireJS介绍 RequireJS
是三个JavaScript模块加载器。它极其适合在浏览器中央银行使。使用Re…

<a name=”table-content”></a>目录

  • 起因
  • 结果
  • 怎么着封装
    autolayout

    • 应用原生约束 API
      的问题
    • 使用
      Masonry
    • 使用
      DLSimpleAutolayout
    • DLSimpleAutolayout
      落成原理

      • 基本原理
      • DLSimpleAutolayout 的贯彻之
        DLSimpleViewAttribute
      • DLSimpleAutolayout 的达成之 NSArray
        类别
      • DLSimpleAutolayout 的兑现之 UIView
        类别

require.js

<a name=”reason-for-this”></a> 起因

支出 iOS SDK
通常索要留心引进的开源代码也许定义的类名和章程名,或然会和客商代码争辩。所以一般的做法是类名,种类方法名加前缀。

不久前在付出 SDK 的时候须要写一些分界面,所以在构思用什么来布局。思索采纳
Masonry。不过引进 Masonry 需要对 Masonry
里面全数类、类别方法加前缀,花费太大,引进错误风险太高。同有时间 SDK
里面包车型客车分界面通常相比较轻易,数量也比较少,引进三个 Masonry
反而会附加编写翻译出来的二进制文件大小,不太值得。所以自身就在思维什么规划二个代码精简的,类似
Masonry 的束缚框架呢?

↑目录

require函数完结用一句话归纳:

<a name=”result-for-this”></a> 结果

在翻阅了 Masonry
的代码之后,笔者主宰效仿它来重新写一个精简的封锁框架,这里的轻便是代码量极少。所以就有了背后的
DLSimpleAutolayout。这些约束框架代码总数大概唯有300行。可是使用方法为主和
Masonry 类似,下面是 DLSimpleAutolayout 写出来的布局代码样式。

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
@[
 view1.dl_top.equalTo(superview).offset(padding.top),
 view1.dl_left.equalTo(superview).offset(padding.left),
 view1.dl_bottom.equalTo(superview).offset(-padding.bottom),
 view1.dl_right.equalTo(superview).offset(-padding.right),
].dl_constraint_install();

↑目录


种种加载require的模块,然后监测script的onload事件,推断全数模块加载成功,试行require的callback,
假若只带多少个参数且不是数组,正是加载成功后return 模块。

<a name=”how-to-encapsulate-autolayout”></a> 怎样封装 autolayout

上边作者会遵纪守法地上课为何,以及怎么着封装 autolayout

 

<a name=”problem-about-original-api”></a> 使用原生约束 API 的难题

在 iOS
下面使用原生约束写代码是极为繁琐的一件事。举个例子上边那样的原生约束代码(来自
Masonry
README.md):

UIView *superview = self.view;

UIView *view1 = [[UIView alloc] init];
view1.translatesAutoresizingMaskIntoConstraints = NO;
view1.backgroundColor = [UIColor greenColor];
[superview addSubview:view1];

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[superview addConstraints:@[

    //view1 constraints
    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeTop
                                multiplier:1.0
                                  constant:padding.top],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeLeft
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeLeft
                                multiplier:1.0
                                  constant:padding.left],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeBottom
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeBottom
                                multiplier:1.0
                                  constant:-padding.bottom],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeRight
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeRight
                                multiplier:1
                                  constant:-padding.right],

 ]];

标题出在苹果提供的特别十分短的函数。当你的视图多的时候,像上面那样的代码就能够越来越庞大,可读性也越来越低。

↑目录

//标记已经加载成功的个数
var REQ_TOTAL = 0;
//模块导出
window.exports = {};
//记录各个模块的顺序
var exp_arr = [];

//判断是否数组
function isArray(param) {
  return param instanceof Array;
}

//require 真正实现
function require(arr, callback) {

  var req_list;

  if(isArray(arr)) {
    req_list = arr;
  } else {
    req_list = [arr];
  }
  var req_len = req_list.length;

  //模块逐个加载
  for(var i=0;i<req_len;i++) {
    var req_item = req_list[i];

    var $script = createScript(req_item, i);

    var $node = document.querySelector('head');

    (function($script) {
      //检测script 的onload事件
      $script.onload = function() {
        REQ_TOTAL++;

        var script_index = $script.getAttribute('index');

        exp_arr[script_index] = exports;

        window.exports = {};

        //所有链接加载成功后,执行callback
        if(REQ_TOTAL == req_len) {
          callback && callback.apply(exports, exp_arr);


        }

      }

      $node.appendChild($script);
    })($script);

  }

}

//创建一个script标签
function createScript(src, index) {
  var $script = document.createElement('script');

  $script.setAttribute('src', src);
  $script.setAttribute('index', index);

  return $script;
}

<a name=”using-masonry”></a> 使用 Masonry

那正是说怎么着进一步雅致的运用 autolayout 呢?绝大比非常多的 iOS 开垦要是运用
autolayout 来布局视图的话,明确或多或少的亲闻过
Masonry
(如果是 Swift 版本的话,官方推荐
SnapKit)。

利用 Masonry,大家可以将方面约束代码写成上边那样(来自 Masonry
README.md):

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler
    make.left.equalTo(superview.mas_left).with.offset(padding.left);
    make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);
    make.right.equalTo(superview.mas_right).with.offset(-padding.right);
}];

Masonry
会帮助大家将约束增多到卓越的视图上(举个例子小编依然和另三个视图的公共祖先),同期也会扶助大家设置相应视图的
translatesAutoresizingMaskIntoConstraintsNO

↑目录

 然后写了2个导出模块的js文件, 只写了最轻巧易行的exports达成

<a name=”using-dlsimpleautolayout”></a> 使用 DLSimpleAutolayout

DLSimpleAutolayout
是贰个运用格局附近 Masonry 的封锁框架,上面是 DLSimpleAutolayout
的约束代码(等价于上边的 Masonry 代码):

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
@[
 view1.dl_top.equalTo(superview).offset(padding.top),
 view1.dl_left.equalTo(superview).offset(padding.left),
 view1.dl_bottom.equalTo(superview).offset(-padding.bottom),
 view1.dl_right.equalTo(superview).offset(-padding.right),
].dl_constraint_install();

是或不是看起来一摸同样?!!

但是 DLSimpleAutolayout
的实现极为简略,唯有三个头文件和二个兑现公文,合计代码行数独有300行左右。

↑目录

define.js

<a name=”how-to-implement-DLSimpleAutolayout”></a> DLSimpleAutolayout 完毕原理

exports.define = {
  topic: 'my export',
  desc: 'this is other way to define ',
  sayHello: function() {
    console.log('topic ' + this.topic + this.desc);
  }
}

<a name=”principle-autolayout”></a> 基本原理

首先你供给精通布局的基本原理

简短的说每二个对等关系的束缚最后会被 Apple 拍卖成一条看似下边包车型地铁等式:

view1.left = 2.0 * view2.left + 8.0

地方这条公式的意思是 view1left 约束等于 view2left 值乘以
2 加 8。这里的 2 叫 multiplier,8 叫 constant,view1 叫 first
item,view2 叫 second item,也正是独家对应

+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;

其一原生 API 的几个参数。无论是 DLSimpleAutolayout 还是 Masonry
的兑现,基本上都是对那几个 API
的包裹,同一时候增添了一部分别样代码,方便使用者利用约束。

↑目录

define2.js

<a name=”principle-DLSimpleViewAttribute”></a> DLSimpleAutolayout 的兑现之 DLSimpleViewAttribute

DLSimpleAutolayout 的落到实处其实参谋了 Masonry,比如
DLSimpleViewAttribute 类似与
MASViewAttributeDLSimpleViewAttribute 类型接口如下:

@interface DLSimpleViewAttribute : NSObject

@property (nonatomic, strong, readonly) DLSimpleViewAttribute *(^equalTo)(id view);
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *(^lessThanOrEqualTo)(id view);
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *(^greaterThanOrEqualTo)(id view);
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *(^multipliedBy)(CGFloat multipier);
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *(^offset)(CGFloat offset);
@property (nonatomic, strong, readonly) NSLayoutConstraint *(^install)();

@end

也便是对应约束的3种大小关系,同偶然候能够对 constant 进行 offset
操作(对应设置 constant),对 second item 有 multipliedBy 操作(对应设置
multiplier),最终增多约束的时候须求手动 install() 。举个例子上面那样:

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
view1.dl_top.equalTo(superview).offset(padding.top).install();
view1.dl_left.equalTo(superview).offset(padding.left).install();
view1.dl_bottom.equalTo(superview).offset(-padding.bottom).install();
view1.dl_right.equalTo(superview).offset(-padding.right).install();

当调用 install() 的时候,DLSimpleAutolayout
会依照当下配备的音讯,来生成八个羁绊,相同的时间将封锁增添到自作者依旧是和
second item 的近年的国有视图上。并安装本人的
translatesAutoresizingMaskIntoConstraintsNO。代码如下所示:

- (NSLayoutConstraint * (^)())install {
    return ^id(){
        // 设置为 NO
        ((UIView *)self.firstItem).translatesAutoresizingMaskIntoConstraints = NO;
        NSLayoutConstraint *constaraint = [NSLayoutConstraint constraintWithItem:self.firstItem
                                                                       attribute:self.firstAttribute
                                                                       relatedBy:self.relation
                                                                          toItem:self.secondItem
                                                                       attribute:self.secondAttribute
                                                                      multiplier:self.multiplier
                                                                        constant:self.constant];
        if (self.secondItem == nil) {
            [self.firstItem addConstraint:constaraint];
        } else {
            // 寻找最近的公共祖先
            UIView *closestCommonSuperview = [self dl_ClosestCommonSuperview:self.firstItem view2:self.secondItem];
            [closestCommonSuperview addConstraint:constaraint];
        }
        return constaraint;
    };
}

↑目录

exports.define = {
  name: 'xm',
  age: 22,
  info: function() {
    console.log('topic ' + this.name + this.age);
  }
}

<a name=”principle-NSArray-category”></a> DLSimpleAutolayout 的兑现之 NSArray 种类

思考到便利在各样属性后边自动使用 install(),小编对 NSArray
增添了一个档案的次序,封装了那些操作。所以没有供给在各样 DLSimpleViewAttribute
对象后调用 install(),只必要将那一个目的放置叁个 NSArray 里面,对这个array 调用 dl_constraint_install()
就可以。这种近似语法糖的写法也会有利了使用者越来越好的组织、调治自身的布局代码。

该 NSArray 类别公开接口如下:

@interface NSArray (DLSimpleAutoLayout)

@property (nonatomic, strong, readonly) NSArray<NSLayoutConstraint *> * (^dl_constraint_install)();

@end

写出来的代码类似上面那样:

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
@[
 view1.dl_top.equalTo(superview).offset(padding.top),
 view1.dl_left.equalTo(superview).offset(padding.left),
 view1.dl_bottom.equalTo(superview).offset(-padding.bottom),
 view1.dl_right.equalTo(superview).offset(-padding.right),
].dl_constraint_install();

↑目录

然后测量检验demo很简单

<a name=”principle-UIView-category”></a> DLSimpleAutolayout 的落实之 UIView 类别

DLSimpleAutolayoutUIView 增加了种类,正是看似 dl_xxx
这样的只读属性。
何况各样 view 再次回到的 dl_xxx 都以八个 DLSimpleViewAttribute
类型。该类别的接口如下:

@interface UIView (DLSimpleAutoLayout)

@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_left;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_top;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_right;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_bottom;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_leading;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_trailing;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_width;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_height;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_centerX;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_centerY;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_baseline;

#if TARGET_OS_IPHONE || TARGET_OS_TV

@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_leftMargin;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_rightMargin;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_topMargin;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_bottomMargin;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_leadingMargin;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_trailingMargin;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_centerXWithinMargins;
@property (nonatomic, strong, readonly) DLSimpleViewAttribute *dl_centerYWithinMargins;

#endif
@end

↑目录

到此截止,DLSimpleAutolayout 基本上就兑现了。具体贯彻的话能够看代码
DLSimpleAutolayout


//测试demo
 require(['../res/define.js', '../res/define2.js'], function(def, def2) {
   def.define.sayHello();

   def2.define.info();
 });

如上正是小编为大家带来的多少个颇为简约的requirejs完毕情势全体内容了,希望大家多多补助脚本之家~

您也许感兴趣的小说:

  • 在Html中选拔Requirejs实行模块化开荒实例详解
  • 基于RequireJS和JQuery的模块化编制程序平时难题浅析
  • 应用requirejs模块化开荒多页面三个入口js的利用方法
  • 依据RequireJS和JQuery的模块化编制程序——常见难点周到深入分析
  • JavaScript模块化之使用requireJS按需加载
  • 一篇小说驾驭RequireJS常用文化
  • SeaJS 与 RequireJS
    的异样相比
  • RequireJS多页面使用实例解析
  • 在JavaScript应用中使用RequireJS来兑现延迟加载
  • angularJS+requireJS完毕controller及directive的按需加载示例
  • requireJS模块化实现再次回到顶端功效的艺术详解

相关文章