前言

内容主要是跟着慕课网上的jQuery源码解析系列课程以及自己的实践+理解来写的,可能会有错误,欢迎指出^_^。

节点遍历

遍历的接口可以分为4个类型:

  1. 祖先
  2. 同胞兄弟
  3. 后代
  4. 过滤

所以这个章节的核心内容就是关于如何通过遍历获取到指定的节点的。

获取父辈/祖先节点

主要集中在三个函数:

  • parent():获得当前匹配元素集合中每个元素的父元素
  • parents():获得当前匹配元素集合中每个元素的祖先元素
  • parentsUntil():获得当前匹配元素集合中每个元素的祖先元素,直到(但不包括)被选择器、DOM 节点或 jQuery 对象匹配的元素

因为实际上这三个要达到的目的的手段有相同的部分,所以jQuery把这个环节抽出来写成了一个dir函数,以减少重复代码,模拟实现过程如下:

/* 寻找所有符合要求的节点* elem:目标元素* dir:目标类型(如:parentNode)* until:搜索终止元素 */
function dir(elem, dir, until) {/* matched:符合条件的元素tuncate:搜索终点 */var matched = [],truncate = until !== undefined;   /* nodeType == 9,表示Document当元素存在,并且元素不是Documentdir=="parentNode",则一层层遍历它的parentNode */while ((elem = elem[dir]) && elem.nodeType !== 9) {//nodeType == 1,表示节点为元素if (elem.nodeType === 1) {//如果存在搜索终点(标签名|类名),退出查找if (truncate) {if (elem.nodeName.toLowerCase() == until || elem.className == until) {break;}}//否则加入集合matched.push(elem);}}return matched;
}

补充点:关于$.each()方法

$.each(Object, function(name, value) {this;      //this指向当前属性的值name;      //name表示Object当前属性的名称value;     //value表示Object当前属性的值});$.each(Array, function(i, value) {this;      //this指向当前元素i;         //i表示Array当前下标value;     //value表示Array当前元素});

我们肯定用过$("...").each(fn)方法来遍历对象,但是还有一个$.each方法,可以遍历对象和数组。要把parent三个方法扩充到jQuery里面,就用了这个方法:

  jQuery.each({parent: function(elem) {var parent = elem.parentNode;//如果父节点存在,且不是文档碎片,就返回。return parent && parent.nodeType !== 11 ? parent : null;},parents: function(elem) {//通过dir函数获取所有祖宗节点return dir(elem, "parentNode");},parentsUntil: function(elem, until) {return dir(elem, "parentNode", until);}}, function(name, fn) {/* name:索引值 * fn:属性值 */ajQuery[name] = function(selector,until) {return  fn(selector.until);};});

补充点:关于nodeType
具体请参阅W3CSchool,这里列一些比较常见的:
1:Element,代表元素
2:Attr,代表属性
3:Text,代表元素或属性中的文本内容。
8:Comment,代表注释。
9:Document,代表整个文档(DOM 树的根节点)。
11:DocumentFragment,代表轻量级的 Document 对象,能够容纳文档的某个部分

获取同胞节点

主要是五个方法:

  • nextAll():匹配元素集合中每个元素的所有跟随的同胞元素。
  • prevAll():当前匹配元素集合中每个元素的前面的同胞元素。
  • nextUntil()
  • prevUntil()
  • siblings():获得匹配集合中每个元素的同胞(不包括自己)。

有了dir函数之后,就可以充分利用这个函数了。

function nextAll(elem) {return dir(elem, "nextSibling");
}function prevAll(elem) {return dir(elem, "previousSibling");
}function nextUntil(elem, until) {return dir(elem, "nextSibling", until);
}function prevUntil(elem, until) {return dir(elem, "previousSibling", until);
}function siblings(n, elem) {var matched = [];for (; n; n = n.nextSibling) { //如果存在下一个兄弟节点if (n.nodeType === 1 && n !== elem) { //是元素节点,并且不包括自己matched.push(n);}}return matched;
}

这里siblings的模拟实现思想是获取目标元素的父亲节点,然后遍历父亲节点的直接子节点来获取,碰到了目标元素则跳过不加入。

【笔记】jQuery源码(节点遍历)相关推荐

  1. js便签笔记(9)——解读jquery源码时记录的一些知识点

    近来一直利用业余时间在看jquery2.1.1源码,大约看了两千行了.平时看的时候,做了一些笔记,贴出来分享. 1. Array.prototype.slice.call 可以将伪数组转化为真正的数组 ...

  2. jQuery源码研究分析学习笔记-静态方法和属性(10)

    jQuery源码中定义了一些重要的静态属性和方法,它们是其他模块实现的基础,整体的源码结构如下 //把window.jQuery和winow.$备份到局部变量_jQuery和_$_jQuery = w ...

  3. jQuery源码研究学习笔记(二)

    jQuery总体架构: jQuery模块可以大致分为三部分:入口模块.底层支持模块.功能模块. 参考jQuery技术内幕解析 jquery源码总体架构: (function(window,undefi ...

  4. jquery源码学习笔记三:jQuery工厂剖析

    jquery源码学习笔记二:jQuery工厂 jquery源码学习笔记一:总体结构 上两篇说过,query的核心是一个jQuery工厂.其代码如下 function( window, noGlobal ...

  5. jquery源码学习笔记一:总体结构

    练武不练功,到老一场空.计算机也一样. 计算机的功,就是原理.如果程序员只会使用各种函数,各种框架,而不知其原理,顶多熟练工人而已.知其然,更要知其所以然. jquery我们用得很爽,但它究竟咋实现的 ...

  6. Mr.J-- jQuery学习笔记(二十四)--剖析jQuery源码--extend

    定义和用法 jQuery.extend() 函数用于将一个或多个对象的内容合并到目标对象. 注意:1. 如果只为$.extend()指定了一个参数,则意味着参数target被省略.此时,target就 ...

  7. jQuery源码学习(1)——addClass

    最近比较闲,寻思着学习下jQuery源码,看了好多博客,很多都讲的比较详细.jQuery虽然只有那么200多K,但内容却比较丰富,对于我这样一个js菜鸟,看起来相当吃力.骨头太大,只能化整为零,从简单 ...

  8. jQuery源码分析-10事件处理-Event-事件绑定与删除-bind/unbind+live/die+delegat/unde

    10.4    .bind() .one() 10.4.1  如何使用 .bind( eventType, [eventData], handler(eventObject) )   在匹配的元素上绑 ...

  9. jQuery源码分析-10事件处理-Event-事件绑定与删除-bind/unbind+live/die+delegat/undelegate

    Js代码   作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 声明:本文为原创文章,如需转载,请注明来源并保留原文链接. 后文预告:封装事件对象 便 ...

最新文章

  1. GitHUb 代码提交遇到的问题以及解决办法
  2. Spring Cloud第九篇:链路追踪Sleuth
  3. Jquery v1.3.2 与v1.4.2在andSelf()函数方面的区别
  4. 关于webcontrols的TreeView中转义符的处理问题
  5. 常见的前端vue面试题
  6. python获取IP位置信息
  7. 针对监控摄像机(海康、大华等)进行手动录像的录像文件播放器功能设计
  8. [HDU1394]Minimum Inversion Number
  9. php-fpm 负荷高,记录简单处理服务器php-fpm占用过多的问题(主题影响负载)
  10. latex伪代码添加注释_Latex中文期刊投稿使用:以《系统工程学报》为例
  11. mysql 函数 局部变量_MySQL 存储过程 存储函数 局部变量 游标 概念示例
  12. RabbitMQ发布确认原理
  13. SQL进阶,子查询与窗口函数
  14. mysql varchar(20)_MySQL中采用类型varchar(20)和varchar(255)对性能上的影响
  15. RabbitMQ主题模式(Topic)
  16. linux的jar命令不能使用,经常使用的linux下jar包管理命令
  17. 《算法图解》之选择排序
  18. 20191102每日一句
  19. GPS坐标与UTM坐标的转换
  20. 国际电话区号mysql表SQL

热门文章

  1. 56 - II. 数组中数字出现的次数 II
  2. python twisted教程一,异步编程
  3. 个基于TensorFlow的简单故事生成案例:带你了解LSTM
  4. 一款回到顶部的 jQuery 插件,支持 Div 中的滚动条回到顶部
  5. Decoder is not a @Sharable handler, so can't be added or removed multiple times
  6. python12-并发编程
  7. Hackerrank manasa-and-combinatorics(数学推导)
  8. C++头文件保护符和变量的声明定义
  9. /var/spool/postfix/maildrop小文件太多造成inode索引使用完解决
  10. 在VS2010中F5调试Silverlight程序时,提示“无法启动调试,找不到Microsoft Internet Explorer”...