欢迎访问 生活随笔!

凯发k8官方网

当前位置: 凯发k8官方网 > 前端技术 > html >内容正文

html

jquery function-凯发k8官方网

发布时间:2024/10/8 html 25 豆豆
凯发k8官方网 收集整理的这篇文章主要介绍了 jquery function_前端基础进阶(十三)详细图解jquery扩展jquery插件 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

ui 鉴赏

早几年学习前端,大家都非常热衷于研究jquery源码。

我至今还记得当初从jquery源码中学到一星半点应用技巧的时候常会有一种发自内心的惊叹,“原来javascript居然可以这样用!”

但是随着前端的迅猛发展,另外几种前端框架的崛起,jquery慢慢变得不再是必须。所有人对jquery的热情都降低了许多。

jquery在前端史上有它非常超然的历史地位,许多从中学到的技巧在实践开发中仍然非常好用。简单的了解它有助于我们更加深入的理解javascript。如果你能够从中看明白jquery是如何一步步被取代的,那么,我想你的收益远不止学会使用了一个库那么简单。

因此,我的态度是,项目中你可以不用,但是我仍然建议你学。

这篇文章的主要目的,是从面向对象的角度,跟大家分享jquery对象是如何封装的。算是对大家进一步学习jquery源码的一个抛砖引玉。

使用jquery对象时,我们这样写:

// 声明一个jquery对象$('.target')// 获取元素的css属性$('.target').css('width')// 获取元素的位置信息$('.target').offset()

在使用之初可能会有许多疑问,比如$是怎么回事?为什么不用new就可以直接声明一个对象?等等。了解之后,才知道原来这正是jquery对象创建的巧妙之处。

先直接用代码展示出来,再用图跟大家解释是怎么回事。

;(function (root) { // 构造函数 var jquery = function (selector) { // 在jquery中直接返回new过的实例,这里的init是jquery的真正构造函数 return new jquery.fn.init(selector) } jquery.fn = jquery.prototype = { constructor: jquery, version: '1.0.0', init: function (selector) { // 在jquery中这里有一个复杂的判断,但是这里我做了简化 var elem, selector; elem = document.queryselector(selector); this[0] = elem; // 在jquery中返回一个由所有原型属性方法组成的数组,我们这里简化,直接返回this即可 // return jquery.makearray(selector, this); return this; }, // 在原型上添加一堆方法 toarray: function () { }, get: function () { }, each: function () { }, ready: function () { }, first: function () { }, slice: function () { } // ... ... } jquery.fn.init.prototype = jquery.fn; // 实现jquery的两种扩展方式 jquery.extend = jquery.fn.extend = function (options) { // 在jquery源码中会根据参数不同进行很多判断,我们这里就直接走一种方式,所以就不用判断了 var target = this; var copy; for (name in options) { copy = options[name]; target[name] = copy; } return target; } // jquery中利用上面实现的扩展机制,添加了许多方法,其中 // 直接添加在构造函数上,被称为工具方法 jquery.extend({ isfunction: function () { }, type: function () { }, parsehtml: function () { }, parsejson: function () { }, ajax: function () { } // ... }) // 添加到原型上 jquery.fn.extend({ queue: function () { }, promise: function () { }, attr: function () { }, prop: function () { }, addclass: function () { }, removeclass: function () { }, val: function () { }, css: function () { } // ... }) // $符号的由来,实际上它就是jquery,一个简化的写法,在这里我们还可以替换成其他可用字符 root.jquery = root.$ = jquery;})(window);

在上面的代码中,我封装了一个简化版的jquery对象。

它向大家简单展示了jquery的整体骨架。

在代码中可以看到,jquery自身对于原型的处理使用了一些巧妙的方式,比如jquery.fn = jquery.prototype,jquery.fn.init.prototype = jquery.fn;等,这几句正是jquery对象的关键所在。看图分析。

jquery对象核心图

对象封装分析

在上面的实现中,首先在jquery构造函数里声明了一个fn属性,并将其指向了原型jquery.prototype。然后在原型中添加了init方法。

jquery.fn = jquery.prototype = { init: {}}

之后又将init的原型,指向了jquery.prototype。

jquery.fn.init.prototype = jquery.fn;

而在构造函数jquery中,返回了init的实例对象。

var jquery = function (selector) { // 在jquery中直接返回new过的实例,这里的init是jquery的真正构造函数 return new jquery.fn.init(selector)}

最后对外暴露入口时,将字符$与jquery对等起来。

root.jquery = root.$ = jquery;

因此当我们直接使用$('#test')创建一个对象时,实际上是创建了一个init的实例,这里的真正构造函数是原型中的init方法。

注意:许多对jquery内部实现不太了解的盆友,常常会毫无节制使用$(),比如对于同一个元素的不同操作:

var width = parseint($('#test').css('width'));if(width > 20) { $('#test').css('backgroundcolor', 'red');}

通过我们上面的一系列分析,我们知道每当我们执行$()时,就会重新生成一个init的实例对象,因此当我们这样没有节制的使用jquery是非常不正确的,虽然看上去方便了一些,但是对于内存的消耗非常大。正确的做法是既然是同一个对象,那么就用一个变量保存起来后续使用即可。

var $test = $('#test');var width = parseint($test.css('width'));if(width > 20) { $test.css('backgroundcolor', 'red');}

扩展方法分析

在上面的代码实现中,我还简单实现了两个扩展方法。

jquery.extend = jquery.fn.extend = function (options) { // 在jquery源码中会根据参数不同进行很多判断,我们这里就直接走一种方式,所以就不用判断了 var target = this; var copy; for (name in options) { copy = options[name]; target[name] = copy; } return target;}

要理解它的实现,首先要明确知道this的指向。如果你搞不清楚,可以回头去看看我们之前关于this指向的讲解。

传入的参数options为一个key: value模式的对象,我通过for in遍历options,将key作为jquery的新属性,value作为该新属性所对应的新方法,分别添加到jquery方法和jquery.fn中。

也就是说,当我们通过jquery.extend扩展jquery时,方法被添加到了jquery构造函数中,而当我们通过jquery.fn.extend扩展jquery时,方法被添加到了jquery原型中。

上面的例子中,我也简单展示了在jquery内部,许多方法的实现都是通过这两个扩展方法来完成的。

当我们通过上面的知识了解了jquery的大体框架之后,我们对于jquery的学习就可以具体到诸如css/val/attr等方法是如何实现这样的程度,那么源码学习起来就会轻松很多,节省更多的时间。也给一些对于源码敬而远之的朋友提供一个学习的可能。

有一个朋友留言给我,说她被静态方法,工具方法和实例方法这几个概念困扰了很久,到底他们有什么区别?

其实在上一篇文章中,关于封装一个对象,我跟大家分享了一个非常非常干,但是却只有少数几个读者大佬get到的知识,那就是在封装对象时,属性和方法可以具体放置的三个位置,并且对于这三个位置的不同做了一个详细的解读。

image.png

在实现jquery扩展方法时,一部分方法需要扩展到构造函数中,一部分方法需要扩展到原型中,当我们通读jquery源码时,还发现有一些方法放在了模块作用域中,至于为什么会有这样的区别,建议大家回过头去读读前一篇文章。

这里用一个例子简单区分一下。

// 模块内部const a = 20;function person(name, age) { this.name = name; this.age = age; // 构造函数方法,每声明一个实例,都会重新创建一次,属于实例独有 this.getname = function() { return this.name; }}// 原型方法,仅在原型创建时声明一次,属于所有实例共享person.prototype.getage = function() { return this.age;}// 工具方法,直接挂载在构造函数名上,仅声明一次,无法直接访问实例内部属性与方法person.each = function() {}

如上例中,each就是一个工具方法,或者说静态方法。

工具方法的特性也和工具一词非常贴近,他们与实例的自身属性毫无关联,仅仅只是实现一些通用的功能,我们可以通过$.each与$('div').each这2个方法来体会工具方法与实例方法的不同之处。

在实际开发中,我们运用得非常多的一个工具库就是lodash.js,大家如果时间充裕一定要去学习一下他的使用。

$.ajax()$.isfunction()$.each()... ...

放在原型中的方法,在使用时必须创建了一个新的实例对象才能访问,因此这样的方法叫做实例方法。也正是因为这一点,他的使用成本会比工具方法高一些。但是相比构造函数方法,原型方法更节省内存。

$('#test').css()$('#test').attr()$('div').each()

这样,那位同学的疑问就被搞定啦。我们在学习的时候,一定不要过分去纠结一些概念,而要明白这些概念背后的具体场景是怎么回事儿,那么学习这件事情就不会在一些奇奇怪怪的地方卡住了。

所以通过$.extend扩展的方法,其实就是对工具方法的扩展,而通过$.fn.extend扩展的方法,就是对于实例方法的扩展。

jquery插件的实现

我在初级阶段时,觉得要自己编写一个jquery插件是超级高大上的事情,可望不可即。但是通过对于上面的理解,我就知道扩展jquery插件其实是一件我们自己也可以完成的事情。

在前面我跟大家分享了jquery如何实现,以及他们的方法如何扩展,并且前一篇文章分享了拖拽对象的具体实现。所以建议大家暂时不要阅读下去,自己动手尝试将拖拽扩展成为jquery的一个实例方法,这就是一个jquery插件了。

具体也没有什么可多说的了,大家看了代码就可以明白一切。

// drag对象简化代码,完整源码可在上一篇文章中查看;(function () { // 构造 function drag(selector) { } // 原型 drag.prototype = { constructor: drag, init: function () { // 初始时需要做些什么事情 this.setdrag(); }, // 稍作改造,仅用于获取当前元素的属性,类似于getname getstyle: function (property) { }, // 用来获取当前元素的位置信息,注意与之前的不同之处 getposition: function () { }, // 用来设置当前元素的位置 setpostion: function (pos) { }, // 该方法用来绑定事件 setdrag: function () { } } // 一种对外暴露的方式 window.drag = drag;})();// 通过扩展方法将拖拽扩展为jquery的一个实例方法(function ($) { $.fn.extend({ becomedrag: function () { new drag(this[0]); return this; // 注意:为了保证jquery所有的方法都能够链式访问,每一个方法的最后都需要返回this,即返回jquery实例 } })})(jquery);

下一篇:前端基础进阶(十四):深入核心,详解事件循环机制

建议收藏,不然刷着刷着就可能找不到了

我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年我花了一个月整理了一份最适合2020年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我的头条号并在后台私信我:前端,即可免费获取

总结

以上是凯发k8官方网为你收集整理的jquery function_前端基础进阶(十三)详细图解jquery扩展jquery插件的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得凯发k8官方网网站内容还不错,欢迎将凯发k8官方网推荐给好友。

  • 上一篇:
  • 下一篇:
网站地图