像jQuery提供 fn.extend() 方法从而可以简单地创建插件一样,jQuery UI也提供了机制使得创造插件变得简单,也确保了公共API功能在新的插件中被保留。

1.首先,创建一个名为  jquery.ui.calculator.js 的文件,代码如下:

(function($) { $.widget("ui.calculator", { options: { autoShow: true, currentSum: [] }, _create: function() { }, destroy: function() { }, disable: function() { }, enable: function() { }, }); })(jQuery);

我们通过 $.widget() 方法定义我们的插件。这个方法接受两个参数。第一个参数定义该插件的名称,此名称需以 ui 命名空间开头。第二个参数是可选属性,表示插件的功能,包含属性和方法。

此处,我们有两个配置选项。

autoShow定义当页面加载时,是否播放。

currentSum是一个空数组。

_create用来添加初始化函数,

destrory,disable,enable方法是公共API,我们总是需要定义这些方法。

2. _create函数代码如下

_create: function() { var div = $("<div />"), list = $("<ul></ul>", { "class": "ui-helper-reset ui-helper-clearfix" }), li = $("<li />", { "class": "ui-corner-all ui-state-default" }), a = $("<a />", { href: "#", "class": "ui-calculator-button" }), container = div.clone() .addClass("ui-calculator-container ui-corner-all ui-widget- content ui-helper-clearfix"), display = div.clone() .addClass("ui-corner-all ui-widget-content ui-calculator- display").text("0").appendTo(container), numberpad = div.clone() .addClass("ui-calculator-numberpad").appendTo(container), functionpad = div.clone() .addClass("ui-calculator-functionpad").appendTo(container), numberlist = list.clone().appendTo(numberpad), functionlist = list.clone().appendTo(functionpad), buttons = ["","clear",7,8,9,4,5,6,1,2,3,0,"."], functions = ["/", "*", "-", "+", "="]; for (var x = 0; x < buttons.length; x++) { var listitem = li.clone().appendTo(numberlist), linky = a.clone().text(buttons[x]).appendTo(listitem); if(x === 0) { $("<span />", { "class": "ui-calculator-icon ui-icon ui-icon-arrowthick-1-w", text: "Backspace" }).appendTo(linky); } else if (x === 1 || buttons[x] === 0) { linky.addClass("ui-calculator-button-wide"); } } for (var y = 0; y < functions.length; y++) { var listitem2 = li.clone().addClass("ui-state-default") .appendTo(functionlist), linky2 = a.clone().text(functions[y]).appendTo(listitem2); } this.element .addClass("ui-calculator ui-widget ui-helper-reset"); (this.options.autoShow) ? container.appendTo(this.element) : container.appendTo(this.element).hide(); this.element.this("li").bind({ mouseenter: this._addHoverState, mouseleave: this._removeHoverState, click: this._buttonClick }); },

一开始我们定义了一些列的变量。前四个变量(div , ul , li , a)是我们创建用来构建控件必须的一系列元素。我们添加任何必须的每次基本元素上我们都要用到的一般属性。如 class,anchor,href.

接下来的六个变量是实际的元素,比用来构建控件,从基本元素克隆而来,并添加主题必须的class扩展他们。

我们使用for 循环在 buttonpad 容器中创建按钮容器。按钮由 <a> 构成,被包装在 <li> 中。他们中的一些按钮不是数字键,如回退,清除键。回退键有一个额外的 <span> ,用来显示 返回箭头 的图标。这是按钮数组中的第一个按钮。

清除键和 0 键,比其余的按键宽,我们知道清除label是按钮数组中的第二个按钮,所以我们能发现试用了数组索引1。 0 键是检查实际数组的值。这两个按键使用 ui-calculator-button-wide,其他按键上使用 ui-calculator-button。

我们使用另一个循环创建功能键,如除,乘等。将他们追加到第二个容器中。这时,没有一个按钮拥有附加元素或特殊的class,所以我们不需要 if 条件。

在函数中定义的this对象被局限于我们的插件。jQuery UI给我们的对象添加了两个特殊的属性,第一个是被称为 元素 ,指向触发插件方法的实际元素。第二个被称为 选项,参照 我们在插件一开始定义的属性配置对象。

当插件方法被触发时,我们通过 this.element 给元素添加一些 class 。这时我们检查 autoShow 选项,如果是默认值——true,我们只需附加我们的插件到页面。如果设为 false,我们依然附加它,但是立即 hide 它。

_create函数中做的最后一件事情,是附加一些 event handles 给 <li>。我们还没有 event handles 函数,添加后,我们能通过 this 对象访问他们。event handling 功能不能直接实现,我们用下划线做前缀。

3.公共API方法

destroy: function() { $.Widget.prototype.destroy.call(this, arguments); this.element .removeClass("ui-calculator ui-widget ui-helper-reset"); this.element.find("li").unbind(); this.element.children(":first").remove(); }, disable: function() { $.Widget.prototype.disable.call(this, arguments); this.element.find("li").unbind(); }, enable: function() { $.Widget.prototype.enable.call(this, arguments); this.element.find("li").bind({ mouseenter: this._addHoverState, mouseleave: this._removeHoverState, click: this._buttonClick }); },

所有这些功能遵循一个共同的格式,jQuery UI为我们做了重量级的。控件工厂已经定义了他们的方法,我们要做的是调用控件工厂使用JavaScript call() 函数定义的原始方法。原始方法能使用我们希望调用、附加给 $.Widget.prototype 的方法的名字,通过控件属性被访问。我们可以提供一些附加的代码。

在销毁功能中,我们移除了 class ,解除绑定了 event handlers ,移除了 DOM 结构。

在禁用功能中,我们再一次调用控件原始 禁用功能,然后简单地解除按钮上绑定的 over-states和 点击 。

在启用功能中,我们再一次调用控件工厂的原始启用方法,然后再一次添加我们的event handles。

3.添加自定义方法

我们提供了 autoShow选项,所以我们的控件可以附加到页面但不立即显示。我们需要提供一个在需要时,可以被用来显示控件的方法。

show: function() { var el = this.element.children(":first"); if (el.is(":hidden")) { el.show(); } this._trigger("show", null, this.element); },

我们的方法用一个键 show 存储着,所以开发者可以想使用我们已经定义的标准API方法

(如$(”#el”).calculator(“show”))一样使用它。在这个功能中我们需要做的是找到那个附在了控件的外层元素的第一个子元素,并在当前隐藏的情况下显示它。

一旦我们显示计算器,我们就出发了自定义事件。当开发者使用我们的控件hook关键的交互点时,这使得它变得很有用。 _trigger()方法接收三个参数:第一个用于触发事件,第二个用于原始浏览器事件对象,第三个是参照存储在 this.element中的元素。即使在自定义方法中,this 对象依然局限于我们的控件实例。注意这个 this 可以被任何我们想要传给 handler功能的开发者为我们自定义事件定义的 hash 键值对 。

4.在 _create()功能中,我们绑定了一些时间,如 mouseenter ,mouseleave ,click 。我们现在需要添加 handler 功能,当这些events 检测到被我们的空间检测到时,做出反应。

_addHoverState: function() { $(this).addClass("ui-state-hover"); }, _removeHoverState: function() { $(this).removeClass("ui-state-hover"); }, _buttonClick: function() { var buttonText = $(this).text(), display = $(".ui-calculator-display"), newArray = $.ui.calculator.prototype.options.currentSum; if (buttonText == "Backspace") { if (display.text() !== "0" && display.text().length > 1) { newArray.pop(); $.ui.calculator.prototype.options.currentSum = newArray; display.text(function(i, orig) { return orig.substring(0, orig.length - 1); }); } } else if (buttonText == "clear") { $.ui.calculator.prototype.options.currentSum = []; display.text("0"); } else if (buttonText == "=") { result = eval ($.ui.calculator.prototype.options.currentSum.join("")); display.text(result); $.ui.calculator.prototype.options.currentSum = [result]; } else if (buttonText == "/" || buttonText == "*" || buttonText == "-" || buttonText == "+") { $.ui.calculator.prototype.options.currentSum.push(buttonText); display.text(buttonText); } else { $.ui.calculator.prototype.options.currentSum.push(buttonText); if (display.text() == "0" || display.text() == "/" || display.text() == "*" || display.text() == "-" || display.text() == "+") { display.text(""); } display.text(function(i, orig) { return orig + buttonText; }); } }

当mouseenter和mouseleae事件被检测到,这个功能被调用。我们仅仅添加和移除适合的状态class ,这样 悬停状态被应用并分别被移除。

点击 handler 有点复杂,但是所有我们做的,是检查按钮被点击,并且为不同类型的按钮不同方式的反应。

在单击 handler中,我们做的第一件事,是存储一些变量,包括被点击按钮的文本,控件的播放元素,currentSum 配置选项的备份。因为 this 对象不再局限于我们的控件实例,我们不能使用this.options访问这个选项,但是我们依然可以通过使用$.ui.calculator.prototype.options这个控件属性访问他们。

我们这时有一个if 声明,检查每个按钮的类型,包括 backspace ,clear ,= ,/,+等功能键和数字键。

如果回退键 被点击,我们检查 显示 不是仅仅由 0 构成,并且将要显示的文本长度比一个字节长。如果条件,我们将控件属性中获得的 currentSum 移除最后一个项目。使用新的短数组更新currentSum,并且这时从将要显示的文本中移除最后一个字符。

如果清除键被点击,我们仅仅通过设置currentSum选项的值为空数组来清空它,并且将显示块重设为0。

如果 = 键被点击,我们估计存储在currentSum数组中的表达式,在显示元素中显示结果,并在这时更新currentSum,以使它近包含结果。

如果任何其他功能键被点击,我们仅仅添加按键上的文本到currentSum数组,并将显示元素的文本为被点击按键的文本。

最后,如果任何数字键被点击,我们首先检查当前将要显示在计算器上的是什么。如果它是0或功能键,我们清空显示元素。我们这时用心数字更新显示。这时如果一个数字已经被点击,这时显示向新数字一样被更新为包含原始数字。但是如果功能键被按下,数字像一个新数字 +1。

5.控件的样式表

.ui-calculator { width:9.65em; } .ui-calculator-container { padding:.2em .2em 0; } .ui-calculator-display { width:12.3em; padding:.3em; margin-bottom:.3em; font-size:0.7em; overflow:auto; } .ui-calculator-numberpad { width:7em; float:left; } .ui-calculator-functionpad { width:2em; float:left; } .ui-calculator li { float:left; margin:0 .2em .2em 0; } .ui-calculator-button { display:block; width:2em; height:1.2em; padding:.3em 0 .5em; text-align:center; border:0; } .ui-calculator-button-wide { width:4.3em; } .ui-calculator-icon { margin:.2em auto; }

jquery.ui.calculator.css

6.使用控件

   1:  <!DOCTYPE html>
   2:  <html>
   3:    <head>
   4:    <meta charset="utf-8">
   5:    <title>Widget Factory - calculator
   6:    </title>
   7:    <link rel="stylesheet"  
   8:      href="css/smoothness/jquery-ui-1.8.9.custom.css">
   9:    <link rel="stylesheet"   href="css/jquery.ui.claculator.css">
  10:    </head>
  11:    <body>
  12:      <div id="calc">
  13:      </div>
  14:      <script src="development-bundle/jquery-1.4.4.js">
  15:      </script>
  16:      <script src="development-bundle/ui/jquery.ui.core.js">
  17:      </script>
  18:      <script  
  19:        src="development-bundle/ui/jquery.ui.widget.js">
  20:      </script>
  21:      <script src="js/jquery.ui.calculator.js">
  22:      </script>
  23:      <script>
  24:        (function($) {
  25:          $("#calc").calculator({
  26:            autoShow: false,
  27:            show: function(e, ui) {
  28:              alert(e + ", " + $(ui).attr("id");
  29:            }
  30:          });
  31:        })(jQuery);
  32:      </script>
  33:    </body>
  34:  </html>

calculator.html

【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.3.创建控件的更多相关文章

  1. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.6.Dialog控件

    习惯上,我们播放一条简短的信息,或向浏览者询问一个问题,都会用到dialog. 创建一个基本的dialog 使用dialog 选项 形式 启用内置动画 给dialog添加按钮 使用dialog回调函数 ...

  2. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.10.Button 和 Autocomplete控件

    Button ,可以使用 <button> <input> <a>. <input> 中的不同类型,submit , radio , checkbox ...

  3. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.8.Datepicker控件

    默认datepicker的安装启用 探索它的配置选项 安装启用一个触发按钮 配置一个供选择的动画 dateFormat选项 简单的国际化 多月datepicker 日期范围选择 datepicker的 ...

  4. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.7.Slider控件

    默认slider的安装启用 为slider自定义风格 修改配置选项 创建一个垂直的slider 设置最大最小值,和默认值 启用多个 手柄 和 范围 slider内置的回调事件 slider的方法 这个 ...

  5. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.5.Accordion控件

    accordion是另一个UI控件,能允许你将一组content加入相互分隔的.能够被浏览者的交互打开或关闭的panels中.因此,它大多数的content在初始化的时候是隐藏的,很像tabs控件.每 ...

  6. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.4.Tabs控件

    之前,我们已经介绍了 jQuery UI 库,CSS 框架.下面,我们将学习这些有增强可视化效果,高度可配置的用户交互组件. Tab 的特性是,点击 tab 后,会高亮该 tab,并显示他的关联con ...

  7. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.2.更换主题

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.1.CSS框架和其他功能

    jquery.ui.all.css 1.所有主题必须的文件都包含在这个文件中.它由ui.base.css和ui.them.css两个文件中拉入的@import执行构成. jquery.ui.base. ...

  9. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.9.Progressbar控件

    Progressbar控件用来显示任意进程的完成百分比. 默认安装启用 配置选项 控件暴露的事件API progressbar暴露的独一无二的方法 一些现实生活的例子 当前版本中,我们或系统必须明确进 ...

随机推荐

  1. 网站提供的下载IE8很慢 由于Microsoft 联机服务暂时不可用,SmartScreen筛选器无法检查此网站。

    在内网环境中,网站系统提供了一个下载功能,用ie8下载特别慢,一个20kb的文件,下载要10分钟,但是在其他环境中是很快的,试了半天,原来是:由于Microsoft 联机服务暂时不可用,SmartSc ...

  2. window.location.href和window.open的几种用法和区别

    使用js的同学一定知道js的location.href的作用是什么,但是在js中关于location.href的用法究竟有哪几种,究竟有哪些区别,估计很多人都不知道了. 一.location.href ...

  3. 防止IE不支持console.log报错

    function log(msg){ if (window["console"]){//判断是否是IE console.log(msg); } }

  4. python故障查找:超时未设置

    最近一台基于python的应用服务总是出现问题.需求是用户可以在页面上提交批量处理任务,后台把这些任务入到一个Queue里排队处理,然后通过一个线程专门处理.现在总是偶尔出现假死状态,任务处理中断执行 ...

  5. fpm来制作rpm包

    转自 http://blog.halfss.com/blog/2013/02/26/fpmbao-guan-li/ 另查看 http://my.oschina.net/lxcong/blog/1438 ...

  6. linux:什么是linux

    1>.linux是一套作业系统(linux就是核心与呼叫这两层),每一种作业系统都是在他专门的硬体机器上面运行的:linux是一个Open Source的作业系统,具有可移植性 2>.li ...

  7. 转:Java的各种类型转换汇总

    java类型转换 Integer String Long Float Double Date 1如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Intege ...

  8. jquery ajax 个人总结

    jquery : 在获取对象的时候,不要用dem的与jquery的混合写法,有的时候 用js获取到的对象 没有JQUERY对应的方法  会报一些不知道的错误.(即如果要使用jquery 就使用jque ...

  9. VS2010程序打包

    今天,小白就来给各位做个打包的新手教程,此文仅是为了记录自己的学习过程与方便其他初次接触的打包的朋友们总结一下,希望大家能够受用.废话不多说,下面我们就来讲解下打包工程.首先,在项目中添加一个安装项目 ...

  10. HDU 2993 MAX Average Problem(斜率优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993 Problem Description Consider a simple sequence w ...