Chrome 扩展开发,定制多功能框(omnibox)

原来一直想着用完整的 Web 应用或 GUI 来做些增强效率的工具集,其实我们每天打交道的浏览器,进行下扩展就能好好的利用。粗略对比了下 Chrome 和 Firefox 的插件系统,Chrome 的插件开发应该要比 Firefox 的简单,无需引用什么新的概念,像 XUL。

例如,想实现一下 omnibox,即 Chrome 的全功能框(地址栏),想要地址栏进入自定的 Unmi 模式,输入关键字让 google 去本站查询,或是输入 tag, category 直接进入本站的相关 tag, category 日志列表,在当前浏览器的 Tab 中打开目的页面。

比如在地址栏上输入关键字 "u>", 然后按空格或 Tab 键就进入到 Unmi 模式,如图

unmi_omnibox

下面是完整开发步骤 阅读全文 >>

AngularJS HelloWorld

经历过一个使用 Backbone.js 的项目,把 Backbone.js 也弄得七七八八了,关键是它比较容易理解。最近接触一个使用了 AngularJS 的项目,乍一看那可是两头雾水,它是一个 MVW(Model - View - Whatever) 型的 Javascript 框架。它与 Backbone.js 相比门槛就要高些了,我的第一感觉。一般都说 MVC,AngularJS 引入个 W(Whatever) 概念来意味就更深远了。

AngularJS 抛却了传统的 Javascript 的操作理念,不再是 Dom 上绑定事件,触发事件,操作 Dom 这样的思维。它在 HTML 代码中的表现就是那些 ng-* 属性,以及 {{...}} 括起来的 AngularJS 表达式。一个简单的操作甚至不需要写一行 Javascript 代码,在 AngularJS 的首页就有几个基本的例子,我体验了类似第一个例子,大概是这样子的 阅读全文 >>

Backbone.js 使用 Collection

在前面我们的 Backbone.js 用上了 Model, 但绝大数的情况下我们处理的都是一批的 Model 数据列表,所以需要有一个 Collection 来容纳 Model, 就像 Java 里最常用的 List。

声明 Collection 时需要指定他处理的 Model 类型,也就是个泛型参数,如我们这样定义 Collection:

然后就是往 Collection 中如何填充 Model 实例,有好多种,这里只演示最直接的方式。还 add, fetch, 及对 Collection 排序, 遍历等各种操作。 阅读全文 >>

Backbone.js 中使用 Model

前面几篇 Backbone.js 的例子中有使用到 template, 及数据的填充,其实这已经很接近 Model 了。现在来学习怎么创建自己的 Model 类,并简单的使用。Backbone.js 中 Model 会涉及到很多的概念,如 Model 的初始化,默认值,属性的读写,属性值改变的监听,数据渲染,校验,以及与服务端的数据同步等。

本文不打算讲前面大部分的内容,最初思考的一个脉络是怎么把 Model 引入进来,所以线索会是 建立 Model 类 -> 初始化 Model 实例 -> 设置值 -> 渲染到页面,其余 Model 特性分别再深入。

直观地能想到的 JavaScript 的 Model 是一个 JSON 对象,差不多,不过 Backbone 赋予 Model 默认属性,只能通过 getter/setter 方法来访问 Model 中的属性值,不能直接用点操作符,相当于 Backbone 的属性是私有的。 阅读全文 >>

Backbone.js 的 View 中定义事件

使用 Backbone 的 View 时,可以象传统 jQuery 那样定义事件,$("selector").click(function(){...})。幸运的是 Backbone 让我们在 View 中定义事件变得更为简单和集中,只要设置 View 的 events 属性,配置 事件,元素以及相应的处理方法,基本模式如下:

    events: {
        "click button": "event_handler",
        "focus #name": "event_handler"
    },
    event_handler: function( event ){
        alert(event.target.id);
    }

格式是 "事件 选择器": "事件处理函数名", 奇怪为什么这里不是使用事件处理函数名的引用,也就是不能写成下面两种方式: 阅读全文 >>

Backbone.js 使用模板

前面一篇 Backbone.js HelloWorld,应用起步 只是让 Backbone 跑起来,实际的应用中会使用到模板,Model 等,而模板又是进阶的基础。所以这里介绍在 View 中使用模板,以及如何向模板填充值,模板可以用字符串,或是用 <script type="text/template"> 声明的内容。使用 <%= %><%- %> 来声明变量输出的占位符。

Backbone 的模板要用到的是 underscore.js 库, 要深入了解 Unserscore 就看官方的 Underscore.js 的文档,Underscore 的 template 方法的原型如下:

_.template(templateString, [data], [settings])

下面是些完整的例子

一: 使用字符串模板

阅读全文 >>

Backbone.js HelloWorld,应用起步

Backbone 是一个 JavaScript 框架,可用于创建模型-视图-控制器 (model-view-controller, MVC) 类应用程序和单页界面。它试图让 JavaScript 应用程序更清晰结构化,所涉及到的概念有  View, Event, Model, Collection 和 Router,所以新手刚开始接触 Backbone 反而会显得零乱了。再加上网上找来的一些起步教程一上来就把 Event, Model, Collection 或是 Router 揽上了。其实新手最想要一个最简单的真相,因此第一个例子只需用到 View,其他的玩艺暂且搁置。

Backbone 强依赖于 Underscore,jQuery 是可选的,不过为操作 DOM 方便一般都会引用到 jQuery。

最简单的例子,分两步走:

1. Backbone.View.extend(obj) 创建一个 View 类型
2. 创建上一步得到的 View 的实例,实例化时将会调用前一步 obj.initialize() 方法

上代码(为方便起见,所有 JS 脚本都从公网上加载): 阅读全文 >>

JavaScript 获得代码行号和脚本文件名

比如要写一个 JavaScript 的日志输出工具,在方法 log.info() 中能得到调用它所在的文件和代码行号。和众多的日志工具一样,像 log4j,都是在程序代码中主动抛出异常,然后从异常栈中去查找到调用者所在的代码行和文件名。不过也就刚刚才了解到 JavaScript V8 引擎提供了自己的 StackTrace API,Chrome 和 Node.js 可用。先来看可通用的 JavaScript  抛异常 throw new Error() 的方式,下面的代码:

点击链接 http://jsfiddle.net/Unmi/53xas/ 执行,其中是用 document.write() 输出的,完整异常栈是: 阅读全文 >>

JSON.stringify(obj) 时 TypeError: cyclic object value 异常

从 ECMAScript 5th Edition 开始,JavaScript 内建了 JSON 对象,用来处理 JSON 的序列化和反序列化,有以下几个方法原型

JSON.stringify(obj [,filter]  [,indent])
JSON.parse(text [,reviver])

jQuery 也提供了 jQuery.parseJSON 方法,但是没有相应的序列化方法。

如果用  JSON.stringify() 来对一个有循环引用的 JSON 对象进行序列化,会产生 TypeError: cyclic object value 异常,类似下面的代码

点击链接 http://jsfiddle.net/Unmi/6eLFF/ 运行上面的代码  阅读全文 >>

JavaScript 模块应用与编程

前边有一篇关于 JavaScript 对象声明,可以作为是 JavaScript 模块化的一个铺垫。这里会涉及到两个话题模块的定义和引入,对于模块化的编程语言,我们可以用 include, require 或 import 那样的谓词来引入模块。回想下我们对于非模块化的 JavaScript 是怎么引入的,比如在 html 文件里 js 文件,用 <script src="some.js"></script>。如果是更动态一点就会用 document.createElement("script"), 再指定它的 src 属性为一个 js 文件,添加加到 DOM 中去的方式来加载 js 文件。

上面两种方式都不够优雅,我们现在想要实现为 require() 函数来引入 js 库的方式,所以 JavaScript 模块的规范就出现了 CommonJSAMD(Asynchronous Module Definition) 两种。

1. CommonJS

CommonJS 中有一个全局的  require() 方法,它就是执行 require() 代码后马上使用模块提供的属性或方法,它假定执行完 require() 行后,模块即已就绪。例如加载一个 'math' 模块

var math = require('math');
math.add(2, 3);

阅读全文 >>