对于jQuery的调用,我们一般都会传入参数

  html: <div></div>
js: console.log($('<a />'));
console.log($('div'));

一、前置(DOM对象和jQuery对象)

  1. DOM对象,

    关于这个,应该是前端的基础知识了,在文档对象模型中,每个部分都是节点。
  2. jQuery对象

    这个是指通过jQuery构造函数创建出来的对象,可以通过jQuery选择器获取到,并以类数组的形式保存在jQuery中

二、实践

仔细观察返回的jQuery对象,感觉像是对DOM节点进行封装,并将其保存在jQuery上

一、实现一个基本的创建选择器
  1. 获取到传入参数,判断是创建一个jquery节点,还是查询节点,
  2. 创建新节点,传入的是一个html标签,以此进行判断
     //获取到传入的参数
var jQuery = function(selector, content) {
return new jQuery.prototype.init(selector, content);
}
jQuery.prototype = {
length: 0,
init: function(selector, content) {
content = content || document;
var match; //match 用来保存selector;
if(typeof selector === 'string') {
// 判断selector传入的是一个html标签;
if(selector.charAt(0) === '<' && selector.charAt(selector.length-1) === '>' && selector.length >= 3 ) {
match = [selector];
}
if (match) {
//创建一个jQuery对象。
}
}
}
}
  1. 确定好是需要创建一个节点之后,我们就需要思考需要进行什么操作。需要将标签名解析出来,然后利用createElement创建节点,并保存。

    • 定义一个html解析函数
     var reg = /^<(\w+)\s*\/?>(?:<\/\1>|)$/;
jQuery.extend({
parseHtml: function(data, content) {
if (!data && typeof data != 'string') {
return null;
}
var parse = reg.exec(data);
return [content.createElement(parse[1])] //ok,这里是将创建的一整个DOM节点保存在了数组中。
}
})
  * 已经可以获取到创建的节点了,下面将节点挂载在jQuery上就可以了。
     if(match) {
for(; i < match.length; i++) {
var opt = match[i]
this[i]=jQuery.parseHtml(opt, content)[i]
}
}

好了,现在我们就可以看下代码的执行结果了。



ok,勉强可以实现,但好像还是有点不对的样子, 让我们来看下jQuery的源码。



可以看出是调用了merge方法。跳转到merge方法查看一下,一般来说,merge用于合并两个数组, 也可以用于将数组合并在有length属性的对象上。

      // push.apply(_, arraylike) throws on ancient WebKit

      merge: function (first, second) {
var len = +second.length,
j = 0,
i = first.length;
for (; j < len; j++) {
first[i++] = second[j];
}
first.length = i;
return first;
}

了解的区别后,我们来优化代码吧,

4. 优化

二、实现一个基本的标签选择器
  1. DOM原生节点查询

    • document.querySelector
    • document.querySelectorAll //返回一个NodeList
  2. 实践

    利用document原生查取节点的方式,获得结果,再将其每一个放在jQuery上
     var ele, i = 0;
if(match) {}
else {
ele = document.querySelectorALL(selector);
for(; i < ele.length; i++) {
this[i] = ele[i]
}
this.length = ele.length;
}
三、关于传入一个方法的选择器
  1. 首先看下init中是如何处理的:
  var rootjQuery;
init = jQuery.fn.init = function(selector, context, root) {
...
root = root || rootjQuery;
if(typeof selector === 'string') {
...
} else if (isFunction(selector)) {
return root.ready !== undefined ? root.ready(selector) : selector(jQuery);
}
}
rootjQuery = jQuery(document);

代码可以看出,其实js是可以传递三个参数的,且root默认为document,如果root.ready没有初始话的话就立刻执行传入的方法,否则调用root.ready方法。关于root,从代码可以看出,是个全局,那么root.ready == jQuery.ready。

2. 在看ready方法前,需要明确一个问题,jquery传入方法的处理是在文档加载之后执行,所以首先应该对文档是否加载完毕进行判断。

    function completed() {
document.removeEventListener('DOMContentLoaded',completed);
window.removeEventListener('load', completed);
jQuery.ready();
} if(document.readyState === 'complete' || (document.readyState !== "loading" && !document.documentElement.doScroll)) {
window.setTimeout(jQuery.ready);
} else {
//dom加载完毕后,调用complate移除监听事件。
document.addEventListener('DOMContentLoaded', complete);
window.addEventListener('load', completed);
}
  1. 可以看下jQuery.ready方法了。
  jQuery.extend({
// DOM是否已经准备好要使用了,发生更改,则修改为true;
isReady: false,
//跟踪就绪事件触发前要等待的项目数计数器
readyWait: 1,
ready: function(wait) {
if(wait === true ? --jQuery.readyWait : jQuery.isReady) {
return ;
}
//DOM节点已经准备好了
jQuery.isReady = true; if(wait !== true && --jQuery.readyWait > 0) {
return
}
//如果有函数绑定,立即执行。
readyList.resolveWidth(document, [jQuery])
}
})

从2.的时候可以看出,在DOM节点加载完的时候,调用了一次ready,此时没有传入wait,ready中第一个判断直接跳过,记录jQuery.isReady = true,然后再看下一句执行,调用readyList.resolveWidth方法,此时DOM节点已经加载完毕,可以执行绑定的函数了,

关于这个readyList是什么,我们在代码中找一下看下,

   var readyList = jQuery.Deferred();

   jQuery.fn.ready = function(fn) {
ready.then(fn).catch(error) {
jQuery.readyException(error);
}
return this;
}

从以上代码可以看出,readyList是Deferred函数的返回值,且从下面的调用,可以推测Defferred函数应该是个promise对象。对于Defferred函数,下次再仔细研究一下。

现在让我们来回顾整个函数流程:



上面的内容只是我自己的理解,如果有什么不对的地方,希望大家帮忙指出啊!

jQuery(三)之 选择器(基础版)的更多相关文章

  1. jquery双向列表选择器select版

    这个是select版的,若想美化某些样式是不支持得,可以用div模拟版的,功能基本实现能用了,需要其他功能自己加上. div模拟版链接:http://www.cnblogs.com/tie123abc ...

  2. jQuery---jq基础了解(语法,特性),JQ和JS的区别对比,JQ和JS相互转换,Jquery的选择器(基础选择器,层级选择器,属性选择器),Jquery的筛选器(基本筛选器,表单筛选器),Jquery筛选方法

    jQuery---jq基础了解(语法,特性),JQ和JS的区别对比,JQ和JS相互转换,Jquery的选择器(基础选择器,层级选择器,属性选择器),Jquery的筛选器(基本筛选器,表单筛选器),Jq ...

  3. java:JQuery(声明,JQ和JS对象的区别,prop,attr,addClass,offset,trigger,dblclick和change事件,hide,show,toggle,slideUp,slideDown,slideToggle,三种选择器,标签的获取,三张图片的放大与缩小)

    1.JQuery: jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架).jQuery设计 的宗旨是“ ...

  4. jquery选择器基础知识(复制w3c)

    jQuery 元素选择器 jQuery 使用 CSS 选择器来选取 HTML 元素. $("p") 选取 <p> 元素. $("p.intro") ...

  5. 强大的JQuery(一)--基础篇

    JQuery是一个优秀的Javascript框架,是轻量级的js库,使用jQuery将极大的提高编写javascript代码的效率,,让写出来的代码更加优雅,更加健壮. 学好了jquery,我们相当于 ...

  6. jQuery初识之选择器、样式操作和筛选器(模态框和菜单示例)

    一.jQuery 1.介绍 jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架). jQuery设计的 ...

  7. jQuery使用(一):jQuery对象与选择器

    一.简单的一些介绍 1.jQuery是由普通的是由一些系列操作DOM节点的函数和一些其他的工具方法组成的js库. 2.为什么要使用jQuery库? jQuery面向用户良好的设计在使用过程中彻底解放了 ...

  8. jQuery学习笔记(基础部分)

    参考:菜鸟教程 一.简介 1.jQuery 是一个 JavaScript 库. 2.jQuery的版本:压缩版(用户生成)和未压缩(用于测试和开发) 3.jQuery的引入方式: 从http://jq ...

  9. 从零开始学习jQuery (三) 管理jQuery包装集

    本系列文章导航 从零开始学习jQuery (三) 管理jQuery包装集 一.摘要 在使用jQuery选择器获取到jQuery包装集后, 我们需要对其进行操作. 本章首先讲解如何动态的创建元素, 接着 ...

随机推荐

  1. Leecode之双指针及二分查找

    题目 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2. 说明: 返回的 ...

  2. [codevs1286]郁闷的出纳员

    题目描述 Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复 ...

  3. 9-3 deepsort在win10配置

    win10+python3.5+tensorflow https://blog.csdn.net/Draw_1999/article/details/79735677 deep-sort https: ...

  4. Random Access Iterator 徐州网络赛(树形dp)

    Random Access Iterator \[ Time Limit: 4000 ms \quad Memory Limit: 262144 kB \] 题意 给出伪代码,问按着伪代码在树上跑,能 ...

  5. SQL数据同步到ELK(一)- 日常开篇

    需求 在我们的实际业务中,业务数据大部分是通过传统DB做持久化,但有时会使用Solr/Elastic Search等做搜索.缓存等其他服务,那么如何将数据同步到这些异构的存储系统中呢? 这就是我最近在 ...

  6. 【07月01日】A股滚动市净率PB历史新低排名

    2010年01月01日 到 2019年07月01日 之间,滚动市净率历史新低排名. 上市三年以上的公司,2019年07月01日市净率在30以下的公司. 来源:A股滚动市净率(PB)历史新低排名. 1 ...

  7. [C++基础] 变量、关键字、运算符、位操作篇

    一.变量篇 1 全局变量和静态变量有什么异同? 相同:都在静态存储区分配空间,生命周期与程序生命周期相同. 区别:全局变量的作用域是整个程序,它只需要在一个源文件中定义,就可以作用于所有的源文件.而静 ...

  8. linux shell 写swoole重启脚本

    linux shell 写swoole重启脚本 代码如下<pre>#!/bin/shkill `lsof -t -i:9501`sleep 2php /data/web/mircoweb/ ...

  9. php filter_var()

    定义和用法 filter_var() 函数通过指定的过滤器过滤变量. 如果成功,则返回已过滤的数据,如果失败,则返回 false. 语法 filter_var(variable, filter, op ...

  10. Feign实现自定义错误处理

    关键操作 实现ErrorDecoder接口 问题和背景 最近项目中在大量使用Feign和OkHttp作为http客户端使用,开发效率得到显著的提升.但也面临一些问题,比如每个下游系统的异常返回方式不同 ...