网站首页 > 技术文章 正文
那些年,我们一起"追"过的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前端面试)
 
- 最近发表
 - 
- 聊一下 gRPC 的 C++ 异步编程_grpc 异步流模式
 - [原创首发]安全日志管理中心实战(3)——开源NIDS之suricata部署
 - 超详细手把手搭建在ubuntu系统的FFmpeg环境
 - Nginx运维之路(Docker多段构建新版本并增加第三方模
 - 92.1K小星星,一款开源免费的远程桌面,让你告别付费远程控制!
 - Go 人脸识别教程_piwigo人脸识别
 - 安卓手机安装Termux——搭建移动服务器
 - ubuntu 安装开发环境(c/c++ 15)_ubuntu安装c++编译器
 - Rust开发环境搭建指南:从安装到镜像配置的零坑实践
 - Windows系统安装VirtualBox构造本地Linux开发环境
 
 
- 标签列表
 - 
- cmd/c (90)
 - c++中::是什么意思 (84)
 - 标签用于 (71)
 - 主键只能有一个吗 (77)
 - c#console.writeline不显示 (95)
 - pythoncase语句 (88)
 - es6includes (74)
 - sqlset (76)
 - apt-getinstall-y (100)
 - node_modules怎么生成 (87)
 - chromepost (71)
 - flexdirection (73)
 - c++int转char (80)
 - mysqlany_value (79)
 - static函数和普通函数 (84)
 - el-date-picker开始日期早于结束日期 (76)
 - js判断是否是json字符串 (75)
 - c语言min函数头文件 (77)
 - asynccallback (87)
 - localstorage.removeitem (77)
 - vector线程安全吗 (73)
 - java (73)
 - js数组插入 (83)
 - mac安装java (72)
 - 无效的列索引 (74)
 
 
