当前位置: 首页 > 工具软件 > jquery widget > 使用案例 >

jQuery Widget 开发 Tutorial

欧阳楚
2023-12-01

标题: jQuery Widget 开发 Tutorial
- Roamman 2010-02-02 07:56 阅读:35
- 评论:0 | 添加评论 | 返回

原文:http://bililite.com/blog/understanding-jquery-ui-widgets-a-tutorial/

由于翻译后不能使用HTML和SCRIPT所以演示部分就不能看到了,请参照原文。

写这篇文章的目的是为了让我理解并开发出我自己的Widgets,同时我也希望这篇文章能对其他人也有帮助。Widget让我说就是一种用户界面元 素,类似于按钮或者像复杂的DatePicker(日期选择控件)。但这一概念对于jQuery,更确切的说是一个类。这个类的成员与一些HTML元素相 关,比如Draggable和Sortable。当然不是所有Widget都使用$.widget,例如datePicker就没有使用。

 

插件:修改元素

让我们用一个带CSS类的P元素作为目标举个例子。

  1. 1
  1. <p class="target">This is a paragraph</p>

我们把它变绿:

  1. 1
  1. $(".target").css({"background":'green'});

然后我们需要将这一功能更通用化:

  1. 1
  1. $.fn.green = function() {return this.css({background: 'green'})}

上面的代码是我们可以在任意的选中元素上产生效果,但他没有让我们保持和某个元素的关联。例如如果我们需要制作一个恢复背景的功能,哪么我们必须确定他的初始颜色。如果要设计一个Darker(),我们就必须知道元素现在是什么颜色。

保持插件状态

我们可以创建一个与某元素管理单的对象:

  1.  
  1. element.myobject = new Myobject({'target': element})
  2.  
  3. $.fn.green2 = function() {
  4. return this.each(function(){
  5. if (!this.green) this.green = new Green(this); // associate our state-keeping object with the element
  6. this.green.setLevel(15);
  7. });
  8. };
  9. $.fn.off = function() {
  10. return this.each(function(){
  11. if (this.green) this.green.setLevel(16);
  12. delete this.green; // recover the memory
  13. });
  14. };
  15. $.fn.darker = function() {
  16. return this.each(function(){
  17. if (this.green) this.green.setLevel(this.green.getLevel()-1);
  18. });
  19. };
  20. $.fn.lighter = function() {
  21. return this.each(function(){
  22. if (this.green) this.green.setLevel(this.green.getLevel()+1);
  23. });
  24. };
  25.  
  26. function Green(target){
  27. greenlevels = ['#000','#010','#020','#030','#040','#050','#060','#070','#080','#090','#0a0','#0b0','#0c0','#0d0','#0e0','#0f0','#fff'];
  28. this.target = target; // associate the element with the object
  29. this.level = 0;
  30. this.getLevel = function() { return this.level; }
  31. this.setLevel = function(x) {
  32. this.level = Math.floor(Math.min(greenlevels.length-1, Math.max(0,x)));
  33. this.target.css({background: greenlevels[this.level]});
  34. }
  35. };

但是上面这种方式使得$.fn命名空间中出现了很多函数。我们也可以在该命名空间内再创建一个命名空间,但一般的设计思路使用一个字符串来调用相应的函数,即我们可以使用类似element.green2("darker")来调用darker()方法:

  1.  
  1. $.fn.green2 = function(which){
  2. return this.each(function(){
  3. if (which === undefined){ // initial call
  4. if (!this.green) this.green = new Green($(this)); // associate our state-keeping object with the element
  5. this.green.setLevel(15);
  6. }else if (which == 'off'){
  7. if (this.green) this.green.setLevel(16);
  8. delete this.green
  9. }else if (which == 'darker'){
  10. if (this.green) this.green.setLevel(this.green.getLevel()-1);
  11. }else if (which == 'lighter'){
  12. if (this.green) this.green.setLevel(this.green.getLevel()+1);
  13. }
  14. });
  15. };
  16.  
  17. function Green(target){
  18. greenlevels = ['#000','#010','#020','#030','#040','#050','#060','#070','#080','#090','#0a0','#0b0','#0c0','#0d0','#0e0','#0f0', '#fff'];
  19. this.target = target; // associate the element with the object
  20. this.level = 0;
  21. this.getLevel = function() { return this.level; }
  22. this.setLevel = function(x) {
  23. this.level = Math.floor(Math.min(greenlevels.length-1, Math.max(0,x)));
  24. this.target.css({background: greenlevels[this.level]});
  25. }
  26. };

插件与对象关联所带来的问题 上面的方式能够方便的写出程序,但是也带来了循环引用和可能的内存漏洞。浏览器对于Javascript和Dom元素是使用不同的垃圾回收方式,上面的引用方式可能就会带来问题,使得回收不能正常进行。 我们同时也要注意,在我们开发插件是也要注意内存的回收。 jQuery用$.fn.data解决了这一问题:

  1. 1
  1. $(element).data('myobject', new Myobject({'target': element}))

但是,这样做的同时又带来了其他的问题,我们需要做很多“额外”的工作,这些工作与程序逻辑毫无关系,重复而无用。所以重复实现这一功能,需要抽象出来减 少工作。 解决问题:$.widget 这就是$.widget出现的原因。它使得插件中的Javascript类的单个实例与每个元素相关联,这样我们在与对象进行交互操作元素的时候就不会带 来内存绣楼的问题。 同上面一样,你还是需要创建类的构造函数。与之不同的是,我们需要一个包含了相关方法的“原型”。同时也有一些变化,如:_init()函数在构造是调 用,destroy()方法在析构是调用。这两个函数都是预先定义的,不过你可以覆盖。element和上面我们的target是与类相关的jQuery 对象。 Widget中所有已“_”开头的方法都属预定义似有形函数,外部不能调用。

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  1. var Green3 = {
  2. _init: function() { this.setLevel(15); },
  3. greenlevels: ['#000','#010','#020','#030','#040','#050','#060','#070','#080','#090','#0a0','#0b0','#0c0','#0d0','#0e0','#0f0', '#fff'],
  4. level: 0,
  5. getLevel: function() { return this.level; },
  6. setLevel: function(x) {
  7. this.level = Math.floor(Math.min(this.greenlevels.length-1, Math.max(0,x)));
  8. this.element.css({background: this.greenlevels[this.level]});
  9. },
  10. darker: function() { this.setLevel(this.getLevel()-1); },
  11. lighter: function() { this.setLevel(this.getLevel()+1); },
  12. off: function() {
  13. this.element.css({background: 'none'});
  14. this.destroy(); // use the predefined function
  15. }
  16. };

上述代码即就是整个程序逻辑,使用下面代码生成插件:

  1. 1
  1. $.widget("ui.green3", Green3); // create the widget

就翻译到这了。差不多也算是我的理解吧,可能翻译的不好欢迎指正。

 类似资料: