zepto/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>
更为具体的对应可以看这张图片:

组件化编程
- 组件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
感谢阅读~~
zepto/jQuery、AngularJS、React、Nuclear的演化的更多相关文章
- vue2.x入坑总结—回顾对比angularJS/React的一统
从感性的角度讲,我是不屑于用VUE,觉得react套件用起来更顺手,但是vue现在越来火,所以也不得入vue(杂烩汤)的坑.vue/anguarJS/React,三者对关系现在就是: https:// ...
- Javascript/CSS/HTML/vue/angularJS/react/jquery/DOM前端编程经典电子书pdf下载
高级进阶必读 你所不知道的系列,高级开发必掌握. JavaScript这门语言简单易用,很容易上手,但其语言机制复杂微妙,即使是经验丰富的JavaScript开发人员,如果没有认真学习的话也无法真正理 ...
- ECharts 初识(基于MVC+jQuery+Angularjs实现的Demo)
一.背景: 我们这行做web开发的,很多时候都需要做数据统计报表,现在我所使用的是来自百度团队的ECharts.官方网址:http://echarts.baidu.com/ 我们知 ...
- jQuery和react实现二维码
jq如何生成二维码 代码如下: 1.jquery.qrcode生成二维码代码 <!DOCTYPE html> <html> <head> <script ch ...
- zepto jquery和zepto的区别?
jQuery 由于强大的生命力基本上是一个事实标准,所以大部分工具 lib 在 DOM 操作.动画等功能上或多或少都会是 jQuery-like 的. Zepto 的 API 就是完全兼容 jQuer ...
- jquery/vue/react前端多语言国际化翻译方案指南
❝ 本文章共3470字,预计阅读时间5-10分钟. ❞ 国际化-前言 每个开发者能希望编写的程序可以让全世界的用户使用,它要求从产品中抽离所有地域语言,国家/地区和文化相关的元素.换种说法,「应用程序 ...
- javascript 完整知识点整理
by 蔡舒啸 目录 一 5种基本类型 typeof 关键字 三种强制类型转换 日期 二 if语句for语句whiledo-whileswitch-case 比较运算符 逻辑运算符 if for语句 w ...
- 移动端开发:使用jQuery Mobile还是Zepto
原:http://blog.csdn.net/liubinwyzbt/article/details/51446771 jQuery Mobile和Zepto是移动端的js库.jQuery Mobil ...
- jquery和zepto的扩展方法extend
jquery和zepto的扩展方法extend 总结下jQuery(3.1.1)和zepto(1.1.6)到底是如何来开放接口,使之可以进行扩展,两者都会有类型判断,本文使用简单的类型判断,暂不考虑兼 ...
随机推荐
- C#事件-使用事件需要的步骤
事件是C#中另一高级概念,使用方法和委托相关.奥运会参加百米的田径运动员听到枪声,比赛立即进行.其中枪声是事件,而运动员比赛就是这个事件发生后的动作.不参加该项比赛的人对枪声没有反应. 从程序员的角度 ...
- Tomcat 部署我的第一个程序
idea 生成war包.先双击clean,再双击package.生成成功之后就会产生war包. 第二步:将生成好的war文件复制到tomcat文件夹下. 第三步:配置tomcat的server.xml ...
- git &github 快速入门
本节内容 github介绍 安装 仓库创建& 提交代码 代码回滚 工作区和暂存区 撤销修改 删除操作 远程仓库 分支管理 多人协作 github使用 忽略特殊文件.gitignore 1.gi ...
- BZOJ3198[SDOI2013]SPRING
Description Input Output Sample Input 3 3 1 2 3 4 5 6 1 2 3 0 0 0 0 0 0 4 5 6 Sample Output 2 HINT 题 ...
- iOS 4s-6Plus屏幕自动适配及颜色转换为十六进制
iOS各种屏幕自动适配及颜色转换为十六进制 ★★★XLJMatchScreen自动适配屏幕★★★ 支持pod导入 pod 'XLJScreenMatching', '~> 1.0.3' 如果发现 ...
- WCF学习之旅—第三个示例之二(二十八)
上接WCF学习之旅—第三个示例之一(二十七) 五.在项目BookMgr.Model创建实体类数据 第一步,安装Entity Framework 1) 使用NuGet下载最新版的Entity Fram ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(36)-文章发布系统③-kindeditor使用
系列目录 我相信目前国内富文本编辑器中KindEditor 属于前列,详细的中文帮助文档,简单的加载方式,可以定制的轻量级.都是系统的首选 很多文章教程有kindeditor的使用,但本文比较特别可能 ...
- Java Collection知识总结
首先说说java中常用的集合容器:ArrayList,LinkedList,Vector,HashMap,Hashtable,HashSet,TreeSet.[就个人认为] java集合容器本人理解为 ...
- 坎坷路:ASP.NET Core 1.0 Identity 身份验证(中集)
上一篇:<坎坷路:ASP.NET 5 Identity 身份验证(上集)> ASP.NET Core 1.0 什么鬼?它是 ASP.NET vNext,也是 ASP.NET 5,以后也可能 ...
- Oracle 11g静默安装简明版
环境:RHEL 6.5 + Oracle 11.2.0.4 1. 初步处理应答文件 2. 静默安装软件 3. 静默安装监听 4. 静默dbca建库 说明: 本文默认安装软件前的步骤已经设置完毕 如果没 ...