jQuery 第二章 实例方法 DOM操作选择元素相关方法
进一步选择元素相关方法:
.get()
$(".class").get() 可以填 $()选择器选出来的dom 索引, 0 1 2 3 -1 -2 , 不填 取全部dom, 但是
取出来的dom 不再是jquery的对象,而是原生dom, 用get()取出来的 dom 都为原生dom;
现在会用了,但是咱们不能单单只会用,还要知道其原理,以下模仿其功能,写一个 .get() 方法。
把上一篇写的 jQuery 函数全部抽出来, 建立一个单独文件为我们自己的 myJquery.js ,
自己慢慢学,写成一个我们自己的jquery 库
1 (function(){
2 function jQuery(selector){
3 return new jQuery.prototype.init(selector);
4 }
5 jQuery.prototype.init = function(selector){
6
7 if( selector.indexOf('.') != -1 ){
8 var dom = document.getElementsByClassName( selector.slice(1) );
9 }else if( selector.indexOf('#') != -1 ){
10 var dom = document.getElementById( selector.slice(1) );
11 }else{
12 var dom = document.getElementsByTagName(selector);
13 }
14 this.length = 0;
15 if( dom.length == undefined ){
16 this[0] = dom;
17 this.length ++;
18 }else{
19 for( var i = 0; i < dom.length; i++ ){
20 this[i] = dom[i];
21 }
22 this.length = dom.length;
23 }
24 }
25 jQuery.prototype.css = function(config){
26 for(var i = 0; i < this.length; i++){
27 for(var prop in config){
28 this[i].style[prop] = config[prop];
29 }
30 }
31 return this;
32 }
33 //以下为我们本章的.get() 方法
34 jQuery.prototype.get = function(num) {
35 if (num == null) { //判断用户有没有填参数。
36 return [].slice.call(this, 0); //空截,把类数组转成数组,借用Array.prototype.slice方法
37 } else {
38 if (num < 0) {//判断用户是否输入 负数。
39 return this[num + this.length];
40 //举个例子 [a, b, c] 此数组的长度为3
41 // 用户输入-1 想要拿最后一位 c,如果你把-1 + 3该数组的长度, 你会发现 刚好等于 最后一位的索引
42 } else {
43 return this[num];//如果用户输入 0 1 2 3 直接返回this 中的 dom 即可
44 }
45 }
46 //以下为简化版本 三目运算符 ↓
47 //return num == null ? [].slice.call(this, 0) : (num < 0 ? this[num + this.length] : this[num]);
48
49 }
50 jQuery.prototype.init.prototype = jQuery.prototype; //$()运行的是init的函数 init的prototype上面没有css方法。
51 //所以 我们把init的prototype指向jQuery.prototype
52 window.$ = window.jQuery = jQuery;
53 })()
.eq()
这个方法和.get() 有点像,但是,获取的dom 并不是原生的dom 了,是 jquery对象的dom,
除此之外,还有一个不同点,不传参数 .get() 是返回全部原生dom,.eq()是返回空。
模拟原理,往我们自己的myJquery.js 添加.eq() 方法,你会发现 此方法 和 get方法的原理一样,但是 有点不同,返回的
jquery对象的dom, 我们先在做另外一个功能, 往$() 传 原生dom 会把你传的dom包装成 jquery对象的dom。
1 (function(){
2 function jQuery(selector){
3 return new jQuery.prototype.init(selector);
4 }
5 jQuery.prototype.init = function (selector) {
6 //加上以下代码
7 if (selector == null) { //判断 有没有传值,没有传值,直接返回 this (jquery 对象)
8 return this;
9 }
10 //如果还按照以前selector.indexOf('.')的话,传入 dom,dom上面没.indexof方法,会报错,再加上一层判断
11 //typeof selector == 'string' 判断他是字符串 再执行, dom的话,就进不去了 &&运算符,遇到假就返回
12 if(typeof selector == 'string' && selector.indexOf('.') != -1 ){
13 var dom = document.getElementsByClassName(selector.slice(1));
14 // ↓ 也要加上哦
15 }else if(typeof selector == 'string' && selector.indexOf('#') != -1 ){
16 var dom = document.getElementById( selector.slice(1) );
17 }else if(typeof selector == 'string'){//zheli
18 var dom = document.getElementsByTagName(selector);
19 }
20
21 this.length = 0;
22 // 主要在这里 加上以下代码 ↓ 判断 传进来的值 是否是dom 元素, 是的话,就进去
23 if(selector instanceof Element || dom.length == undefined ){
24 this[0] = dom || selector; // 把selector 直接挂到 this[0] 位上就OK了
25 this.length ++;
26 }else{
27 for( var i = 0; i < dom.length; i++ ){
28 this[i] = dom[i];
29 }
30 this.length = dom.length;
31 }
32 }
33 jQuery.prototype.css = function(config){
34 for(var i = 0; i < this.length; i++){
35 for(var prop in config){
36 this[i].style[prop] = config[prop];
37 }
38 }
39 return this;
40 }
41
42 jQuery.prototype.get = function(num) {
43
44 return num == null ? [].slice.call(this, 0) : (num < 0 ? this[num + this.length] : this[num]);
45 }
46 // 跟 get方法原理差不多,差的就是, 传进去是空的话 返回 null 即可,
47 jQuery.prototype.eq = function (num) {
48 var dom = num == null ? null : (num < 0 ? this[num + this.length] : this[num]);
49 return $(dom); // 如果直接返回 dom 就是返回原生的dom 我们要把他包装一下,变成jquery对象, 此方法
50 // 在上面已经实现了。
51 }
52 jQuery.prototype.init.prototype = jQuery.prototype;
53
54 window.$ = window.jQuery = jQuery;
55 })()
下面几个方法不探究 原理,几乎原理都是用一大堆正则筛选出来的
.find()
用法是 在什么之下, 举个例子 $('.wra').find('span1') 这样会选出span1标签, 在.wra 下面 找span1,
跟$('.wra span1')好像一样,但是 这两个差别还是挺大的。
$('.wra span1') 其实这样把选择器给 选死了, jquery的精髓在于链式调用, 你后面的 . 什么方法,全部都在
操作$('.wra span1') 这个, 并不能改变了,如果想再选span2的就得重新选 但是 $('.wra').find('span1') 并不会选死了,
你现在选了span1,你后面假如不想操作span1了,你可以通过 回退操作等方法,返回上一次选择的元素,直接选span2
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <meta http-equiv="X-UA-Compatible" content="ie=edge">
7 <title>Document</title>
8 </head>
9 <body>
10 <div class="wra">
11 <span class="span1">
12 span1
13 </span>
14 <span class="span2">
15 span2
16 </span>
17 </div>
18
19 <script src="./jquery/jquery.js"></script>
20 <script>
21 //第一种选法
22 $('.wra .span1')
23 .css({background:'red'});
24 $('.wra .span2')
25 .css({background:'green'})
26
27 //使用find()
28 $('.wra')
29 .find('.span1')
30 .css({background:'red'})
31 .end()
32 .find('.span2')
33 .css({background:'green'})
34
35
36
37 </script>
38 </body>
39 </html>
.filter()
意思如其名,.filter()方法就是过滤。 可传入 css selector jquery dom 等等,他会按照你传进去的参数,
过滤掉 没有 这个参数的。 还可以传 函数(fn) 传函数,就跟 数组上的 filter方法比较像了 。如图所示,把不是 span2 其他dom给过滤掉了。
传入函数,函数第一个参数为index 索引,第二个为,ele 元素。处理后需要你返回一个true 或者 false , true表示留下该值
过滤掉class名不是为 "span2" 的元素
.not()
学了filter 之后,自然你就会not了, 为什么,因为not和filter是相反的。
.is()
判断是否有交集,我选的东西,里面有没有你;
.has()
1 <ul>
2 <li>1</li>
3 <li>
4 2
5 <p></p>
6 </li>
7 <li>3</li>
8 <li>4</li>
9 <li>5</li>
10 </ul>
11 <ul>
12 <li>6</li>
13 <li>7</li>
14 <li>8</li>
15 <li>9</li>
16 <li>10</li>
17 </ul>
接下来,重头戏来了:
.add() 和 .end()
.add() 添加元素到匹配的元素集合, 意思就是,$('.wra').add('.dome'), 先选了 .wra元素,然后加上.dome元素,即使没有关系也能加在一起
看个案例吧。像下面这种情况,给两个没有关系的元素加上一样的样式。
如果有一天,我不想给.wra变成红色了,我想把它绿了,那么这个时候,end() 就派上用场了,他会回退到你上一次选择的地方,不需要你
传参,利用的是 jquery 对象里面 prevObject 属性,每次选择元素,这个属性都会记录你上一次选择的元素是什么,end 就是利用 prevObject 来进行回退的;
我们来利用end()方法把.wra 给绿了
剖析原理:
咱们知道,add()方法, 是把 上一次选择,和 自己选择的元素给结合起来,所以,里面肯定有两个 值,第一个是 记录上一次选择的,
第二个是记录 本身自己选择的,还有一个值,是用来接收这两个值 合在一起的,此代码编辑在myJQuery.js文件下
1 (function(){
2 function jQuery(selector){
3 return new jQuery.prototype.init(selector);
4 }
5 jQuery.prototype.init = function (selector) {
6 this.length = 0;
7 if (selector == null) {
8 return this;
9 }
10 if(typeof selector == 'string' && selector.indexOf('.') != -1 ){
11 var dom = document.getElementsByClassName(selector.slice(1));
12 }else if(typeof selector == 'string' && selector.indexOf('#') != -1 ){
13 var dom = document.getElementById( selector.slice(1) );
14 }else if(typeof selector == 'string'){
15 var dom = document.getElementsByTagName(selector);
16 }
17
18
19 if(selector instanceof Element || dom.length == undefined ){
20 this[0] = dom || selector;
21 this.length ++;
22 }else{
23 for( var i = 0; i < dom.length; i++ ){
24 this[i] = dom[i];
25 }
26 this.length = dom.length;
27 }
28 }
29 //先看56行
30 jQuery.prototype.pushStack = function (dom) {
31 //这里的this 是$('.wra'),也就是上一次选择的元素, 所以我们把this 加到 你想加的对象上就可以
32 if (dom.constructor != jQuery) {//这里判断 你传进来的值是否为 jquery 对象的dom
33 dom = jQuery(dom); //如果不是,那么就把你变成jquery 对象的 dom。
34 }
35 dom.prevObj = this;//不管是不是 jquery 对象的dom,你最后都是要加上 prevObj属性的。
36 return dom; //返回 加上 prevObj 属性 就是传进来的值。
37 }
38 jQuery.prototype.css = function(config){
39 for(var i = 0; i < this.length; i++){
40 for(var prop in config){
41 this[i].style[prop] = config[prop];
42 }
43 }
44 return this;
45 }
46
47 jQuery.prototype.get = function(num) {
48 return num == null ? [].slice.call(this, 0) : (num < 0 ? this[num + this.length] : this[num]);
49 }
50
51 jQuery.prototype.eq = function (num) {
52 var dom = num == null ? null : (num < 0 ? this[num + this.length] : this[num]);
53 return this.pushStack(dom);// 这里做一个小修改,原来我们这里并没有加上 prevObj属性,现在加上
54 }
55
56 jQuery.prototype.add = function (selector) {//加上add 方法
57 var baseObj = this;//谁调用add这个方法,this就是谁,拿到上一个元素
58 var curObj = jQuery(selector);// 传进来的值,要进行选择,我们之前写过jQuery() 利用它进行选择
59 var newObj = jQuery();//var一个空的jquery对象变量来接收 上面两个元素的集合。
60
61 for (var i = 0; i < baseObj.length; i++) {//遍历 上一个元素,拿出dom, 赋给newObj
62 newObj[newObj.length++] = baseObj[i];
63 } //第一次遍历的时候,newObj的length 为0, 每次 赋值后 ++;
64 for (var i = 0; i < curObj.length; i++) { //遍历 传进来的元素,拿出dom, 赋给newObj
65 newObj[newObj.length++] = curObj[i];
66 }
67 //到这里,add的功能就算完成了,但是你会发现,我们写的,没有prevObject 这个属性,接下来添加这个属性
68
69 //请看30行,我添加了一个为pushStack的方法
70 // this.pushStack(newObj); 此时的this 是谁?谁调用了 我们add方法,this就是谁 我们是$('.wra')
71 return this.pushStack(newObj); //最后把 newObj 返回出去,以供下一次链式调用。
72 }
73
74
75 jQuery.prototype.end = function () { //加上end方法
76 //end 这个方法,就是返回上一次选择的元素,那么我们直接把,谁调用它,就把它的prevObj返回就ok
77 return this.prevObj;
78 }
79 jQuery.prototype.init.prototype = jQuery.prototype;
80
81 window.$ = window.jQuery = jQuery;
82 })()
结果如下:很好的模拟了
觉得有用,点个赞呗, 谢谢你的查看
jQuery 第二章 实例方法 DOM操作选择元素相关方法的更多相关文章
- jQuery 第二章 实例方法 DOM操作取赋值相关方法
取赋值相关方法: .html() .text() .val() .size() .addClass() .removeClass() .hasClass() .html() html方法干嘛的呢,底 ...
- jQuery选择器对应的DOM API ——选择元素
英文原文:http://blog.garstasio.com/you-dont-need-jquery/selectors/愚人码头注: 原作者的写这文章的意图是让我们抛弃jQuery,You Don ...
- jQuery 第四章 实例方法 DOM操作_基于jQuery对象增删改查相关方法
.next() .prev() .nextAll() .prevAll() .prevUntil() .nextUntli() .siblings() .children() .parent() .p ...
- jQuery 第四章 实例方法 DOM操作之data方法
jquery 里面 的 data 方法比较重要, 所以成一个模块写: 首先, 得知道 data() 干嘛用的, 看淘宝上 有自定义的属性, 为data - 什么什么, 这是为了dom 跟数据有 ...
- jQuery学习笔记之DOM操作、事件绑定(2)
jQuery学习笔记之DOM操作.事件绑定(2) --------------------学习目录------------------------ 4.DOM操作 5.事件绑定 源码地址: https ...
- jQuery使用(五):DOM操作之插入和删除元素
插入: insertBofore() before() insertAfter() after() appendTo() append() prependTo() prepen() 删除: remov ...
- jQuery(3)——DOM操作
---恢复内容开始--- jQuery中的DOM操作 [DOM操作分类] DOM操作分为DOM Core(核心).HTML-DOM和CSS-DOM三个方面. DOM Core:任何一种支持DOM的 ...
- jquery 第二章
1.本章目标 css样式 选择器2.css样式 宽.高.边框.背景颜色.字体....... <html> <head> <style> div{ ...
- jQuery学习笔记(DOM操作)
DOM操作的分类 一般来说,DOM操作分为3个方面,即DOM Core.HTML-DOM和CSS-DOM. 1. DOM Core DOM Core并不专属于JavaScript,任何一种支持DOM的 ...
随机推荐
- 常用物联网应用层协议(1)——先说HTTP协议
概念 简介 HTTP是一个属于应用层的面向对象的协议,目前使用最为广泛的是HTTP1.1协议.当然,许多网站已经开始支持HTTP2.0,HTTP2复杂度高于HTTP1.1,我们先从HTTP1.1说起. ...
- 由Menu小项目所引发的对软件工程的思考
学习了孟老师的这几节课程,我学习了如何搭建一个简单的命令行menu小程序,从最简单的程序开始,一步步的根据软件工程的一般规律,进行逐步开发.完善,最终实现了一个比较通用的menu程序,可以让别的开发者 ...
- NB-IoT成为3GPP后会有哪些优势
NB-IoT无线接入的设计使用了很多LTE设计大的原则,并且得到了传统蜂窝网络和芯片组供应商的支持,使MBB取得了成功.NB-IoT采用与LTE(E-UTRA)相同的设计原则,尽管它使用单独的新载波, ...
- Vue+Antd搭配百度地图实现搜索定位等功能
前言 最近,在做vue项目的时候有做到选择地址功能,而原项目中又引入了百度地图,所以我就打算通过使用百度地图来实现地址搜索功能啦. 本次教程可能过于啰嗦,所以这里先放上预览地址供大家预览--点我预览, ...
- python使用zlib库压缩图片,使用ffmpeg压缩视频
python压缩图片.视频 图片压缩使用zlib库 视频压缩使用工具ffmpeg # ffmpeg -i 1.mp4 -r 10 -pix_fmt yuv420p -vcodec libx264 -p ...
- 妙用 Intellij IDEA 创建临时文件,Git 跟踪不到的那种
| 好看请赞,养成习惯 你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it ...
- CSS换行和省略号
换行 原地址:https://www.cnblogs.com/meowcool/p/10130103.html //强制不换行 div{ white-space:nowrap; } //自动换行 di ...
- RBAC设计前期设计
//s用户表 create table userinfo( id int(18) primaryk key auto_increment, username varchar(50) not null ...
- python编写实现抽奖器
这篇文章主要为大家详细介绍了python编写实现抽奖器,文中代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 # coding=utf-8 import sys import os ...
- ubuntu12.04 安装lamp <1>
安装:lamp: sudo apt-get install apache2 libapache2-mod-php5 php5-mysql mysql-server 删除mysql sudo apt-g ...