自己封装的简易版jQuery

素颜马尾好姑娘i 2021-09-20 05:42 437阅读 0赞

学过jQuery快一年了,学jQuery时曾尝试封装过一个简易的jQuery,也是为了考察自己对原生js的掌握程度。实现了jQuery的部分功能。如选择元素、add、trigger、queue、dequeue、delay、animate、callback、deffer…等方法
Github地址:https://github.com/mytheart/my-projects/tree/master/projects/myjQuery

  1. (function () {
  2. function jQuery (selector) {
  3. return new jQuery.prototype.init(selector);
  4. }
  5. jQuery.prototype.init = function (selector) {
  6. // this = {};
  7. // 选出 dom 并且包装成jQuery对象 返回
  8. // id class
  9. this.length = 0;
  10. // null undefined dom
  11. if (selector == null) {
  12. return this;
  13. }
  14. if (typeof selector == 'string' && selector.indexOf('.') != -1) {
  15. var dom = document.getElementsByClassName( selector.slice(1) );
  16. }else if (typeof selector == 'string' && selector.indexOf('#') != -1) {
  17. var dom = document.getElementById( selector.slice(1) );
  18. }
  19. if (selector instanceof Element || dom.length == undefined) {
  20. this[0] = dom || selector;
  21. this.length++;
  22. }else {
  23. // 基础铺垫
  24. for (var i = 0; i < dom.length; i++) {
  25. this[i] = dom[i];
  26. this.length++
  27. }
  28. }
  29. // return this;
  30. }
  31. jQuery.prototype.css = function (config) {
  32. // 循环操作每一个dom
  33. // 循环操作
  34. for (var i = 0; i < this.length; i++) {
  35. for (var attr in config) {
  36. this[i].style[attr] = config[attr];
  37. }
  38. }
  39. // 链式操作
  40. return this;
  41. }
  42. jQuery.prototype.pushStack = function (dom) {
  43. // dom newObj
  44. if (dom.constructor != jQuery) {
  45. dom = jQuery(dom);
  46. }
  47. dom.prevObject = this;
  48. return dom;
  49. }
  50. jQuery.prototype.get = function (num) {
  51. return num != null ? (num >= 0 ? this[num] : this[num + this.length]) : [].slice.call(this, 0);
  52. }
  53. jQuery.prototype.eq = function (num) {
  54. var dom = num != null ? (num >= 0 ? this[num] : this[num + this.length]) : null;
  55. return this.pushStack(dom);
  56. }
  57. jQuery.prototype.add = function (selector) {
  58. var curObj = jQuery(selector);
  59. var baseObj = this;
  60. var newObj = jQuery();
  61. for (var i = 0; i < curObj.length; i++) {
  62. newObj[newObj.length++] = curObj[i];
  63. }
  64. for (var i = 0; i < baseObj.length; i++) {
  65. newObj[newObj.length++] = baseObj[i];
  66. }
  67. console.log(newObj);
  68. this.pushStack(newObj);
  69. return newObj;
  70. }
  71. jQuery.prototype.end = function () {
  72. return this.prevObject;
  73. }
  74. jQuery.prototype.myOn = function (type, handle) {
  75. for (var i = 0; i < this.length; i++) {
  76. if (!this[i].cacheEvent) {
  77. this[i].cacheEvent = {};
  78. }
  79. if ( !this[i].cacheEvent[type] ) {
  80. this[i].cacheEvent[type] = [handle];
  81. }else {
  82. this[i].cacheEvent[type].push(handle);
  83. }
  84. }
  85. }
  86. jQuery.prototype.myTrigger = function (type) {
  87. var params = arguments.length > 1 ? [].slice.call(arguments, 1) : [];
  88. var self = this;
  89. for (var i = 0; i < this.length; i++) {
  90. if ( this[i].cacheEvent[type] ) {
  91. this[i].cacheEvent[type].forEach(function (ele, index) {
  92. ele.apply(self, params)
  93. });
  94. }
  95. }
  96. }
  97. jQuery.prototype.myQueue = function () {
  98. var queueObj = this;
  99. var queueName = arguments[0] || 'fx';
  100. var addFunc = arguments[1] || null;
  101. var len = arguments.length;
  102. // 获取队列
  103. if (len == 1) {
  104. return queueObj[0][queueName];
  105. }
  106. // queue dom {chain: } 添加队列 或 往已有队列中添加内容
  107. queueObj[0][queueName] == undefined ? queueObj[0][queueName] = [addFunc] : queueObj[0][queueName].push(addFunc);
  108. return this;
  109. }
  110. jQuery.prototype.myDequeue = function (type) {
  111. var self = this;
  112. var queueName = arguments[0] || 'fx';
  113. var queueArr = this.myQueue(queueName);
  114. var currFunc = queueArr.shift();
  115. if (currFunc == undefined) {
  116. return;
  117. }
  118. var next = function () {
  119. self.myDequeue(queueName);
  120. }
  121. currFunc(next);
  122. return this;
  123. }
  124. jQuery.prototype.myDelay = function (duration) {
  125. var queueArr = this[0]['fx'];
  126. queueArr.push(function (next) {
  127. setTimeout(function () {
  128. next();
  129. }, duration);
  130. });
  131. return this;
  132. }
  133. jQuery.prototype.myAnimate = function (json, callback) {
  134. var len = this.length;
  135. var self = this;
  136. // 最后添加到队列里的内容函数
  137. var baseFunc = function (next) {
  138. var times = 0;
  139. for (var i = 0; i < len; i++) {
  140. startMove(self[i], json, function () {
  141. times++;
  142. if (times == len) {
  143. callback && callback();
  144. next();
  145. }
  146. });
  147. }
  148. }
  149. this.myQueue('fx', baseFunc);
  150. if ( this.myQueue('fx').length == 1 ) {
  151. this.myDequeue('fx');
  152. }
  153. function getStyle (obj, attr) {
  154. if (obj.currentStyle) {
  155. return obj.currentStyle[attr];
  156. }else {
  157. return window.getComputedStyle(obj,false)[attr];
  158. }
  159. }
  160. function startMove (obj, json, callblack) {
  161. clearInterval(obj.timer);
  162. var iSpeed;
  163. var iCur;
  164. var name;
  165. obj.timer = setInterval(function () {
  166. var bStop = true;
  167. for (var attr in json) {
  168. if (attr === 'opacity') {
  169. name = attr;
  170. iCur = parseFloat(getStyle(obj, attr)) * 100;
  171. }else {
  172. iCur = parseInt(getStyle(obj, attr));
  173. }
  174. iSpeed = (json[attr] - iCur) / 7;
  175. if (iSpeed > 0) {
  176. iSpeed = Math.ceil(iSpeed);
  177. }else {
  178. iSpeed = Math.floor(iSpeed);
  179. }
  180. if (attr === 'opacity') {
  181. obj.style.opacity = (iCur + iSpeed) / 100;
  182. }else {
  183. obj.style[attr] = iCur + iSpeed + 'px';
  184. }
  185. if (json[attr] - iCur !== 0) {
  186. bStop = false;
  187. }
  188. }
  189. if (bStop) {
  190. clearInterval(obj.timer);
  191. callblack();
  192. }
  193. }, 30);
  194. }
  195. return this;
  196. }
  197. jQuery.myCallbacks = function () {
  198. // 'once' 'memory' 'once memory' null
  199. // 存储参数
  200. var options = arguments[0] || '';
  201. // 通过add 来加入的方法
  202. var list = [];
  203. // 记录当前要执行的函数的索引
  204. var fireIndex = 0;
  205. // 记录是否有被fire过
  206. var fired = false;
  207. // 实际参数列表
  208. var args = [];
  209. var fire = function () {
  210. for (; fireIndex < list.length; fireIndex++) {
  211. list[fireIndex].apply(window, args);
  212. }
  213. if (options.indexOf('once') != -1) {
  214. list = [];
  215. fireIndex = 0;
  216. }
  217. }
  218. return {
  219. add: function (func) {
  220. list.push(func);
  221. if (options.indexOf('memory') != -1 && fired) {
  222. fire();
  223. }
  224. return this;
  225. },
  226. fire: function () {
  227. fireIndex = 0;
  228. args = arguments;
  229. fired = true;
  230. fire();
  231. }
  232. }
  233. }
  234. jQuery.myDeferred = function () {
  235. // callback
  236. // 3个callback
  237. // done resolve fail reject progress notify
  238. var arr = [
  239. [
  240. jQuery.myCallbacks('once memory'), 'done', 'resolve'
  241. ],[
  242. jQuery.myCallbacks('once memory'), 'fail', 'reject'
  243. ],[
  244. jQuery.myCallbacks('memory'), 'progress', 'notify'
  245. ]
  246. ];
  247. var pendding = true;
  248. var deferred = {};
  249. for (var i = 0; i < arr.length; i++) {
  250. // arr[0][1]
  251. // 注册
  252. // deferred['done'] = function () {}
  253. // deferred['fail'] = function () {}
  254. // deferred['progress'] = function () {}
  255. deferred[ arr[i][1] ] = (function (index) {
  256. return function (func) {
  257. arr[index][0].add(func)
  258. }
  259. })(i);
  260. // 触发
  261. // deferred['resolve'] = function () {}
  262. // deferred['reject'] = function () {}
  263. // deferred['notify'] = function () {}
  264. deferred[ arr[i][2] ] = (function (index) {
  265. return function () {
  266. var args = arguments;
  267. if (pendding) {
  268. arr[index][0].fire.apply(window, args);
  269. arr[index][2] == 'resolve' || arr[index][2] == 'reject' ? pendding = false : '';
  270. }
  271. }
  272. })(i);
  273. }
  274. return deferred;
  275. }
  276. jQuery.prototype.init.prototype = jQuery.prototype;
  277. window.$ = window.jQuery = jQuery;
  278. })();

只写了jQuery部分功能,有不足之处欢迎之处,也欢迎大家自己继续完善。现在有好多人说jQuery已经过时了,学完js之后直接奔三大框架。但我认为,jQuery仍有它自己的魅力,并且现在还有好多公司还用jQuery。我自己封装简易版jQuery的初衷也仅仅是为了加深自己对原声js的理解。不管框架怎么变,只要前端还在,原生JavaScript就永远不会过时。

发表评论

表情:
评论列表 (有 0 条评论,437人围观)

还没有评论,来说两句吧...

相关阅读

    相关 概念

      封装:         概念:            将类的某些信息隐藏在类内部,不允许外部程序直接访问,            而是通过该类提供的方法来实现对隐藏

    相关 自己JDBC类

    > 对JDBC进行一些简单的封装,可以方便在项目中调用,同时也减少了重复代码量,降低代码的冗余度,提高代码的可读性和美观。 package JdbcUtil