Archive for the JavaScript Category

使用Qunee组件展示水文观测站点

中科院的某个客户遇到这样的需求:将区域内所有水文观测站信息按层次结构展现出来。原来用的是mxGraph组件,遇到几个问题:布局难以定制、节点样式难定制、交互有问题,后来改用Qunee组件,顺利解决问题。
这是一种典型应用,主要用到Qunee的布局类TreeLayouter,以及UI和交互的简单定制

树形布局效果

HTML5 Canvas绘制效率如何?

js运行效率在提升

编程语言的效率是前提,js自然比不上native的C语言效率,所以Canvas效率无疑比不上原生的2D图形绘制,但是js效率的提升是有目共睹的,以js与as为例,基本操作(运算操作,集合操作,Map操作)已经超越ActionScript,尤其是Google Chrome浏览器与as拉开了不小的距离,甚至某些方面超过java

JavaScript性能比较

Canvas绘制效率不低

Canvas没有dom操作,只是简单的2D绘制,所以效率不低,Chrome浏览器下,每秒可绘制五万个基本图形元素(圆形,矩形或者线条),如果有阴影效果会慢很多,总的来说上万元素的绘制还是很轻松的

适合简单应用

因为简单,做一些像素处理,2D绘制,小游戏啥的还是很方便的,国际上有javascript 1k作品大赛(http://js1k.com/),用1024字节的js代码,实现丰富的效果,基本上都用到canvas,所以在轻量小巧方面很有优势

附上SVG与Canvas的适用范围

canvas_or_SVG

复杂应用借助第三方开发包

对于复杂应用,需要自己来解决无效区域,局部刷新,交互选中等功能,自己实现有些难度,这时候我建议借助第三方开发包

Canvas学习资料

http://www.w3.org/TR/2dcontext/

https://developer.mozilla.org/en/docs/HTML/Canvas

http://www.w3schools.com/html/html5_canvas.asp

第三方类库

KineticJS – kineticjs.com

EaselJS – www.createjs.com/#!/EaselJS

Qunee – qunee.com

Fabric.js – fabricjs.com

HTML5之图形绘制技术(Canvas Vs SVG)

HTML5中的2D图形绘制技术

Canvas和SVG是HTML5中主要的2D图形技术,前者提供画布标签和绘制API,后者是一整套独立的矢量图形语言,成为W3C标准已经有十多年(2003.1至今),总的来说,Canvas技术较新,从很小众发展到广泛接受,注重栅格图像处理,SVG则历史悠久,很早就成为国际标准,复杂,发展缓慢(Adobe SVG Viewer近十年没有大的更新)

Canvas_Vs_SVG1

Canvas vs SVG

<canvas>和<svg>都是HTML5推荐使用的图形技术,Canvas基于像素,提供2D绘制函数,是一种HTML元素类型,依赖于HTML,只能通过脚本绘制图形;SVG为矢量,提供一系列图形元素(Rect, Path, Circle, Line …),还有完整的动画,事件机制,本身就能独立使用,也可以嵌入到HTML中,SVG很早就成为了国际标准,目前的稳定版本是1.1 – http://www.w3.org/TR/SVG/,两者的主要特点见下面的表格:

Canvas_Vs_SVG2

SVG与Canvas主要特点

根据两者的不同特点,Canvas和SVG有各自的适用范围

Canvas适用场景

Canvas提供的功能更原始,适合像素处理,动态渲染和大数据量绘制

SVG适用场景

SVG功能更完善,适合静态图片展示,高保真文档查看和打印的应用场景

canvas_or_SVG

HTML5的当下与未来?

HTML5技术而今已不再陌生,不管是趋之若鹜,热情拥抱,还是远远张望,保持距离,HTML5都是技术论坛热门的话题,给人的感觉就是酷、新、看上去很美

任何技术都有他的适用范围,HTML5技术是一种被夸大了的万金油,在目前浏览器支持不一,开发工具,第三方类库缺乏的情况下,HTML5无法解决一切问题,但如果限定它的使用范围,HTML5确实可以优雅的解决很多问题

HTML5是什么?

侠义的HTML5

侠义的HTML5指HTML下一个主要的修订版本,是W3C制定的标准,目前还在发展中,在HTML 4.01和XHTML1.0标准基础上,HTML5标准增加和修改了一些标签元素,其中多媒体相关的有<video>, <audio>, <canvas>,同时集成了SVG内容,数据内容的元素有<section>, <article>, <header>, <nav>, <menu>等,还提供了新的API,如2D绘图(Canvas),离线存储(Local Storage),加强版的cookie(WebStorage),拖拽,通讯(WebSockets),浏览历史管理,文件API(上传下载本地存储),位置API(Geolocation)等。

HTML5

更多HTML5的介绍,可参阅:

http://en.wikipedia.org/wiki/HTML5

http://www.html5rocks.com

http://dev.w3.org/html5/spec

广义的HTML5

广义的HTML5包括HTML, CSS和JavaScript在内的一套技术组合,其目标是减少浏览器对于插件的依赖,提供丰富的RIA(富客户端)应用。所以CSS3, SVG, WebGL, Touch事件,动画支持等都属于HTML5技术范围

广义HTML5

相关技术

Web相关组织

W3C – 万维网联盟 - http://www.w3.org/

WHATWG – 网页超文本技术工作小组 - http://www.whatwg.org/

为什么选择HTML5技术?

互联网趋势

随着网络架构的完善,宽带提升,网速满足实时交互需求时,计算机结构也将发生变化,光驱消失,硬盘消失,内存增大,GPU愈加重要,现在B/S结构的应用越来越多,而HTML5旨在富互联网应用,能够改善B/S结构应用的用户体验,是互联网应用的趋势之一

HTML5 Vs Flash

以前富客户端应用主要通过插件技术实现,比如Adobe Flash, Microsoft Silverlight, Java Applet,存在一些问题:需要安装插件,不支持移动设备,私有技术,没有国际标准等等,当然插件技术也有优势的地方,有特定的用途,下面就Flash技术和HTML5进行比较

HTML5_Vs_Flash

HTML5的缺点

HTML5目前最大的问题有三个:功能简单且分散、浏览器支持不一

功能简单且分散

HTML5是一种技术集合,包括各种标签及其相关API,HTML,CSS,SVG,JavaScript等,没有统一的开发工具,一个完整的HTML5应用涉及到多种技术,导致开发难度大,对于企业应用,HTML5的功能有限,需要借助第三方类库

浏览器支持不一

一直以来HTML5都以跨平台著称,但实际上要实现这一目标工作量巨大,HTML5绝少一个浏览器的标杆(Webkit有希望成为),尤其目前在IE6/7/8占有率居高不下的情况下,希望用HTML5跨全平台基本是不可能的

导致的结果是用户体验不佳,那么什么时候可以选择HTML5呢?

HTML5适用范围

酷的应用

曾经有人这样形容HTML5,doing anything cool (on the web),HTML5可以做很酷的应用,无需安装插件,就可以在网页中全屏观看高清视频,玩儿轻巧的在线游戏,体验流畅的动画效果,浏览精美的网络图,收听网络电台的音乐……一些小而美的应用非常适合HTML5,企业应用中的某些模块也可以选择HTML5

非得跨平台吗?

每种编程语言和技术都有特定的适用范围,如果你的目标客户是iPhone,你只需要考虑Safari for Mobile就可以了,如果还要考虑Android平台,选择支持Webkit内核,如果目标人群是高端用户,用些新技术也是可行的,如果非得所有平台都支持,在基本功能之外,使用HTML5技术增加一些亮点,也会很有吸引力

总结

目前HTML5已经可以解决很多问题,多少可以用到一部分,而面向未来互联网,基于“云+终端”的构架,终端的HTML5的兼容解决方案必然会出现,那时候你就可以全面拥抱HTML5了。

Safari Mobile中的事件处理 – touch, gesture, mouse events

Safari for Mobile中使用触控操作,传统的鼠标事件无法完全支持,比如没有mousemove, dblclick事件,要想灵活处理交互,可以通过监听TouchEvent和GestureEvent,下面是各个事件调用顺序的介绍:

保留的mouse事件

safari mobile中也保留有部分鼠标事件,如:mousedown/mouseup/mouseover/moouseout/mouseclick, 当然这些事件本身还是由touch事件开始触发的,准确的说只在单点触摸时触发,且在touch事件之后。

四种touch事件

touchstart, touchmove, touchend, touchcancel,分别表示触摸,移动,抬起手指,取消(我还不知道什么时候会调到这里)

三种gesture事件

如果有多点触摸,每个点都会派发自己的touch事件,当然处理一堆touch事件会比较麻烦,safari同时会派发gesture事件,包括gesturestart, gesturechange, gestureend, 分别表示开始多点触摸,触点在移动,结束多点触摸,IPhone中双指捏拉伸过程中都会派发这些事件。

单点触摸过程

多点触摸属于高级事件,我暂时用不到,只对单点的情况作处理。

判断是否是单点触摸:

evt.touches.length == 1

几种常见操作

点击 – tap

touchstart, touchend, (mouseout, mouseover,) mousedown, mouseup, click

点击移动 – tap and move

touchstart, touchmove, touchend

连续两次触摸 – double tap

touchstart, touchend, touchstart, touchend

多点触摸 – pinch

(touchstart, )gesturestart, touchstart, gesturechange, touchmove, gesturechange, touchmove, gestureend, touchend

从上面的事件顺序可以看到,只有在轻拍动作时会触发mouse 事件,其他情况下都不会触发(包括双击,两只手指同时点击……)

扩展事件

有很多种触摸操作方式,如双击(double tap),长按(touch and hold),捏(pinch)…没有直接这样类型的事件,比如safari mobile中并没有doubletap事件可以监听,也没有hold事件,只有上面列的四种touch,三种gesture,而像双击这样的比较常用,可以自己扩展, 如double tap:

双击时间的定制

svg.ontouchstart = function(evt){
    if(evt.touches.length == 1){
        var now = evt.timeStamp;
        if(this.touchTime && now - this.touchTime < 200){//时间间隔200ms时算 double tap
            delete this.touchTime;

   this.doubletap(evt, this); //这里判断是double tap
        }
        this.touchTime = now;
    }
};

同样touchhold也有办法,可以通过timer实现,复杂一下,这里不作细究

获取触点位置和target

touch 事件也有target属性,可以如桌面版的mouse事件同样处理
对于位置需要注意,因为touch事件包含多个触点的信息,也就是说包含多个触点的位置,对于单点触摸的情况,也要取touch集合中的第一个

var touch = evt.touches[0];//取第一个触点
 var x = touch.clientX;
 var y = touch.clientY;

备注:没有touch.layerX属性,用clientX代替,这可能与mobile上的缩放布局机制不同有关,待后研究

JavaScript中的等价操作符

JavaScript中存在两种等价操作符:相等”==”和全等”===”,前者对不同类型(比如String与Object)也可作等价判断,后者则必须要求类型相同,此外JavaScript中的任何对象都可以判断是非,也就是转换成boolean基本类型,这些都是ECMAScript语言(包括JavaScript)的基础

JavaScript中的四种基本类型

number, string, boolean, object

等价判断首先会判断对象类型,对于全等操作符,类型不一时,直接返回false,而对于相等”==”操作符则会按特定的规则,转换成number, string, boolean这三种基本类型,而后做判断

相同类型间比较

全等操作符(strict equality operator) “===”

  1. 如果类型不一致,返回false
  2. number,如果相同值,返回true,NaN不等于任何值,包括他自己,NaN可通过全局方法,isNaN(…)判断
  3. string,相同字符序列的返回true,有一种情况,相同的字符串使用Unicode标准可能有不同的编码方式,但遗憾的是,javascript只通过基本的字符比较,所有的字符串在比较之前,会先转换成“正常格式”。参考”String.localeCompare()”提供另一种比较字符串的方式
  4. boolean,同为true或false,返回true
  5. 相同引用表示是同一个对象
  6. 如果两者都是null或者undefined,表示他们相同

这里需要注意一点,NaN是个怪物,它不等于任何对象,甚至不等于自己:

NaN !== 0;
NaN !== NaN;
NaN != 0;
NaN != NaN;

相等操作符(Equality operator)”==”

相同类型之间的比较,有的人说等同于”===”,准确的说要除去null 和 undefined外,因为null == undefined ,但 null !== undefined ,余下的按全等的规则

null == undefined

不同类型间比较

相等操作符(Equality operator)”==”

javascript有四种类型对象,number, string, boolean, object,除去相同类型的比较外,不同类型之间会先通过类型转换,然后对二者比较,按排列组合存在六种情况:

  1. number , string >>> string转换成number,然后比较
  2. number , boolean >>> boolean转换成number,然后比较
  3. number , object >>> object.valueOf()转换成number,然后比较
  4. string , object >>> object.toString()转换成string,然后比较
  5. object , boolean >>> boolean转换成number,object转换成number,然后比较
  6. string, boolean >>> string转换成number, boolean转换成number,然后比较

补充:object转换成number:先object.valueOf()或者object.toString(),没有上面的方法的话找基类的相关方法(这里涉及到ToPrimitive()转换,这里不多介绍),得到的结果再转换成numberboolean转换成number:true是1,false是0

示例:

var a = "yCoder.com";
 var b = {valueOf: function(){return 1}, toString: function(){return "yCoder.com"}};
 a == b;//结果为true
 b == 1;//结果为true

关于对象是非的判断 – ToBoolean(…)

JavaScript中可以直接判断对象true和false,比如下面的代码:

if(a){ }
if(!a){ }

实际上这里就是将对象强制转换成了boolean基本类型,是执行的ToBoolean(o)操作,规则如下:

  • Boolean : 不变
  • Undefined/Null : false
  • Number : +0, -0, NaN –> false 其他为 true
  • String : ” –> false 其他为 true
  • Object : true

以一个题目结尾

曾看到过一道有名的javascript题目,其中有一处判断语句如下:

var a = [];
if(a == !a){
    alert("a == !a");
}

问a==!a是否为真,这里就涉及到前面提到的关于object >> boolean,以及object与boolean类型间等价判断的问题,留给大家思考

JavaScript类继承与属性定义

Extjs的类继承——$.extend

Extjs是比较早期的web企业组件,代表了面向对象编程思想在js中的实践,其中最基本的就是类的继承,通过对prototype和constructor的复制和设置实现,但实现代码并不是那么容易,看过extjs的extend代码就会明白其难度,没有相当js经验很难看懂,当年看这块儿费了不少精力,后来考虑到版权问题,以及代码简化的需要,自己实现相关功能,经历几番修改才得以稳定

下面是最简化的实现,以及测试例子,当然这个实现存在些问题,比如对于javascript 1.8中的get set不支持,需要自行改造

function extend(sb, sp) {
	var sbp = sb.prototype;
	var F = function() { };
	F.prototype = sp.prototype;
	sb.prototype = new F();
	sp.prototype.constructor = sp;
	for (var name in sbp) {
		sb.prototype[name] = sbp[name];
	}
}
//test
function A() { }
A.prototype.name = "A";
function B() { }
extend(B, A);

var a = new A();
var b = new B();
console.log(b.name == "A");
console.log(b instanceof B);
console.log(b instanceof A);

打印结果全为true

JavaScript 1.8

到HTML5,出现了很多新的东西,很多高级应用不再考虑IE6,甚至IE7, 8,主流浏览器开始支持JavaScript 1.8,增加了新功能,支持严格模式-”use strict”,而getter, setter也有了更多的实现方式

Getter/Setter

get set语法

首先是直接语法上的支持,写法类似ActionScript

var foo = {
    get test(){ return this._test; },
    set test(value){
        console.log(value);
        this._test = value;
    }
};
foo.test = "abc";

函数支持 – Object.defineProperty/ defineProperties

此外还可以通过函数调用的方式实现,Object上定义了一些有用的方法,可以实现类的构造,函数扩展,属性扩展等功能,详见:https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Working_with_Objects

示例:

var Canvas = function(){};
Object.defineProperties(Canvas.prototype, {
    name: {
        get: function(){
            return this._name;
        },
        set: function(value){
            console.log(value);
            this._name = value;
        }
    }
});
var g = new Canvas();
g.name = "Qunee.com";

这里需要注意两点:

  • 只支持Object – 而不能是Function,比如上面的例子,只能是Canvas.prototype而不是Canvas
  • 部分属性名不可使用 – 比如”length”

严格模式 – “use strict”;

严谨模式就是在代码前加上下面这行代码:

"use strict";

“strict mode”限制了一些不安全的语法,使代码可读性增加,更便于调试,此外js引擎可以完全抛开老的兼容语法,从而提升性能

可参阅这篇文章:http://www.alloyteam.com/2012/06/it-is-time-to-use-the-javascript-strict-mode-strict-mode-to-enhance-the-efficiency-of-team-development/
详见:https://developer.mozilla.org/en/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode

famo.us是什么?

初次访问famo.us,被他的动画和交互效果所震撼,研究过其代码后,发现用到三种技术:matrix3d变换,requestAnimationFrame实现动画,以及物理运动引擎,单从技术上看三者都不难实现,但事物表面背后往往隐藏深意,famo.us的由来和目标却是野心勃勃。

famo.us2

创始人为web apps性能低下困扰已久,后受到Twitter Bootstrap的启发,试图提供一种用于开发本地级运行效率的web app框架,什么Sencha touch, jQuery Mobile等都是低效的代名词,这些为website而生的东西不适合复杂的web apps应用,应绕开浏览器固有的一些缺陷(document 渲染机制,CSS3导致的性能问题,浏览器之间的差异等等),实现一种针对web app的渲染引擎。

对于famo.us能否真正带来一波web app开发的热潮,尚不可知,从各种资料来看,已经有了一些app示例,但我未曾亲眼所见,目前公开的只有官网的元素周期表的例子,平板上运行也算流畅,但耗电厉害,实用性有待考证。

对技术感兴趣的朋友,可以看看这篇演示文稿:http://www.slideshare.net/befamous/html5-devconf-oct-2012-tech-talk ,作者详细介绍了famo.us 技术上的由来,作为演示文稿,循序渐进,简洁明了的思路也是值得借鉴的

famo.us

下面是2012年九月,famo.us的第一封简报,原文:http://us5.campaign-archive1.com/?u=4656ba2b0a364690c8530bc1e&id=675bbf010f

为什么我们如此特别

尝试使用HTML5构建一个web应用,实现可靠的本地程序级的运行效率,通过诸如Sencha Touch,jQuery Mobile和Appcelerator Titanium这样的框架是不可能实现的,实际上,很多公司,譬如Facebook,已经宣布放弃一些在HTML5上的努力,因为浏览器的一些固有问题需要很长时间来解决。Famo.us之所以特别,是因为我们实现了一种渲染引擎,绕开了浏览器的这些固有问题,从而实现可靠的本地级别高性能的复杂web应用,兼容多种设备,简单的说,经过多年的开发,我们解决了困扰复杂web应用的性能问题,应用的布局,动画和设计这些原本只存在于本地应用的东西,现在也可以用于web开发中,我们希望能带来一波从未有过的web app开发浪潮

一旦我们有了突破,下一步我们将寻求一种方式来分享这些成果,以社区驱动,检验,接受和合理分析

famo.us是什么?

如果你喜欢Twitter Bootstrap,那么你将爱上famo.us,很多方面我们都视Bootstrap为灵感来源
Bootstrap 引导web开发者构建跨设备访问的网站,给开发者提供视图图层,网站布局,框架,UI(用户界面)和UX(用户体验)组件,主题,字体和JavaScript插件
Famo.us 引导web开发者构建跨设备访问的应用程序,给开发者提供视图图层,应用布局,框架,UI和UX组件,主题,字体和JavaScript插件

路线图

我们将参照Bootstrap类似的展示方式,当我们正式启动,我们将公开我们GitHub上的工程,这样你可以分享和连接,我们还会创建Google组,你可以提问,Mark和我会直接回复,我们还会通过简报,博客(当它发布的时候),twitter @befamous 进行更新,我们将花费大量的时间保证文档完整和示例打包,就时机而言,我们希望第一个完整版本能在今年晚些时候发布(主要取决于文档)

使用 famo.us

famo.us的开发与Bootstrap类似,使用famo.us你可以先从应用布局开始,然后混合和匹配相应的famo.us 的UI和UX组件和部件

在我们的”hello world”应用中,你将使用famo.us 的卡片布局(Spotify, Twitter, Facebook和很多其他应用都使用这样的布局)构建一个Twitter iPad 应用的复制品,并采用了famo.us的UI和UX组件,并填充了一些演示数据,一旦你掌握了famo.us的窍门,你可以选择替代的应用布局,并按你所喜欢的修改,实际上你可以创建自己的应用布局,组件和主题,并将他们分享到famo.us市场,我们的目标是所有本地应用的主流布局,另外我们希望能和社区合作创造出更多东西,每个应用布局将能用于iOS和Android,同时作为Web app或者包装进一个本地app,实现手机,平板和PC上布局的灵活转换。