jQuery微整理
jQuery
无意间想到jQuery之前的辉煌,想一想还没有好好整理过呢。正好趁着国庆期间,稍微整理一些想到的点,那就开始吧!!!
jQuery入口函数
// 第一种: 简单易用。
$(function () {
... // 此处是页面 DOM 加载完成的入口
}) ;
// 第二种: 繁琐,但是也可以实现
$(document).ready(function(){
... // 此处是页面DOM加载完成的入口
});
- 等着 DOM 结构渲染完毕即可执行内部代码,不必等到所有外部资源加载完成,jQuery 帮我们完成了封装。
- 相当于原生 js 中的 DOMContentLoaded。
- 不同于原生 js 中的 load 事件是等页面文档、外部的 js 文件、css文件、图片加载完毕才执行内部代码。
- 更推荐使用第一种方式。
jQuery中的顶级对象$
- $是 jQuery 的别称,在代码中可以使用 jQuery 代替,但一般为了方便,通常都直接使用 $ 。
- $是jQuery的顶级对象,相当于原生JavaScript中的 window。把元素利用$包装成jQuery对象,就可以调用jQuery 的方法。
jQuery对象和原生DOM对象
- 用原生 JS 获取来的对象就是 DOM 对象
- jQuery 方法获取的元素就是 jQuery 对象。
- jQuery 对象本质是: 利用$对DOM 对象包装后产生的对象(伪数组形式存储)。
注意点:
只有 jQuery 对象才能使用 jQuery 方法,DOM 对象则使用原生的 JavaScirpt 方法。
jQuery 对象和 DOM 对象转换
// 1.DOM对象转换成jQuery对象,方法只有一种
var box = document.getElementById('box'); // 获取DOM对象
var jQueryObject = $(box); // 把DOM对象转换为 jQuery 对象
// 2.jQuery 对象转换为 DOM 对象有两种方法:
// 2.1 jQuery对象[索引值]
var domObject1 = $('div')[0]
// 2.2 jQuery对象.get(索引值)
var domObject2 = $('div').get(0)
jQuery选择器
基础选择器
层级选择器
筛选选择器
jQuery设置样式
jQuery中常用的样式操作有两种:css()
和 设置类样式方法
css()
// 1.参数只写属性名,则是返回属性值
var strColor = $(this).css('color');
// 2. 参数是属性名,属性值,逗号分隔,是设置一组样式,属性必须加引号,值如果是数字可以不用跟单位和引号
$(this).css(''color'', ''red'');
// 3. 参数可以是对象形式,方便设置多组样式。属性名和属性值用冒号隔开, 属性可以不用加引号
$(this).css({ "color":"white","font-size":"20px"});
设置类样式方法
// 1.添加类
$("div").addClass("active");
// 2.删除类
$("div").removeClass("active");
// 3.切换类
$("div").toggleClass("active");
注意点:
1、作用等同于以前的 classList,可以操作类样式, 注意操作类里面的参数不要加点。
2、原生 JS 中 className 会覆盖元素原先里面的类名,jQuery 里面类操作只是对指定类进行操作,不影响原先的类名。
jQuery效果
- 显示隐藏:show() / hide() / toggle() ;
- 划入画出:slideDown() / slideUp() / slideToggle() ;
- 淡入淡出:fadeIn() / fadeOut() / fadeToggle() / fadeTo() ;
- 自定义动画:animate() ;
注意点:
动画或者效果一旦触发就会执行,如果多次触发,就造成多个动画或者效果排队执行。
jQuery提供另一个方法,可以停止动画排队:stop(),动画时建议加上stop()
- 自定义动画:animate()
jQuery属性操作
jQuery 常用属性操作有三种:prop()
/ attr()
/ data()
;
prop()
元素固有属性值:元素本身自带的属性,比如 < a> 元素里面的 href ,比如 < input> 元素里面的 type。
注意点:
prop() 除了普通属性操作,更适合操作表单属性:disabled / checked / selected 等。
attr()
元素自定义属性值:用户自己给元素添加的属性,称为自定义属性。 比如给 div 添加 index =“1”
注意点:
attr() 除了普通属性操作,更适合操作自定义属性。(该方法也可以获取 H5 自定义属性)
data()
数据缓存:data() 方法可以在指定的元素上存取数据,并不会修改 DOM 元素结构。一旦页面刷新,之前存放的数据都将被移除。
注意点:
同时,还可以读取 HTML5 自定义属性 data-index ,得到的是数字型。
<body>
<a href="http://www.helloworld.cn" title="标题">你好,世界!</a>
<input type="checkbox" name="" id="" checked>
<div index="1" data-index="2">我是div</div>
<span>123</span>
<script src="./jquery.js"></script>
<script>
$(function () {
//1. element.prop("属性名") 获取元素固有的属性值
console.log($("a").prop("href")); // http://www.helloworld.cn/
$("a").prop("title", "你好");
$("input").change(function () {
console.log($(this).prop("checked"));
});
console.log($("div").prop("index")); // undefined
// 2. 元素的自定义属性 我们通过 attr()
console.log($("div").attr("index")); //1
$("div").attr("index", 4);
console.log($("div").attr("index")); //4
console.log($("div").attr("data-index")); //2 (字符串型)
// 3. 数据缓存 data() 这个里面的数据是存放在元素的内存里面
$("span").data("uname", "fqniu");
console.log($("span").data("uname")); // fqniu
// 这个方法获取data-index h5自定义属性 第一个 不用写data- 而且返回的是数字型
console.log($("div").data("index")); // 2 (数字型)
})
</script>
</body>
jQuery文本属性值
jQuery的文本属性值常见操作有三种:html()
/ text()
/ val()
;
分别对应JS中的 innerHTML 、innerText 和 value 属性。
注意点:
html() 可识别标签,text() 不识别标签;
val() 操作表单内的值,或者获取表单的值;
jQuery元素操作
jQuery 元素操作主要是用jQuery方法,操作标签的遍历、创建、添加、删除等操作。
遍历
jQuery 隐式迭代是对同一类元素做了同样的操作。 如果想要给同一类元素做不同操作,就需要用到遍历。
注意点:
此方法用于遍历 jQuery 对象中的每一项,回调函数中元素为 DOM 对象,想要使用 jQuery 方法需要转换。
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<script>
$(function() {
// 如果针对于同一类元素做不同操作,需要用到遍历元素(类似for,但是比for强大)
var sum = 0;
var arr = ["red", "green", "blue"];
// 1. each() 方法遍历元素
$("div").each(function(i, domEle) {
// 回调函数第一个参数一定是索引号 可以自己指定索引号号名称
// console.log(i);
// 回调函数第二个参数一定是 dom 元素对象,也是自己命名
// console.log(domEle); // 使用jQuery方法需要转换 $(domEle)
$(domEle).css("color", arr[i]);
sum += parseInt($(domEle).text());
})
console.log(sum);
// 2. $.each() 方法遍历元素 主要用于遍历数据,处理数据
// $.each($("div"), function(i, ele) {
// console.log(i);
// console.log(ele);
// });
// $.each(arr, function(i, ele) {
// console.log(i);
// console.log(ele);
// })
$.each({
name: "fqniu",
age: 25
}, function(i, ele) {
console.log(i); // 输出的是 name age 属性名
console.log(ele); // 输出的是 andy 18 属性值
})
})
</script>
</body>
创建
// 动态创建的节点
$("<div></div>")
添加
内部添加
// 把内容放入到匹配元素的最后面 类似于原生的appendChild
element.append("内容")
// 把内容放入到匹配元素的最前面
element.prepend("内容")
外部添加
// 把内容放入到目标元素后面
element.after("内容")
// 把内容放入到目标元素前面
element.before("内容")
注意点:
内部添加元素,生成后,他们是父子关系
外部添加元素,生成后,他们是兄弟关系
删除
// 删除匹配的元素(本身)
element.remove()
// 删除匹配元素集合中国所有的子节点
element.empty()
// 清空匹配的元素内容
element.html("")
注意点:
remove()删除元素本身;
empty()和html(" ")作用等价,都可以删除元素里面的内容,只不过html()还可以设置内容;
克隆
var cloneEle = $(this).clone(true); // 有true为深克隆!
<button class="cloneBtn">点击克隆</button>
//需求:点击克隆按钮,然后克隆一个新的按钮
$(".cloneBtn").on("click", function () {
var cloneEle = $(this).clone(true);
$(this).after(cloneEle);
})
注意点:
克隆会把克隆元素里面的事件也一起克隆过来;
jQuery 尺寸、位置操作
jQuery 尺寸操作
jQuery 位置操作
jQuery的位置操作主要有三个: offset()
、position()
、scrollTop()/scrollLeft()
jQuery 事件注册
// 语法:
element.事件(function () {})
// 例如:
$("div").click(function(){
// 事件处理程序
})
// 比如 mouseover 、 mouseout、blur、focus、change、keydown、resize、scroll
流氓网站的点击事件
<button class="box2">按钮</button>
<button class="box2">按钮</button>
<button class="box2">按钮</button>
//流氓网站的点击事件 第一次点击跳转到流氓网站 第二次点击跳转到正常的网站!
//清空带有小名的点击事件
var flag = false;
$(".box2").on("click.lm", function () {
console.log("跳转到流氓网站");
flag = true;
})
$(".box2").on("click", function () {
// console.log(flag);
if (!flag) { //为真(就是标志位的另一种状态)
console.log("跳转到正常网站");
} else {
//清除流氓网站的点击事件
$(".box2").off("click.lm");
flag = false;
}
})
jQuery 事件处理
- on(): 用于事件绑定,目前最好用的事件绑定方法
- off(): 事件解绑
- trigger() / triggerHandler(): 事件触发
事件处理 on() 绑定事件
因为普通注册事件方法的不足,jQuery又创建了多个新的事件绑定方法bind() / live() / delegate() / on() 等,其中最好用的是: on()
1、可以绑定多个事件,多个处理事件处理程序
$("div").on({
mouseover:function(){},
mouseout:function(){},
click:function(){}
})
$("div").on("mouseover mouseout", function(){
$(this).toggerClass("active")
})
2、事件委托操作;
$("ul").on("click", "li", function(){
alert("我是li")
})
3、动态创建的元素;
// 动态创建的元素,click() 没有办法绑定事件, on()可以给动态生成的元素绑定事件
$("div").on("click", "p", function(){
alert("动态生成的元素p")
})
$("div").append($("<p>我是动态生成的p标签</p>"))
事件处理 off() 解绑事件
当某个事件上面的逻辑,在特定需求下不需要的时候,可以把该事件上的逻辑移除,这个过程我们称为事件解绑。jQuery 为我们提供 了多种事件解绑方法:die() / undelegate() / off() 等,甚至还有只触发一次的事件绑定方法 one(),在这里我们重点讲解一下 off() ;
$("p").off() // 解绑p元素所有的事件处理函数
$("p").off("click") // 解绑p 元素上面的点击事件 后面的foo是监听函数名
$("ul").off("click", "li") // 解绑事件委托
// 如果有事件只想触发一次,可以使用one() 来绑定事件
事件处理 trigger() 自动触发事件
有些时候,在某些特定的条件下,我们希望某些事件能够自动触发, 比如轮播图自动播放功能跟点击右侧按钮一致。可以利用定时器自动触发右侧按钮点击事件,不必鼠标点击触发。由此 jQuery 为我们提供了两个自动触发事件 trigger() 和 triggerHandler() ;
// trigger()
element.click() // 第一种简写形式
element.trigger("type") // 第二种自动触发模式
// triggerHandler()
element.triggerHandler(type) // 第三种自动触发模式
注意点:
triggerHandler(type)
这个特别的方法将会触发指定的事件类型上所有绑定的处理函数。但不会执行浏览器默认动作,也不会产生事件冒泡。
这个方法的行为表现与trigger类似,但有以下三个主要区别:
-
第一,他不会触发浏览器默认事件。
-
第二,只触发jQuery对象集合中第一个元素的事件处理函数。
-
第三,这个方法的返回的是事件处理函数的返回值,而不是据有可链性的jQuery对象。此外,如果最开始的jQuery对象集合为空,则这个方法返回 undefined 。
jQuery 事件对象
jQuery 对DOM中的事件对象 event 进行了封装,兼容性更好,获取更方便,使用变化不大。事件被触发,就会有事件对象的产生。
element.on(events, [selector], function(event){})
阻止默认行为:event。preventDefault()或者 return false
阻止冒泡:event.stopPropagation()
jQuery 拷贝对象
jQuery 多库共存
实际开发中,很多项目连续开发十多年,jQuery版本不断更新,最初的 jQuery 版本无法满足需求,这时就需要保证在旧有版本正常运行的情况下,新的功能使用新的jQuery版本实现,这种情况被称为,jQuery 多库共存。
解决方案:
1、把里面的$ 统一改为jQuery ,比如jQuery(“div”)
2、jQuery变量规定新的名称:$.noConflict()var xxx = $.noConflict ;
<script>
$(function() {
// 让jquery 释放对$ 控制权 让用自己决定
var xxx = jQuery.noConflict();
console.log(xxx("span"));
})
</script>
场景:
-
我们一直在使用
jQuery
,都没有什么问题 -
但是如果有一天,我们需要引入一个别的插件或者库的时候
-
人家也向外暴露的是
获取 jQuery
-
那么,我们的
jQuery
就不能用了 -
那么这个时候,
jQuery
为我们提供了一个多库并存的方法// 这个方法可以交还 jQuery 命名的控制权 jQuery.noConflict() // 上面代码执行完毕以后 $ 这个变量就不能用了 // 但是 jQuery 可以使用 console.log($) // undefined console.log(jQuery) // 可以使用
-
完全交出控制权
// 这个方法可以交并且传递一个 true 的时候,会完全交出控制权 jQuery.noConflict(true) // 上面代码执行完毕以后 $ 这个变量就不能用了 // jQuery 这个变量也不能用了 console.log($) // undefined console.log(jQuery) // undefined
-
更换控制权
// 可以用一个变量来接受返回值,这个变量就是新的控制权 var aa = jQuery.noConflict(true) // 接下来就可以把 aa 当作 jQuery 向外暴露的接口使用了 aa('div').click(function () { console.log('我被点击了') })
JQuery 的插件扩展
jQuery 插件
jQuery 插件常用的网站:
-
jQuery 插件库 http://www.jq22.com/
-
jQuery 之家 http://www.htmleaf.com/
jQuery 插件使用步骤:
-
引入相关文件(jQuery 文件 和 插件文件)
-
复制相关html、css、js (调用插件)。
jQuery链式调用原理
jQuery的这种管道风格的DSL链式代码,总的来说:
- 节约JS代码;
- 所返回的都是同一个对象,可以提高代码的效率。
通过简单扩展原型方法并通过return this的形式来实现跨浏览器的链式调用。利用JS下的简单工厂方法模式,来将所有对于同一个DOM对象的操作指定同一个实例。
这个原理就超简单了,如下代码:
dQuery().init().name()
分解:
d = dQuery();
d.init()
d.name()
dQuery.prototype = {
init: function() {
return this;
},
name: function() {
return this
}
所以我们如果需要链式的处理,只需要在方法内部方法当前的这个实例对象this就可以了,因为返回当前实例的this,从而又可以访问自己的原型了,这样的就节省代码量,提高代码的效率,代码看起来更优雅。
但是这种方法有一个问题是: 所有对象的方法返回的都是对象本身,也就是说没有返回值,所以这种方法不一定在任何环境下都适合。
jQuery中的同用特性:
- 所有的API是函数
- 复杂数据传递都是使用对象的形式!
jQuery的请求
发送 ajax 请求
-
发送 get 请求
// 直接使用 $.get 方法来发送一个请求 /* 参数一: 请求地址 参数二: 请求时携带的参数 参数三: 请求成功的回调 参数四: 返回的数据类型 */ $.get('./ajax.php', { id: 10 }, function (res) { console.log(res) }, 'json')
-
发送 post 请求
// 直接使用 $.post 方法来发送一个请求 /* 参数一: 请求地址 参数二: 请求时携带的参数 参数三: 请求成功的回调 参数四: 返回的数据类型 */ $.post('./ajax.php', { id: 10 }, function (res) { console.log(res) }, 'json')
-
综合发送 ajax 请求
// 使用 $.ajax 方法 // 只接受一个参数,是一个对象,这个对象对当前的请求进行所有的配置 $.ajax({ url: './ajax', // 必填,请求的地址 type: 'GET', // 选填,请求方式,默认是 GET(忽略大小写) data: {}, // 选填,发送请求是携带的参数 dataType: 'json', // 选填,期望返回值的数据类型,默认是 string async: true, // 选填,是否异步,默认是 true success () {}, // 选填,成功的回调函数 error () {}, // 选填,失败的回调函数 cache: true, // 选填,是否缓存,默认是 true context: div, // 选填,回调函数中的 this 指向,默认是 ajax 对象 status: {}, // 选填,根据对应的状态码进行函数执行 timeout: 1000, // 选填,超时事件 })
-
发送一个 jsonp 请求
// 使用 $.ajax 方法也可以发送 jsonp 请求 // 只不过 dataType 要写成 jsonp $.ajax({ url: './jsonp.php', dataType: 'jsonp', data: { name: 'fqniu', age: 25 }, success (res) { console.log(res) }, jsonp: 'cb', // jsonp 请求的时候回调函数的 key jsonpCallback: 'fn' // jsonp 请求的时候回调函数的名称 })
全局 ajax 函数
- 全局的
ajax
函数我们也叫做ajax
的钩子函数 - 也就是在一个
ajax
的整个过程中的某一个阶段执行的函数 - 而且每一个
ajax
请求都会触发
ajaxStart
-
任意一个请求在 开始 的时候就会触发这个函数
$(window).ajaxStart(function () { console.log('有一个请求开始了') })
ajaxSend
-
任意一个请求在 准备 send 之前 会触发这个函数
$(window).ajaxSend(function () { console.log('有一个要发送出去了') })
ajaxSuccess
-
任意一个请求在 成功 的时候就会触发这个函数
$(window).ajaxSuccess(function () { console.log('有一个请求成功了') })
ajaxError
-
任意一个请求在 失败 的时候就会触发这个函数
$(window).ajaxError(function () { console.log('有一个请求失败了') })
ajaxComplete
-
任意一个请求在 完成 的时候就会触发这个函数
$(window).ajaxComplete(function () { console.log('有一个请求完成了') })
ajaxStop
-
任意一个请求在 结束 的时候就会触发这个函数
$(window).ajaxStop(function () { console.log('有一个请求结束了') })
load
load(url, [data], [callback])
一般情况下 ajax 都是去请求接口的; 获取json数据; 在极个别情况下我们需要用ajax加载html字符串;
作用:就是请求html文件,插入到DOM之中!
- 参数1: url: 待载入页面的URL地址;
- 参数2: data: 待发送 Key / value 参数。 对象的形式!
- 参数3: callback: 载入成功时回调函数。
注意点: url为必须传递的参数, 其他的都是可选参数!
<div class="container"></div>
$(function () {
//需求:发起一个简单的load请求
$(".container").load("./php/load.html")
//结果:就是在 container 这个容器中 请求到路径中的html文件,擦好人到这里面!
})
jQuery之深浅克隆
存储机制
- 栈 — 队列方式,先进后出
- 堆 — 映射关系,栈里面存储复杂对象的值(而复杂对象的地址存储在栈之中,最后指向堆!)
深浅克隆
- 浅克隆: — 就是对象长得一样,地址也是一样
- 深克隆: — 就是对象长得一样,地址却是不一样
jQuery.extend()
- 作用1:就是合并对象
- 作用2:深克隆对象
$(function () {
// 浅克隆
var a = {};
var b = a;
console.log(a === b); //true
//为true的原因:就是a存储的一个对象地址,然后把这个地址赋值给了b,两者都是相同的地址,因此为true!
// 深克隆
var a1 = {}
var a2 = {}
console.log(a1 === a2); //false
//为false的原因:就是a1存储的是一个对象的地址,a2存储的是另一个对象的地址
var b1 = {
obj: {
arr: [1, 3, 5],
ax: 20
}
}
// IE8 + 的浏览器 --- 对象的深克隆 黑科技;
var b3 = JSON.parse(JSON.stringify(b1));
console.log(b1 === b3); //false
// 1. 把对象变成了纯字符串; 2. 用解析器把字符串重新解析成对象;
// 深克隆的克隆方式:
var c = $.extend(true, {}, b1)
console.log(b1 === c); //false
// jQuery.extend()
// 作用: 函数用于将一个或多个对象的内容合并到目标对象。一般用于默认参数的设置,后面是传递的参数!最后合并到目标对象之中!
// 参数: 参数1:为目标对象(后面的对象,将会被合并到这边) 参数2-。。。:准备被合并的对象
// 优化代码结构 :
// 面向对象 : 构造函数 + 原型对象;
function Factory(){}
// Factory.prototype.init = function(){}
// Factory.prototype.bindEvent = function(){}
// Factory.prototype.xxx = function(){}
// 使用 $.extend 优化;
$.extend( Factory.prototype , {
init : function(){
},
bineEvent : function(){}
})
var fac = new Factory();
console.log(fac);
})
补充原生的深浅克隆实现:
// 1. 遍历数组赋值
<script type="text/javascript">
var a = [1,2,3,4];
var b = [];
for(var i = 0; i < a.length; i++){
b.push(a[i])
}
console.log(b) //[1,2,3,4]
</script>
//2. slice方法
/*
(1) 作用:从一个数组中截取出新的数组
(2) 格式:数组名.slice(begin,end);
begin表示开的下标
end表示结束的下标,但是在截取时不包含结束下标对应的元素
(3) 注意:
原数组不受影响
如果只设置一个参数,即begin,那么会从begin截取到最后
如果不写参数,那么slice方法可以实现数组的复制
*/
<script type="text/javascript">
var arr1 = [1, 2, 3, 4]
var arr2 = arr1.slice(0)
console.log(arr2) //[1,2,3,4]
arr1 = [4, 3, 2, 1]
console.log(arr2) //[1,2,3,4]
</script>
// 3. assign实现深浅克隆
// 浅克隆
<script type="text/javascript">
var obj = { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
var arr = [1,2,3];
var copy = Object.assign([], arr);
console.log(copy); // [1,2,3]
// 深克隆
let arr1 = [1,2,3,4,5];
let arr2 = JSON.parse(JSON.stringify(arr1));
console.log(arr2) //[1,2,3,4,5]
</script>
//4.concat方法
/*
(1) 作用:拼接数组
(2) 格式:数组名1.concat(数组名2); 就是指将数组2拼接在数组1后面
(3) 返回值:为拼接后的新的数组
(4) 注意:原数组不受影响
*/
<script type="text/javascript">
let arr1 = [1,2,3,4];
let arr2 = arr1.concat()
arr2[1] = 5
console.log(arr1, arr2) //[1,2,3,4], [1,5,3,4]
</script>