当前位置: 首页 > Web前端 > HTML5

Zepto核心模块拾取的工具方法

时间:2023-04-05 01:51:59 HTML5

前言在开发过程中经常会用到each、map、forEach等方法,Zepto本身将这些方法挂载在$函数上作为静态方法,可以给Zepto的Instances也可以用于普通的js对象。今天我们主要是针对它提供的这些API做一些源码实现分析。源码仓库原文链接各API使用方法详见英文文档Zepto.js中文文档Zepto.js1。$.camelCase这个方法主要是将连字符转换成驼峰命名法。例如,形式a-b-c可以转换为aBC。当然,连字符的个数可以是多个,a---b-----c=>aBC。具体实现在Zepto中设置的实用方法中已经提到,可以点击查看。它的代码只是将camelize函数分配给$.camelCase$.camelCase=camelize2。$.contains$.contains(parent,node)?boolean该方法主要用于检测parent是否包含给定的node节点。如果父节点和节点是同一个节点,则返回false。示例1

  • 2
  • 让oList=document.querySelector('.list')letoItem=document.querySelector('.item')letoTest=document.querySelector('.test')console.log($.contains(oList,oItem))//真正的父和子节点console.log($.contains(oList,oList))//false相同节点console.log($.contains(oList,oTest))//false兄弟节点源代码$.contains=document.documentElement.contains?function(parent,node){//防止parent和node传递同一个节点,所以先parent!==node//然后调用native的contains方法判断返回parent!==node&&parent.contains(node)}:function(parent,node){//当node节点存在时,将该节点的父节点赋值给该节点while(node&&(node=node.parentNode))//如果父节点存在则返回truenode的node等于parent,否则继续向上查找//其实有个问题,为什么不一开始就去查node===parent的情况//否则循环之后会得到false最后,这是非常浪费的。if(node===parent)returntruereturnfalse}使用document.documentElement.contains做判断,如果浏览如果浏览器支持这种方式,我们使用node.contains重新封装一层得到一个功能。不同的是,如果传入的两个node相同,那么原来的node.contains返回true。具体用法参考MDNNode.contains但是$.contains返回false。如果原生不支持,我们需要自己写一个方法。主要逻辑是通过while循环判断传入的node节点的父节点是否是parent。如果一个循环结束,它不会在最后返回false。两个节点是否为同一个节点不做后续判断。3.$.each用于遍历数组或对象,类似于原来的forEach但不同的是循环的执行可以中断,服务对象不限于数组。例子lettestArr=['qianlongo','fe','juejin']lettestObj={name:'qianlongo',sex:'boy'}$.each(testArr,function(i,val){console.log(i,val)})//0"qianlongo"//1"fe"//2"juejin"$.each(testObj,function(key,val){console.log(key,val)})//名称qianlongo//sexboy需要注意的是,此时回调函数中的this指向数组或对象中的某一项。这里主要是为了方便遍历dom节点的时候一些其他的内部方法,this方便的指向对应的dom源码实现$.each=function(elements,callback){vari,key//如果是类数组就拿这个ifif(likeArray(elements)){for(i=0;i{returnval})letresultArr2=$.map(testArr,(val,i)=>{return[val,[val]]})//看一下原图的表现letresultArr3=testArr.map((val,i)=>{returnval})let结果Arr4=测试Arr。map((val,i)=>{return[val,[val]]})的结果如下。可以看出resultArr1和resultArr3的区别在于$.map过滤掉了undefined和null。resultArr2和resultArr4的区别在于$.map对回调函数的返回值进行了扁平化处理。接下来我们看看源码是如何实现的。$.map=function(elements,callback){varvalue,values=[],i,key//如果是类数组,使用for循环if(likeArray(elements))for(i=0;i{}letdoSomeThingElse=()=>{}如果你直接这样做letdoSomeThing=$.noopletdoSomeThingElse=$.noop宿主环境不必为我们创建多个匿名函数。其实还有一个场景可能用的不多,可以在判断一个变量是否undefined的时候用到。因为函数没有返回值,所以默认返回undefined,即排除undefined可以被老式浏览器修改的情况if(xxx===$.noop()){//xxx}13.$.parseJSONnativeJSON.parse方法的别名,接收一个字符串对象,返回一个对象。源码实现$.parseJSON=JSON.parse14。$.trim删除字符串开头和结尾的空白字符。如果传入null或undefined,则返回一个空字符串。源码实现$.trim=function(str){returnstr==null?"":String.prototype.trim.call(str)}15.$.type获取JavaScript对象的类型。可能的类型有:nullundefinedbooleannumberstringfunctionarraydateregexpobjecterror。该方法的内部实现其实就是内部类型函数,在Zepto的这些实用方法集中已经有所论述,可以点击查看。$.type=type以Zepto大部分工具方法或静态方法结尾,有错误和问题欢迎指正。参考阅读工具函数MDNtrimMDNtypeofMDNisNaNMDNNumberMDNNode.包含zepto源码。文章记录你是这样的jsonp(原理和具体实现细节)。谁说您只是“知道如何使用”jQuery?学习zepto.js如何手动触发DOM为什么事件mouseenter和mouseover这么纠结?Zepto中的这些实用方法集