网站首页 > 技术文章 正文
那些年,我们一起"追"过的Jquery 一文中有说到jquery的基本原理和插件的相关理论,今天我们来简单的实现一下。
废话少说,先上代码:
(function(window,document){ function xQuery(args){ this.elements = []; if(typeof args === 'string'){//选择器 var firstStr = args.charAt(0);//获取字符选择的是第一个字符,# . switch (firstStr) { case '#'://id选择器 this.elements = [document.getElementById(args.substring(1))]; break; case '.'://类选择器 this.elements = [...document.getElementsByClassName(args.substring(1))]; break; default://标签选择器 this.elements = [...document.querySelectorAll(args)]; break; } } else if(typeof args === 'function'){ window.addEventListener('DOMContentLoaded',()=>{ args(); }); } } xQuery.prototype = { constructor: xQuery,//这里指定下constructor,因为这个是可改的,容易发生变化。 each(fn){ this.elements.forEach(fn); return this; }, css(){ if (arguments.length === 1) {//只有一个参数,就是获取css属性 //IE获取元素样式则用 this.elements.currentStyle来做处理,我这边就不处理了。 return window.getComputedStyle(this.elements[0], null)[arguments[0]]; } else if (arguments.length === 2) {//两个参数就是设置css了 var args = arguments; return this.each(function(el,i){ el.style[args[0]] = args[1]; }) } }, width(){ if (arguments.length === 0) { return window.getComputedStyle(this.elements[0], null)['width']; } else if (arguments.length === 1) { var args = arguments;//注意arguments 也有指向的问题哦 return this.each(function (el, i) { el.style['width'] = args[0]; }) } }, click(fn){ return this.each((el,i)=>{ el.addEventListener('click',(e)=>{ fn && fn(e); }); }) }, }; function $(args) { return new xQuery(args); } $.fn = xQuery.prototype; window.$ = $; window.xQuery = xQuery; })(window,document); //扩展插件。 (function($){ $.fn.tap = function(fn,option){ var defaultOption = Object.assign({ responseTime: 120 },option); var startime =0,endtime =0; this.each((el,i)=>{ el.addEventListener('touchstart', function (e) { startime = new Date().getTime(); }); }) this.each((el, i) => { el.addEventListener('touchend', function (e) { endtime = new Date().getTime(); if (endtime - startime < defaultOption.responseTime) { fn && fn(); } }); }) return this; } })(window.$)
简单测试一把:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name='viewport' content='width=750,user-scalable=no' /> <title>xQuery</title> <style> * { margin: 0; padding: 0; } #box{ width: 100px; height: 100px;; } </style> </head> <body> <div id='box'></div> <script src='./xQuery.js'></script> <script> $('#box').css('background','red').css('height','400px').width('400px').tap(function () { alert(22) }, { responseTime: 220 }); $(function () { console.log('loaded'); }) </script> </body> </html>
知识点:
- 面向对象基础,我用的是es5的,完全可以使用ES6的 class 来实现。
- 怎么在类的原型上扩展方法。
- 通过return this 实现链式调用。
- 使用闭包,防止全局污染。然后对外暴露访问的入口。
- 类似jQuery对外提供$方法的,我们在$方法中实例化类。
- arguments的使用,注意会有和this一样的指向问题。
- ES6 ... 语法的使用。可以将nodeList快速转成数组。
- 类的原型里面记得要重新指向一下 constructor为当前的类。
- 插件的扩展完全可以放在闭包里面,形成保护,因为对外的方法是挂载到了类的对象elements上面了,这个已经对外有暴露。
写在最后:
通过现象看本质,以上的实现只是一个最最基础的JQuery了,真正的jquery,比这个复杂得多 。希望我的这个简单的JQ,能让大家对jquery内部原理有一个更深层次的认识。
如果你发现有以上什么不对的,请一定要告诉我,反正我也不会改。VX公众号:itmlgb,你值得拥有。
猜你喜欢
- 2024-09-11 浅析MySQL Join Reorder算法(mysqlinner join)
- 2024-09-11 js 小函数(js函数总结)
- 2024-09-11 Kubernetes 高性能网络组件 Calico 入门教程
- 2024-09-11 jQuery中的clone妙用(jquery.on)
- 2024-09-11 前端单元测试以及自动化构建入门(前端单元测试是什么)
- 2024-09-11 Python全栈 Web(jQuery 一条龙服务)
- 2024-09-11 jQuery遍历说、详解与示例的结合,轻松搞定这个遍历!
- 2024-09-11 「clickhouse专栏」对标mongodb存储类JSON数据文档统计分析
- 2024-09-11 jQuery实现简易购物车功能(jquery购物车结算页面)
- 2024-09-11 jQuery核心的3个面试问题(jquery前端面试)
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)