AngularJSzepto/jQuery、AngularJS、React、Nuclear的嬗变

写在前面

因为zepto、jQuery2.x.x和Nuclear都是为现代浏览器而出现,不兼容IE8,适合现代浏览器的web开发如故移动web/hybrid开发。每个框架类库被大量用户广泛利用都表明其戳中了开发者的刚需。本文将相相比较zepto/jQuery到Nuclear的筹划和演化的长河。

无框架时代

互联网的春风刚刮来的时候,人们随即接纳三剑客制作网页。

<div onclick="showMsg()"></div>

<script>
    function showMsg(){
        alert("恭喜你实现第一个人机交互程序");
    }
</script>

这边会发现showMsg必须是全局的,onclick触发才能访问,这样就会造成每绑一个轩然大波就要污染一个全局变量。那点问题难不倒前端工程师,加个一级namespace,所有的风波挂在它下边:

<div onclick="SuperNamespce.showMsg1()"></div>
<div onclick="SuperNamespce.showMsg2()"></div>
<script>
    var SuperNamespce={};
    SuperNamespce.showMsg1=function(){
    }
    SuperNamespce.showMsg2=function(){
    }
</script>

不过也有问题,比如这样的场所:

var SuperNamespce = {};
setTimeout(function () {
    SuperNamespce.showMsg1 = function () {
    }
    SuperNamespce.showMsg2 = function () {
    }
}, 4000)

抑或更诚实一点:

var SuperNamespce = {};
ajax({
    url: "xxx",
    success: function () {
        SuperNamespce.showMsg1 = function () {
        }
        SuperNamespce.showMsg2 = function () {
        }
    }
})

在定时器没实施到位或者AJAX没有success从前,用户的有所交互都会报:

Uncaught TypeError: SuperNamespce.showMsg1 is not a function
Uncaught TypeError: SuperNamespce.showMsg2 is not a function

接下来,善于记录分析总计思考提炼的工程师们拿出本子记录下至上实践:

  • 不提出在dom元素上一贯阐明事件绑定调用
  • 阐明式事件绑定所调用的法子自然要污染全局某个变量
  • 讲明式事件绑定的有关js未举办完的场馆下发生人机交互会报脚本错误,且严重影响用户体验
  • 提出在js中先物色dom、再给dom绑定事件

想象一下:一个按钮5秒后才绑的风波,用户前4秒内直接点都没反应,然后5秒到了,可是用户已经吐弃该网页了。

util库时代

开发者们如约地点统计的顶尖实践,重构了下边的代码:

<div id="myID1"></div>
<div id="myID2"></div>

<script>
    var myID1 = document.getElementById("myID1");
    var myID2 = document.getElementById("myID2")
    myID1.onclick = function () {
        alert(1);
    }
    myID2.onclick = function () {
        alert(2);
    }
</script>

这给开发者们带来了此外一个劳苦的题目,从前申明式间接在div上绑定事件不需要寻找dom,所以不需要标记id,现在各类需要绑定事件的dom都亟需标记id用于js查找。而且,这种写法依旧没有改动讲明式事件绑定的一个题材:

  • js未执行完的事态下发生人机交互【即便不会报脚本错误】,但是严重影响用户体验

比如说你div是个按钮形态,看上去用户就想点,一贯点从来点。可是js还没实施完,事件还没绑定上去。用户将收不到任何反馈。
而是开发者并不关乎这‘皮秒’、甚至‘秒’级其它用户体验,也有的开发者利用UI逻辑去回避,比如先来个loading?比如绑定完事件再呈现该dom。
就如此,那个问题就这样不了了之~~~~。随之而来的是:
搜索dom好累,封个类库:

function query(selector){
    //此处省略一万行代码
}

绑定事件好累,封个类库(edwards的events.js):

function addEvent(element, type, handler) {
  // assign each event handler a unique ID
  if (!handler.$$guid) handler.$$guid = addEvent.guid++;
  // create a hash table of event types for the element
  if (!element.events) element.events = {};
  // create a hash table of event handlers for each element/event pair
  var handlers = element.events[type];
  if (!handlers) {
    handlers = element.events[type] = {};
    // store the existing event handler (if there is one)
    if (element["on" + type]) {
      handlers[0] = element["on" + type];
    }
  }
  // store the event handler in the hash table
  handlers[handler.$$guid] = handler;
  // assign a global event handler to do all the work
  element["on" + type] = handleEvent;
};
// a counter used to create unique IDs
addEvent.guid = 1;

function removeEvent(element, type, handler) {
  // delete the event handler from the hash table
  if (element.events && element.events[type]) {
    delete element.events[type][handler.$$guid];
  }
};

function handleEvent(event) {
  // grab the event object (IE uses a global event object)
  event = event || window.event;
  // get a reference to the hash table of event handlers
  var handlers = this.events[event.type];
  // execute each event handler
  for (var i in handlers) {
    this.$$handleEvent = handlers[i];
    this.$$handleEvent(event);
  }
};

再然后,开发者们觉得引用这么多工具库好累…

zepto/jQuery时代

开发者们认为引用这么多工具库,而且她们实际上都隶属于一致类东西(查找dom、dom绑定事件都是操作dom)能够勾兑一起。就有了新生风行全球的jQuery和zepto在web里实现人机交互:

$("#myID").click(function(){
    alert("恭喜你使用三行代码实现了人机交互程序");
})

开发者的刚需就是:找到dom、绑定事件、写逻辑。而且,下边的程序还不会丢掉语义,一看就知道想干什么。可是:

  • js未执行完的气象下暴发人机交互【即使不会报脚本错误】,然而严重影响用户体验

开发者们被各个爽到之后,这些题目早就被抛到了满天云外。这我们就继续往下看,看到哪位阶段把地点这多少个题目迎刃而解了?!

AngularJS

<div ng-app="myApp" ng-controller="personCtrl">
<button ng-click="toggle()">隐藏/显示</button>
<p ng-show="myVar">
AngularJS
</p>
</div>

<script>
var app = angular.module('myApp', []);
app.controller('personCtrl', function($scope) {
    $scope.myVar = true;
    $scope.toggle = function() {
        $scope.myVar = !$scope.myVar;
    };
});
</script>

因为AngularJS通过ng-click绑定事件,所以没有解决。

React

var Photo = React.createClass({
  toggleLiked: function() {
    this.setState({
      liked: !this.state.liked
    });
  },
  getInitialState: function() {
    return {
      liked: false
    }
  },
  render: function() {
    var buttonClass = this.state.liked ? 'active' : '';
    return (
      <div className='photo'>
        <button onClick={this.toggleLiked} className={buttonClass}>点我</button>
      </div>
    )
  }
});

因为React的布局和逻辑放在一块儿,解决了超越了十多年之久的前端问题:

  • js未执行完的状况下发出人机交互【尽管不会报脚本错误】,不过严重影响用户体验

通过把相关的布局和逻辑放在同一个零部件中,整个体系变得卫生清晰了。
我们为那多少个根本的洞见向 React 致敬。(引用于riot)

React的中央根本不是怎么UI=fn(state);不用React也得以UI=fn(state)。

Nuclear

理念:some HTML + scoped CSS + JS === Reusable Component
Nuclear的网站在此地: http://alloyteam.github.io/Nuclear/
里面有雅量的介绍。

因而下边的使用办法:

var TodoApp = Nuclear.create({
    add: function (evt) {
        evt.preventDefault();
        this.option.items.push(this.textBox.value);
    },
    render: function () {
        return '<div>\
                    <h3>TODO</h3>\
                    <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>\
                    <form onsubmit="add(event)" >\
                        <input nc-id="textBox" type="text"  />\
                        <button>Add #{{items.length}}</button>\
                    </form>\
                </div>';
    }
});
new TodoApp({ items: [] }, "#todoListContainer");

会在html里转变如下的协会:

<div data-nuclearid="0">
    <div>
        <h3>TODO</h3>
        <ul></ul>
        <form onsubmit="Nuclear.instances[0].add(event)">
            <input nc-id="textBox" type="text">
            <button>Add #0</button>
        </form>
    </div>
</div>

更是现实的相应可以看这张图片:
AngularJS 1

组件化编程

  • 组件html结构、css和js必须在一齐,要么都加载,要么都不加载。
  • 只加载其中有些都是荒废如css加载了,组件没用到js加载了,浪费带宽
  • 拉动糟糕的经验,如组件js加载完了,css却没加载成功,导致用户看到错乱的页面
  • 脚本错误和不佳体验,如组件HTML和css加载完了,js却没加载成功,导致用户交互无响应

Nuclear编程

  • 组件化编程
  • 超小的体积,5k
  • 扶助任意模板引擎
  • 双向绑定改进编程体验
  • 面向对象编程
  • 支撑部分CSS

回来最初的题目:

  • 不建议在dom元素上直接声明事件绑定调用(Nuclear指出事件直接绑在dom上)
  • 声明式事件绑定所调用的方法必定要污染全局某个变量(只污染了Nuclear)
  • 声明式事件绑定的相关js未执行完的情况下发生人机交互会报脚本错误,且严重影响用户体验(组件化编程,组件的html、css和js是一个完完全全)
  • 建议在js中先查找dom、再给dom绑定事件(Nuclear指出事件直接绑在dom上,查找dom的需要可以标记nc-id或者nc-class)

总而言之:使用Nuclear组件化编程,使组件的HTML、CSS和JS同时一头生效可以避开许多题目。

Github: https://github.com/AlloyTeam/Nuclear

谢谢阅读~~

相关文章