摘要:优化代码的原则就是提出重复的代码。新的叫它,它返回一个对象,对象里面有两个函数,也就是和,并用初始化。当然了这只是的基本原理,实际远比它复杂。
学习了DOM api 之后,做些简单的小练习
在HTML写5个无序列表
获取item3的所以的兄弟节点如何做呢?
DOM 提供了nextSbiling`previousSbiling,有人说用parentNode.children获取,但是这样做item3`也在里面了,所以就自己做一个API,
我把这个名字叫做getSiblings
//node 是参数,传递item3进来,传出item3的所有兄弟节点。 function getSiblings(node){ var allChildren = node.parentNode.children //先获取item3所有兄弟节点,保存在allChildren中,是一个伪数组 //剔除item3节点 var array = {length:0}; //创建一个伪数组,存储item3节点的所有兄弟节点,因为是伪数组,所以给它添加length:0 for(var i=0; i如果要给item3添加或删除class,用自带的API 只能一个个添加,看下面
item3.classList.add("a") item3.classList.add("b") item3.classList.add("c") item3.classList.remove("b")如果自己做一个API,是不是可以实现批量添加呢
//node classes 是参数,要添加或删除class的节点,这里传递的classes是伪数组 function addOrRemoveClass(node,classes){ for(var aaa in classes){ //用for循环遍历classes的key var a = classes[aaa]; //用一个变量来存储classes的value if(a){ //用if循环判断classes的value是true还是false node.classList.add(aaa); //如果是true,则添加key }else { node.classList.remove(aaa);//否则移除 } } } addOrRemoveClass(item3,{"a":true,"b":false,"c":true});上面代码if...else...中有重复代码,可优化成下面这样。
优化代码的原则就是提出重复的代码。
var methondName = a?"add":"remove"; //add、remove要用字符串 node.classList[methondName](aaa)下面先看添加class怎么实现。
foreach接受一个函数参数,函数参数是数组的value和key,可以看之前总结的Array基本概念//node classes 是参数,要添加或删除class的节点,这里classes是数组 function addClass(node,classes){ classes.forEach(value => node.classList.add(value)) //把数组的`value`添加到class中 } addClass(item3,[a,b,c])用这样的方法创建好用的API,但有个不足的地方,这些都是全局变量,如果在大项目中,很容易覆盖别人的变量。
所以把自己写的API 添加到Node的原型上
Node.prototype.getSiblings = function(){ var allChildren = this.parentNode.children; //this指代调用时前面的那个 var array = {length:0}; for(var i=0; ithis.classList.add(value)) } item3.getSibllings.call(item3) //用call的话,直接指定this,不用call的话,是隐示指向`.`前面那个 item3.addClass.call(item3,["a","b","c"]) 不理解this的可以看函数小知识点
在原型上面添加方法也和上面一样有弊端,第一项目一大,所有人都在原型上面添加,就会造成原型里面很混乱;第二你也不知道别人有没写和你一样的方法,这又会造成覆盖的问题。
因为这是在Node上直接写的,那我能不能自己写一个Node这样就不会和人家重名了,就算遇到,改一个名字呗。新的Node叫它Node2,它返回一个对象,对象里面有两个函数,也就是getSiblings和addClass,并用node2初始化。
//Node2相当于原来的Node window.Node2 = funcuntion(){ return{ //返回2个方法 getSiblings:function(){}, addClass:function(){} } } var node2 = Node2(""item3) //初始化 node2.getSiblings.call() //正常调用 node2.addClass.call()getSiblings和addClass方法还是和前面一样,之前我们用this来指代node,但是这里用this的话会指向node2,而我们要操作的是node,所以要把this变成node才行。
window.Node2 = function(node){ //参数是要操作的节点 return{ getSiblings:function(){ var allChildren = node.parentNode.children; //这里不能用this 了,因为用this会变成前面的.node2,而这里我们要操作的是node var array = {length:0}; for(var i = 0; i < allChildren.length;i++){ if(allChildren[i] !== node){ array[array.length] = allChildren[i]; array.length++; } } return array; }, addClass:function(classes){ classes.forEach(value => node.classList.add(value)) } } } var node2 = Node2(item3); node2.getSiblings(); //这里为什么不需要传入节点,因为在初始化的时候,已经把节点传进去了 node2.addClass(["a","b","c"]);如果把Node2改成jQuery其他都不变,是不是也可以,看下面,getSiblings和addClass里面的方法就不写了。
window.jQuery = funcuntion(){ return{ getSiblings:function(){}, addClass:function(){} } } var node2 = jQuery(item3) node2.getSiblings.call() node2.addClass.call()jQuery就是一个升级的DOM,它接受一个参数,然后返回一个新的对象,这个新对象有新的API,就是这边的getSiblings和addClass,它们的内部是怎么实现的呢,还是去调用浏览器提供的API,区别是你就写下面调用的API,一句话就可以了,而jQuery是在里面调用老的API,进行复杂的转换。
简单的说jQuery就是接收一个参数,返回给你一个新对象,你调用它提供的API 就可以了。
当然了这只是jQuery的基本原理,实际远比它复杂。
再来看下面的例子,如果我传递的是选择器怎么操作呢?
window.jQuery = function(nodeOrSelector){ var node; //存储if判断后的参数 if(typeof nodeOrSelector === "string"){ //因为选择器是以字符串的形式传递进来的,所以先要用if进行判断,typeof用来判断类型的 node = document.querySelector(nodeOrSelector); //如果是字符串,就是选择器,根据选择器找到对应的节点,并保存在声明的变量中 }else{ node = nodeOrSelector; //如果不是,直接保存在变量中 } return{ getSiblings:function(){ var allChildren = node.parentNode.children; var array={length:0}; for(var i = 0 ;i < allChildren.length;i++){ if(allChildren[i] !== node){ array[array.length] = allChildren[i]; array.length++; } } return array; }, addClass:function(classes){ classes.forEach(value => node.classList.add(value)) } } } var node2 = jQuery("#item3"); //传递选择器,使用字符串的形式表示 node2.getSiblings(); node2.addClass(["red"]);初始化的时候传递了一个选择器,jQuery 内部先进行判断,传进来的是不是字符串,如果是,我就找到对应的节点;后面的操作和之前讲的一样。
我们再来升级下jQuery,如果我想同时操作5个节点呢?看下面:
window.jQuery = function(nodeOrSelector){ var nodes = {}; //querySelectorAll输出的是伪数组,所以用来存储的变量也要初始化成伪数组 if(typeof nodeOrSelector === "string"){ //用typeof判断传进来的类型 var temp = document.querySelectorAll(nodeOrSelector);//如果传进来的是选择器,就获取对应所有的节点,querySelectorAll输出的是伪数组 //因为获取到的不是纯净的伪数组(原型不是直接指向Object),先用临时变量存储,再用for循环遍历一遍就可以了 for(var i = 0; i < temp.length; i++){ nodes[i] = temp[i] } nodes.length = temp.length; //把临时变量的length长度赋值给nodes,下面遍历时需要用到 }else if(nodeOrSelector instanceof node){ //instanceof用来判断传进来的是不是节点,因为节点只能传进来一个 nodes = { //因为上面用的是伪数组,所以这边也要一致,虽然节点是一个,但也要做成伪数组的形式 0:nodeOrSelector, length:1 }; } //这时伪数组内部是{0,1,2,3,4}的属性,没有addclass的方法,所以这边可以直接往里面添加方法 nodes.addClass = function(classes){ for(var i = 0; i < nodes.length; i++){ classes.forEach(value => nodes[i].classList.add(value)); //nodes不是元素,这边操作是在元素身上,所以要for循环遍历,动态添加 } } nodes.text = function(text){ if(text === undefined){ //这里默认没传参数就是获取节点文本 var texts = []; //文本最终是数组的形式 for(var i = 0; i < nodes.length; i++){ //遍历nodes,就可以获取到了 texts.push(nodes[i].textContent); } return texts; }else{ //有参数就是设置文本 for(var i = 0; i < nodes.length; i++){ nodes[i].textContent = text; } } } return nodes; //因为整个jQuery内部是一个伪数组,所以这边返回出去了肯定也是一个伪数组了 } var node2 = jQuery("ul > li"); node2.addClass(["red"]); console.log(node2.text()); node2.text("hi");最后简化一下jQuery ,初始化时的变量名最好带上$,后面好辨认。
window.$ = jQuery; var $node2 = $("item3");
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/95103.html
摘要:它能够使得在不刷新浏览器的情况下,更改本地的前端代码组件,浏览器自动更新预览。直接集成了这项技术,而且建立了专门的通道进行错误的实时反馈。命令行提供了三个主要的命令,。服务器关于服务器,其实是内部起了一个基于的服务器,外加进行消息的通讯。 跟着初探了下flintjs,的确会很棒,超级热更新! 学习地址: http://frontenddev.org/link/ali-11-11-...
摘要:后来在爬取不到让我一度怀疑人生的时候巧合下,发现磁力链接有小写字母,有长度的,有长度的。。 原文博客: 羞羞的node爬虫 前言 学了一阵子node,除了用 express 写东西,就没怎么做过东西突然就想写个 爬虫 来玩一玩,而且还是爬一些羞羞的东西 使用模块 SuperAgent 是个 http 方面的库,可以发起 get 或 post 请求。 cheerio 大家可以理解成一个 ...
摘要:后来在爬取不到让我一度怀疑人生的时候巧合下,发现磁力链接有小写字母,有长度的,有长度的。。 原文博客: 羞羞的node爬虫 前言 学了一阵子node,除了用 express 写东西,就没怎么做过东西突然就想写个 爬虫 来玩一玩,而且还是爬一些羞羞的东西 使用模块 SuperAgent 是个 http 方面的库,可以发起 get 或 post 请求。 cheerio 大家可以理解成一个 ...
阅读 2079·2021-11-24 10:34
阅读 3054·2021-11-22 11:58
阅读 3711·2021-09-28 09:35
阅读 1723·2019-08-30 15:53
阅读 2769·2019-08-30 14:11
阅读 1550·2019-08-29 17:31
阅读 541·2019-08-26 13:53
阅读 2140·2019-08-26 13:45