jQueryUI如何自定义组件

第一次自定义jQueryUI Widget

又是第一次,现在的感受是jQueryUI Widget能让你代码组织得更好,风格更一致。

如何开始使用

首先用$.widget()方法开始定义你的组件,它只接收三个参数:第一个是组件名称,第二个是可选的基类组件(默认的基类是$.Widget),第三个是组件的原型。

组件名称必须包含命名空间,要注意的是,官方组件的命名空间是以‘ui’开头的,比如:‘ui.tabs’。我在下面的用‘我’的拼音(‘wo’)。


	$.widget("yourNamespace.yourWidgetName",[yourBaseWidget],yourWidgetPrototype)

$.Widget基类含有一个重要的属性‘options’,它用来定义公有参数,组件初始化时外部调用的参数会覆盖内部定义的参数;以及三个重要的私有的方法‘_create’、‘_init’、‘’,前两个相当于构造函数的作用,按顺序执行,_create()方法执行之后会触发'create'事件。 _trigger()方法会将参数中的指定函数标准化为W3C事件,并且触发这个自定义事件。
另外还有三个公有方法‘enable’,‘disable’,‘destroy’,分别表示启用、禁用和销毁组件。

这里很有意思的,是私有方法和公有方法的实现。jQuerUI Widget暴露的方法都是不以‘_’开头的:


	// prevent calls to internal methods
	if ( isMethodCall && options.charAt( 0 ) === "_" ) {
		return returnValue;
	}

实际上,jQueryUI Widget还是保留了原始的API,比如这样使用:


	var $div = $('.demo:first');
	var api = $div.data('divZoom');
	// console.dir(api);
	api.zoomIn();
	// 对比
	$div.divZoom('zoomIn');

一个实现完全私有变量的小技巧:


(function($) {
	var privateVar = '';
	$.widget("wo.divZoom",{});
})(jQuery)

所有代码


/*
* @by   ambar
* @create 2010-10-20
* @update 2010-10-25
*/

(function ($) {
  var html = '<div class="icon-zoom">\
          <span title="zoom in" class="zoom-in">zoom in</span>\
          <span title="zoom out" class="zoom-out">zoom out</span>\
        </div>';
  $.widget("wo.divZoom", {
    _init: function () {
      var self = this,
          opt = self.options,
          tgt = opt.target,
          $el = self.element;
      // 初始一次
      if ($('div.icon-zoom', $el).length) return;
      $el.append(html);

      self.target = (tgt == '' ? $el : $el.find(tgt));
      // 检测初始值
      var level   = self.target.attr(opt.dataPrefix);
      self.target.attr(opt.dataPrefix, level || opt.level[0]);

      self.btnZoomIn  = $el.find('span.zoom-in').click($.proxy(self.zoomIn, self));
      self.btnZoomOut = $el.find('span.zoom-out').click($.proxy(self.zoomOut, self));
    },
    destroy: function () {
      this.element.find('div.icon-zoom').remove();
    },
    options: {
      level     : [120, 160, 200],
      target    : '',
      speed     : 'normal',
      dataPrefix: 'data-zoom-level',
      zooming   : null,
      select    : null,
      show      : null
    },
    currentLevel: function () {
      var self = this, opt = self.options, lvl = Number(self.target.attr(opt.dataPrefix));
      return $.inArray(lvl, opt.level);
    },
    zoomIn: function () {
      this.zoom(this.currentLevel() + 1);
    },
    zoomOut: function () {
      this.zoom(this.currentLevel() - 1);
    },
    zoom: function (i) {
      var self = this, opt  = self.options, lvls = opt.level, $tgt = self.target;

      if (i <= -1 || i >= lvls.length) return;

      var value = lvls[i], originalValue = lvls[self.currentLevel()], style = { width : value, height: value };
      var data = { target: $tgt, css: style, originalCss: { width : originalValue,height: originalValue } };

      var goon = self._trigger('start', null, data);
      if (!goon) return;

      $tgt.animate(style, {
        duration: opt.speed,
        step: function (val) {
          var css = { width: val, height: val };
          self._trigger('zooming', null, $.extend({}, data, { css: css }));
        },
        complete: function () {
          $tgt.attr(opt.dataPrefix, value);
          self._trigger('stop', null, data);
        }
      });
    }
  });
})(jQuery)

在页面上调用


	<script src="js/jquery-1.4.4.min.js"></script>
	<script src="js/jquery.ui.widget.js"></script>
	<!-- 自定义的 -->
	<script src="js/jquery.ui.wo.divZoom.js"></script>

	<script type="text/javascript">
  $(function () {
    $('div.demo').divZoom({
      target: '>a',
      level: [80, 120, 160, 200],
      zooming: function (e, ui) {
        // console.log(e,ui.css);
      },
      start: function (e, ui) {
        console.log('开始', this, e.type, ui);
      },
      stop: function (e, ui) {
        console.log('结束', ui.css);
      }
    });
  });
	</script>

示例:

/Files/ambar/demos/divZoom/demo.htm

posted @ 2010-11-12 16:29  ambar  阅读(2381)  评论(0编辑  收藏  举报