首页 前端知识 jQuery UI widget源码解析,超通俗解析

jQuery UI widget源码解析,超通俗解析

2024-05-10 22:05:18 前端知识 前端哥 857 246 我要收藏
  1. methodValue = instance[options].apply(instance, args);

  2. if (methodValue !== instance && methodValue !== undefined) {

  3. returnValue = methodValue && methodValue.jquery ? returnValue.pushStack(methodValue.get()) : methodValue;

  4. return false;

  5. }

  6. });

  7. } else {

  8. this.each(function() {

  9. var instance = $.data(this, fullName);

  10. if (instance) {

  11. instance.option(options || {});

  12. //这里每次都调用init方法

  13. if (instance._init) {

  14. instance._init();

  15. }

  16. } else {

  17. //缓存插件实例

  18. $.data(this, fullName, new object(options, this));

  19. }

  20. });

  21. }

  22. return returnValue;

  23. };

  24. };

  25. //这里是真正的widget基类

  26. $.Widget = function( /* options, element */ ) {};

  27. $.Widget._childConstructors = [];

  28. $.Widget.prototype = {

  29. widgetName: “widget”,

  30. //用来决定事件的名称和插件提供的callbacks的关联。

  31. // 比如dialog有一个close的callback,当close的callback被执行的时候,一个dialogclose的事件被触发。

  32. // 事件的名称和事件的prefix+callback的名称。widgetEventPrefix 默认就是控件的名称,但是如果事件需要不同的名称也可以被重写。

  33. // 比如一个用户开始拖拽一个元素,我们不想使用draggablestart作为事件的名称,我们想使用dragstart,所以我们可以重写事件的prefix。

  34. // 如果callback的名称和事件的prefix相同,事件的名称将不会是prefix。

  35. // 它阻止像dragdrag一样的事件名称。

  36. widgetEventPrefix: “”,

  37. defaultElement: “

    ”,

  38. //属性会在创建模块时被覆盖

  39. options: {

  40. disabled: false,

  41. // callbacks

  42. create: null

  43. },

  44. _createWidget: function(options, element) {

  45. element = $(element || this.defaultElement || this)[0];

  46. this.element = $(element);

  47. this.uuid = widget_uuid++;

  48. this.eventNamespace = “.” + this.widgetName + this.uuid;

  49. this.options = $.widget.extend({}, this.options, this._getCreateOptions(), options);

  50. this.bindings = $();

  51. this.hoverable = $();

  52. this.focusable = $();

  53. if (element !== this) {

  54. //            debugger

  55. $.data(element, this.widgetFullName, this);

  56. this._on(true, this.element, {

  57. remove: function(event) {

  58. if (event.target === element) {

  59. this.destroy();

  60. }

  61. }

  62. });

  63. this.document = $(element.style ?

  64. // element within the document

  65. element.ownerDocument :

  66. // element is window or document

  67. element.document || element);

  68. this.window = $(this.document[0].defaultView || this.document[0].parentWindow);

  69. }

  70. this._create();

  71. //创建插件时,有个create的回调

  72. this._trigger(“create”, null, this._getCreateEventData());

  73. this._init();

  74. },

  75. _getCreateOptions: $.noop,

  76. _getCreateEventData: $.noop,

  77. _create: $.noop,

  78. _init: $.noop,

  79. //销毁模块:去除绑定事件、去除数据、去除样式、属性

  80. destroy: function() {

  81. this._destroy();

  82. // we can probably remove the unbind calls in 2.0

  83. // all event bindings should go through this._on()

  84. this.element.unbind(this.eventNamespace).removeData(this.widgetFullName)

  85. // support: jquery <1.6.3

  86. // http://bugs.jquery.com/ticket/9413

  87. .removeData($.camelCase(this.widgetFullName));

  88. this.widget().unbind(this.eventNamespace).removeAttr(“aria-disabled”).removeClass(

  89. this.widgetFullName + "-disabled " + “ui-state-disabled”);

  90. // clean up events and states

  91. this.bindings.unbind(this.eventNamespace);

  92. this.hoverable.removeClass(“ui-state-hover”);

  93. this.focusable.removeClass(“ui-state-focus”);

  94. },

  95. _destroy: $.noop,

  96. widget: function() {

  97. return this.element;

  98. },

  99. //设置选项函数

  100. option: function(key, value) {

  101. var options = key,

  102. parts, curOption, i;

  103. if (arguments.length === 0) {

  104. // don’t return a reference to the internal hash

  105. //返回一个新的对象,不是内部数据的引用

  106. return $.widget.extend({}, this.options);

  107. }

  108. if (typeof key === “string”) {

  109. // handle nested keys, e.g., “foo.bar” => { foo: { bar: ___ } }

  110. options = {};

  111. parts = key.split(“.”);

  112. key = parts.shift();

  113. if (parts.length) {

  114. curOption = options[key] = $.widget.extend({}, this.options[key]);

  115. for (i = 0; i < parts.length - 1; i++) {

  116. curOption[parts[i]] = curOption[parts[i]] || {};

  117. curOption = curOption[parts[i]];

  118. }

  119. key = parts.pop();

  120. if (arguments.length === 1) {

  121. return curOption[key] === undefined ? null : curOption[key];

  122. }

  123. curOption[key] = value;

  124. } else {

  125. if (arguments.length === 1) {

  126. return this.options[key] === undefined ? null : this.options[key];

  127. }

  128. options[key] = value;

  129. }

  130. }

  131. this._setOptions(options);

  132. return this;

  133. },

  134. _setOptions: function(options) {

  135. var key;

  136. for (key in options) {

  137. this._setOption(key, options[key]);

  138. }

  139. return this;

  140. },

  141. _setOption: function(key, value) {

  142. this.options[key] = value;

  143. if (key === “disabled”) {

  144. this.widget().toggleClass(this.widgetFullName + “-disabled”, !! value);

  145. // If the widget is becoming disabled, then nothing is interactive

  146. if (value) {

  147. this.hoverable.removeClass(“ui-state-hover”);

  148. this.focusable.removeClass(“ui-state-focus”);

  149. }

  150. }

  151. return this;

  152. },

  153. enable: function() {

  154. return this._setOptions({

  155. disabled: false

  156. });

  157. },

  158. disable: function() {

  159. return this._setOptions({

  160. disabled: true

  161. });

  162. },

  163. _on: function(suppressDisabledCheck, element, handlers) {

  164. var delegateElement, instance = this;

  165. // no suppressDisabledCheck flag, shuffle arguments

  166. if (typeof suppressDisabledCheck !== “boolean”) {

  167. handlers = element;

  168. element = suppressDisabledCheck;

  169. suppressDisabledCheck = false;

  170. }

  171. // no element argument, shuffle and use this.element

  172. if (!handlers) {

  173. handlers = element;

  174. element = this.element;

  175. delegateElement = this.widget();

  176. } else {

  177. // accept selectors, DOM elements

  178. element = delegateElement = $(element);

  179. this.bindings = this.bindings.add(element);

  180. }

  181. $.each(handlers, function(event, handler) {

  182. function handlerProxy() {

  183. // allow widgets to customize the disabled handling

  184. // - disabled as an array instead of boolean

  185. // - disabled class as method for disabling individual parts

  186. if (!suppressDisabledCheck && (instance.options.disabled === true || $(this).hasClass(“ui-state-disabled”))) {

  187. return;

  188. }

  189. return (typeof handler === “string” ? instance[handler] : handler).apply(instance, arguments);

  190. }

  191. // copy the guid so direct unbinding works

  192. if (typeof handler !== “string”) {

  193. handlerProxy.guid = handler.guid = handler.guid || handlerProxy.guid || $.guid++;

  194. }

  195. var match = event.match(/^([\w:-]*)\s*(.*)$/),

  196. eventName = match[1] + instance.eventNamespace,

  197. selector = match[2];

  198. if (selector) {

  199. delegateElement.delegate(selector, eventName, handlerProxy);

  200. } else {

  201. element.bind(eventName, handlerProxy);

  202. }

  203. });

  204. },

  205. _off: function(element, eventName) {

  206. eventName = (eventName || “”).split(" ").join(this.eventNamespace + " ") + this.eventNamespace;

  207. element.unbind(eventName).undelegate(eventName);

  208. },

  209. _delay: function(handler, delay) {

  210. function handlerProxy() {

  211. return (typeof handler === “string” ? instance[handler] : handler).apply(instance, arguments);

  212. }

  213. var instance = this;

  214. return setTimeout(handlerProxy, delay || 0);

  215. },

  216. _hoverable: function(element) {

  217. this.hoverable = this.hoverable.add(element);

  218. this._on(element, {

  219. mouseenter: function(event) {

  220. $(event.currentTarget).addClass(“ui-state-hover”);

  221. },

  222. mouseleave: function(event) {

  223. $(event.currentTarget).removeClass(“ui-state-hover”);

  224. }

  225. });

  226. },

  227. _focusable: function(element) {

  228. this.focusable = this.focusable.add(element);

  229. this._on(element, {

  230. focusin: function(event) {

  231. $(event.currentTarget).addClass(“ui-state-focus”);

  232. },

  233. focusout: function(event) {

  234. $(event.currentTarget).removeClass(“ui-state-focus”);

  235. }

  236. });

  237. },

  238. _trigger: function(type, event, data) {

  239. var prop, orig, callback = this.options[type];

  240. data = data || {};

  241. event = $.Event(event);

  242. event.type = (type === this.widgetEventPrefix ? type : this.widgetEventPrefix + type).toLowerCase();

  243. // the original event may come from any element

  244. // so we need to reset the target on the new event

  245. event.target = this.element[0];

  246. // copy original event properties over to the new event

  247. orig = event.originalEvent;

  248. if (orig) {

  249. for (prop in orig) {

  250. if (!(prop in event)) {

  251. event[prop] = orig[prop];

  252. }

  253. }

  254. }

  255. this.element.trigger(event, data);

  256. return !($.isFunction(callback) && callback.apply(this.element[0], [event].concat(data)) === false || event.isDefaultPrevented());

  257. }

  258. };

  259. $.each({

  260. show: “fadeIn”,

  261. hide: “fadeOut”

  262. }, function(method, defaultEffect) {

  263. $.Widget.prototype[“_” + method] = function(element, options, callback) {

  264. if (typeof options === “string”) {

  265. options = {

  266. effect: options

  267. };

  268. }

  269. var hasOptions, effectName = !options ? method : options === true || typeof options === “number” ? defaultEffect : options.effect || defaultEffect;

  270. options = options || {};

  271. if (typeof options === “number”) {

  272. options = {

  273. duration: options

  274. };

  275. }

  276. hasOptions = !$.isEmptyObject(options);

  277. options.complete = callback;

  278. if (options.delay) {

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
img

总结

=============================================================

从转行到现在,差不多两年的时间,虽不能和大佬相比,但也是学了很多东西。我个人在学习的过程中,习惯简单做做笔记,方便自己复习的时候能够快速理解,现在将自己的笔记分享出来,和大家共同学习。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

个人将这段时间所学的知识,分为三个阶段:

第一阶段:HTML&CSS&JavaScript基础

第二阶段:移动端开发技术

第三阶段:前端常用框架

  • 推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;如果因为我的笔记太过简陋不理解,可以关注我以后我还会继续分享。

  • 大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。

学习的过程中,习惯简单做做笔记,方便自己复习的时候能够快速理解,现在将自己的笔记分享出来,和大家共同学习。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

个人将这段时间所学的知识,分为三个阶段:

第一阶段:HTML&CSS&JavaScript基础

第二阶段:移动端开发技术

第三阶段:前端常用框架

  • 推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;如果因为我的笔记太过简陋不理解,可以关注我以后我还会继续分享。

  • 大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/8015.html
标签
element-ui
评论
发布的文章

HTML5(H5)中的Web Workers

2024-05-19 09:05:52

HTML5

2024-02-27 11:02:15

HTML5 <option> 标签

2024-05-19 09:05:51

@JsonProperty 注解详解

2024-05-19 09:05:27

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!