jq是一款伟大的,用原生js封装的,【操作DOM的类库】。他里面封装了大量的方法,基于这些方法我们可以快速的进行DOM操作和项目的开发
1.学习jq的方法
- 看API文档 http://jquery.cuishifeng.cn/
- 看相关书籍
- 做案例
- 学习jq的源码
v2.xxx
主要是为移动端的开发准备的,不在兼容低版本浏览器(例如:IE8及以下),配合出现的还有 jQuery mobile等UI库。但是,第二代版本在移动端方面的处理不如 Zepto.js
v3.xxx
也不再兼容IE低版本浏览器了,它从性能等方面都要比之前的强,但是生不逢时,此时正好是angular / vue / react这种框架崛起的时代,大家已经不再基于操作DOM的思想开发了,JQ也就慢慢退出舞台了
3.jq常用的方法
请参考jq的官方API文档: http://jquery.cuishifeng.cn/
4.jq源码剖析
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><script>// jq的最外层是一个自执行函数(function (global, factory) {"use strict" // 使用严格模式if (typeof module === "object" && typeof module.exports === "object") {// 支持CommonJs规范的执行这里,(比如在node.js里)// module.exports = global.document ?// factory(global, true) :// function (w) {// if (!w.document) {// throw new Error("jQuery requires a window with a document");// }// return factory(w);// };} else {// 走这里可以认为就是在浏览器里边运行// factory就是实参的函数,global就是windowfactory(global); // global--> window}}(typeof window !== "undefined" ? window : this, function (window, noGlobal) {var deletedIds = [];var slice = deletedIds.slice;var concat = deletedIds.concat;var push = deletedIds.push;var indexOf = deletedIds.indexOf;var class2type = {};var toString = class2type.toString;var hasOwn = class2type.hasOwnProperty;var support = {};var version = "1.11.3";var jQuery = function (selector, context) {return new jQuery.fn.init(selector, context);};// jq的是一个类,并且给jq加了一个私有属性,期属性值也是当前jq类的原型jQuery.fn = jQuery.prototype = {jquery: version, // jq的版本constructor: jQuery, // 给jq的原型进行重定向,手动补全constructortoArray: function () { // jq的类数组转数组方法return slice.call(this);},get: function (num) { // 获取jq实例里的某一个具体的元素,或者将jq实例转为数组return num != null ?// Return just the one element from the set(num < 0 ? this[num + this.length] : this[num]) :// Return all the elements in a clean arrayslice.call(this);},each: function (callback, args) { // each方法在jQ的类的原型上和Jq自己身上都存在return jQuery.each(this, callback, args);},};var init = jQuery.fn.init = function (selector, context) {// 这里的代码就是jq的元素选择器}init.prototype = jQuery.fn;if (typeof noGlobal === "undefined") {window.jQuery = window.$ = jQuery;}}));// 检测当前对象是数组还是类数组// function isArraylike(obj) {// var length = "length" in obj && obj.length,// type = jQuery.type(obj);// if (type === "function" || jQuery.isWindow(obj)) {// return false;// }// if (obj.nodeType === 1 && length) {// return true;// }// return type === "array" || length === 0 ||// typeof length === "number" && length > 0 && (length - 1) in obj;// }// jq上的方法放到了两个位置上,一部分在jq类的原型上,一部分在jq自己身上// $() // 返回的是init的实例,但是init的原型是jquery的原型// 但是这块大家有没有疑惑,为什么他不直接 new jquery()呢,只是人家的更加简洁的写法而已// function Fn(){// return new Fn();// }// Fn()/*基于$执行创建出来的是jQ的实例,就可以调取jQ原型上的方法1、创建出来的实例是一个类数组2、$执行时支持传递三种不同的格式$('.box') jq选择器$('<div></div>') 创建jq实例版的元素$(js原生元素) 转化成jq的实例版的元素(因为只有这样才可以调用jq原型上的方法)原生js中的方法或属性和jq的方法或者不能相互调用把jq对象转化成js原生对象,直接获取即可(也可以用jq的get方法)eq(index)==> eq也是通过索引来获取某个元素,但是获取的是jq的实例3、$(function(){}) 等待页面中的DOM结构加载完成再执行函数,等价于 $(document).ready(function(){})*/// $(selector)selector==> 支持三种格式// 传字符串 --> $('.box') jq选择器// 传字符串 --> $('<div></div>')// var// _jQuery = window.jQuery,// _$ = window.$;// 转让$和jQuery的使用权// jQuery.noConflict = function (deep) {// if (window.$ === jQuery) {// window.$ = _$;// }// if (deep && window.jQuery === jQuery) {// window.jQuery = _jQuery;// }// return jQuery;// };//-------------------------------------------------------------------// extend()$.extend({}) // 向jq中继续扩展方法,这种写法,是吧方法扩展到jQ的对象上,一般是为了给类库增加更多的方法$.fn.extend(true,{}); // 这种是扩展到jQ的原型上,让jq的实例去调用$().extend()// 大家注意这个布尔值如果不穿或者传false,如果你写的方法名和jq内会的冲突了,以jq的为主不会覆盖,但是如果布尔值是true,那以你写的为主$.extend(true,{queryUrlParams:function(){}})$.queryUrlParams('xxxxxxx');/*分三部分去讲1、jq的基础实现原理2、jq里的一些简单的方法 get each eq jq的选择器3、jq的noConflict extend ready(类似于onload)*/</script></body></html>
5.jq选项卡
<div id="box"><ul id="navList"><li class="active">一</li><li>二</li><li>三</li></ul><div class="active">我们是一</div><div>我们是二</div><div>我们是三</div></div><script src="./jquery-1.11.3.js"></script><script>// let navList = document.querySelectorAll('#navList li');// let tabList = document.querySelectorAll('#box div');// for (let i = 0; i < navList.length; i++) {// navList[i].onclick = function(){// selected(i)// }// }// function selected(index){// for (var i = 0; i < navList.length; i++) {// navList[i].className = '';// tabList[i].className = '';// }// navList[index].className = 'active';// tabList[index].className = 'active';// }// $('#navList li').each(function(index,item){// console.log(item)// $(item).click(function(){console.log(1)})// })// // index:获取当前元素在所有兄弟中的位置的索引// $('#navList li').click(function(){// console.log($(this).index()) // 获取当前this所在位置的索引// $(this).addClass('active').siblings().removeClass('active');// $('#box div').eq($(this).index()).addClass('active').siblings().removeClass('active');// })$('#navList li').click(function () {$(this).addClass('active').siblings().removeClass('active').parent().nextAll().eq($(this).index()).addClass('active').siblings('div').removeClass('active');});</script>
6.购物车
<script>/*1、获取所有的i标签2、给每一个i标签绑定点击事件*/let $btns = $('.list i');let $infoEms = $('.info em'); // 获取下半部分里的所有em元素let $ems = $('.list em'); // 获取上部分所有的em元素let $strongs = $('.list strong');$btns.click(function(){let index = $(this).index() // 拿到当前元素在自己所有的兄弟姐妹中的索引let $count = $(this).siblings('em'); // 获取显示数量的em元素let num = parseFloat($count.html()); // 获取当前em的内容let $strong = $count.siblings('span').find('strong'); // 获取素有的strong元素let price = parseFloat($strong.eq(0).html()) // 获取当前商品的单价// console.log($strong)if(index == 0) {// 点击的减号num-- ;num<0?num = 0:null; //}else {// 点击的加num++};$count.html(num); // 把数量设置回去$strong.eq(1).html(num*price+'元'); // 把小计设置回去computed();})function computed(){let allCount = 0; // 初始化一个累加数量的变量let allPrice = 0; // 初始化一个累加总计的变量let ary = [0]; // 初始化一个存储商品单价的数组// 循环上半部分所有的em元素$ems.each(function(index,item){// 把每一个em元素的内容累加到allCountallCount+=parseFloat($(item).html());});$strongs.each(function(index,item){// 如果strong元素的索引为偶数那就是单价那个元素,如果是奇数那就是小计那个元素if(index%2===1){// 把所有的小计元素的内容累加到allPrice里allPrice+=parseFloat($(item).html())}else {// 如果当前单价对应的小计不为位0,那就把单价push到ary数组里,用来一会在里面获取最大的单价if(parseFloat($(item).next('strong').html()) !== 0){ary.push(parseFloat($(item).html()))}}})// 以下三局就是把内容重新放回页面的元素中$infoEms.eq(0).html(allCount);$infoEms.eq(1).html(allPrice);$infoEms.eq(2).html(Math.max(...ary));/*1、获取所有的strong标签2、循环所有的strong标签3、判断当前strong的索引,如果是奇数,那就是小计的那个标签*/}</script>
