来源 http://caibaojian.com/es6 一、Set和Map 1、Set:ES6提供的新的数据结构,类似于数组,但是成员的值都是唯一的,没有重复的。 2、Map:ES6提供的新的数据结构,类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。 二、Proxy(内部拦截) 1、Proxy实例(Proxy必须针对Proxy实例进行操作,否则Proxy不起作用) (1)实例一 var obj = {}; var thisObj = new Proxy(obj, { get: function (target, key, receiver) { console.log(obj === target); //true if (key === 4) { return 5; } return 6; }, set: function (target, key, value, receiver) { return Reflect.set(target, key, value, receiver); }, has: function (target, key) { if (key[0] === "c") { return false; } return key in target; }, }); thisObj.count = 1; console.log(thisObj.count); console.log("count" in thisObj); (2)实例二 var fn=function(){ }; var thisFn = new Proxy(fn,{ construct:function(target,args){ console.log(target===fn)//true return { value: args[0]*10 }//construct方法返回的必须是一个对象,否则会报错。 } }); console.log(new thisFn(1)); console.log(Reflect.construct(thisFn,[1])); 2、Proxy配置 (1)get(target, propKey, receiver) 拦截对象属性的读取,比如proxy.starFunction 和 proxy['starFunction']。 如果propKey属性部署了读取函数,则读取函数的this绑定receiver(一个对象)。 (2)set(target, propKey, value, receiver) 拦截对象属性的设置,比如proxy.starFunction = v或proxy['starFunction'] = v,返回一个布尔值。 (3)has(target, propKey) 拦截propKey in proxy的操作,以及对象的hasOwnProperty方法,返回一个布尔值。 (4)deleteProperty(target, propKey) 拦截delete proxy[propKey]的操作,返回一个布尔值。 (5)ownKeys(target) 拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy),返回一个数组。该方法返回对象所有自身的属性,而Object.keys()仅返回对象可遍历的属性。 (6)getOwnPropertyDescriptor(target, propKey) 拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。 (7)defineProperty(target, propKey, propDesc) 拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。 (8)preventExtensions(target) 拦截Object.preventExtensions(proxy),返回一个布尔值。 (9)getPrototypeOf(target) 拦截Object.getPrototypeOf(proxy),返回一个对象。 (10)isExtensible(target) 拦截Object.isExtensible(proxy),返回一个布尔值。 (11)setPrototypeOf(target, proto) 拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。 如果目标对象是函数,那么还有两种额外操作可以拦截。 (12)apply(target, object, args) 拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...) 。 (13)construct(target, args) 拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。 三、Reflect(外部操纵) 1、Reflect概述 Reflect对象与Proxy对象一样,也是ES6为了操作对象而提供的新API。Reflect对象的设计目的有这样几个。 (1) 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。 (2) 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。 (3) 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。 (4)Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。 2、Reflect方法 (1)Reflect.get(target, name, receiver) 查找并返回target对象的name属性,如果没有该属性,则返回undefined。 如果name属性部署了读取函数,则读取函数的this绑定receiver。 var antzone = { webName: "蚂蚁部落", url:"www.softwhy.com", get age() { return this.myAge; } } console.log(Reflect.get(antzone, "age", { myAge: 4 })); (2)Reflect.set(target, name, value, receiver) 设置target对象的name属性等于value。如果name属性设置了赋值函数,则赋值函数的this绑定receiver。 (3)Reflect.has(obj, name) 等同于name in obj。 (4)Reflect.deleteProperty(obj, name) 等同于delete obj[name]。 (5)Reflect.construct(target, args) 等同于new target(...args),这提供了一种不使用new,来调用构造函数的方法。 function func1(a, b, c) { this.sum = a + b + c; } const args = [1, 2, 3]; const object1 = new func1(...args); const object2 = Reflect.construct(func1, args); console.log(object2.sum);//expected output: 6 console.log(object1.sum);//expected output: 6 (6)Reflect.getPrototypeOf(obj) 读取对象的__proto__属性,对应Object.getPrototypeOf(obj)。 (7)Reflect.setPrototypeOf(obj, newProto) 设置对象的__proto__属性,对应Object.setPrototypeOf(obj, newProto)。 (8)Reflect.apply(fun,thisArg,args) 等同于Function.prototype.apply.call(fun,thisArg,args)。一般来说,如果要绑定一个函数的this对象,可以这样写fn.apply(obj, args),但是如果函数定义了自己的apply方法,就只能写成Function.prototype.apply.call(fn, obj, args),采用Reflect对象可以简化这种操作。 console.log(Reflect.apply(Math.floor, undefined, [1.75]));// expected output: 1 四、ts泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。 1、泛型函数的类型与非泛型函数的类型没什么不同,只是有一个类型参数在最前面,像函数声明一样. function createArray<T>(length: number, value: T): Array<T> { let result: T[] = []; for (let i = 0; i < length; i++) { result[i] = value; } return result; } createArray<string>(3, 'x'); // ['x', 'x', 'x'] 2、泛型参数的默认类型 function createArray<T = string>(length: number, value: T): Array<T> { let result: T[] = []; for (let i = 0; i < length; i++) { result[i] = value; } return result; } 3、泛型接口 interface CreateArrayFunc { <T>(length: number, value: T): Array<T>; } let createArray: CreateArrayFunc; createArray = function<T>(length: number, value: T): Array<T> { let result: T[] = []; for (let i = 0; i < length; i++) { result[i] = value; } return result; } createArray(3, 'x'); // ['x', 'x', 'x'] 4、也可以把泛型参数提前到接口名上 interface CreateArrayFunc<T> { (length: number, value: T): Array<T>; } let createArray: CreateArrayFunc<any>; createArray = function<T>(length: number, value: T): Array<T> { let result: T[] = []; for (let i = 0; i < length; i++) { result[i] = value; } return result; } createArray(3, 'x'); // ['x', 'x', 'x'] 5、泛型类 TypeScript的核心原则之一是对值进行类型检查。 在TypeScript里,接口的作用就是为这些类型命名和为代码定义契约。 https://www.tslang.cn/docs/handbook/interfaces.html class GenericNumber<T> { zeroValue: T; add: (x: T, y: T) => T; } let myGenericNumber = new GenericNumber<number>(); myGenericNumber.zeroValue = 0; myGenericNumber.add = function(x, y) { return x + y; }; 6、泛型约束 interface Lengthwise { length: number; } function loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length); return arg; } 7、对泛型进行约束,只允许这个函数传入那些包含 length 属性的变量 我们定义一个接口来描述约束条件。 创建一个包含 .length属性的接口,使用这个接口和extends关键字来实现约束。 五、Iterator(遍历器) //以下遍历器(迭代器)模拟代码 function createIterator(items) { var i = 0; return { next: function() { var done = (i >= items.length); var value = done ? undefined : items[i++] ; return { done: done, value: value }; } }; } var iterator = createIterator([1, 2, 3]); console.log(iterator.next()); // "{ value: 1, done: false }" console.log(iterator.next()); // "{ value: 2, done: false }" console.log(iterator.next()); // "{ value: 3, done: false }" console.log(iterator.next()); // "{ value: undefined, done: true }" JavaScript原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6又添加了Map和Set。这样四种数据结构只要部署了Iterator接口,就是”可遍历的“(iterable)。ES6规定,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。 const obj = { [Symbol.iterator] : function () { return { next: function () { return { value: 1, done: true }; } }; } }; 上面代码中,对象obj是可遍历的(iterable),因为具有Symbol.iterator属性。 六、Generator 函数(生成器) 1、Generator函数有两个特征 (1)function关键字与函数名之间有一个星号; (2)函数体内部使用yield(即“产出”)语句,定义不同的内部状态。 2、调用Generator函数后,该函数并不执行,返回的是一个指向内部状态的指针对象,也就是遍历器对象(Iterator Object)。 3、调用遍历器对象的next方法,使得指针移向下一个状态。 4、也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield语句(或return语句)为止。 5、换言之,Generator函数是分段执行的,yield语句是暂停执行的标记,而next方法可以恢复执行。 6、示例1 function* starFunction(one) { console.log(one); var two = 2 * (yield one + 1); //6,7 console.log("1111111111111111111111111111111"); console.log(two); var three = yield 2 * two; //4,8 console.log("2222222222222222222222222222222"); console.log(three); var four = yield 2 * three; //2,4 console.log("3333333333333333333333333333333"); console.log(four); console.log(one, two, three, four); console.log("4444444444444444444444444444444"); return one + two + three + four; } var useFunction = starFunction(6); console.log(useFunction.next()); console.log(useFunction.next(2)); console.log(useFunction.next(2)); console.log(useFunction.next(2)); next第1次执行,返回“第1个yield语句的计算结果”; next第2次执行,返回“第2个yield语句的计算结果”,传入的参数取代“第1个yield语句的计算结果”; next第3次执行,返回“第3个yield语句的计算结果,传入的参数取代“第2个yield语句的计算结果””; next第n次执行时,如果没有第n个yield语句,那就一直执行到return,如果没有return,就返回undefined。 7、示例2 来源:http://www.ruanyifeng.com/blog/2015/04/generator.html Fetch模块返回的是一个Promise对象,因此要用then方法调用下一个next方法。 var fetch = require('node-fetch'); function* generatorFn(){ var urlA = 'https://api.github.com/users/githubA'; var urlB = 'https://api.github.com/users/githubB'; yield fetch(urlA); yield fetch(urlB); } var generatorOne = generatorFn(); var result = generatorOne.next(); result.value.then(function(data){ return data.json(); }).then(function(data){ generatorOne.next(data); }); 8、如果想要第一次调用next方法时,就能够输入值,可以在Generator函数外面再包一层。如下 function wrapper(generatorFunction) { return function (num) { let generatorObject = generatorFunction(num); generatorObject.next(); return generatorObject; }; } const wrapped = wrapper(function* starFunction(a) { console.log(a); var b = 2 * (yield a + 1); //6,7 console.log("1111111111111111111111111111111"); console.log(b); var c = yield 2 * b; //4,8 console.log("2222222222222222222222222222222"); console.log(c); var d = yield 2 * c; //2,4 console.log("3333333333333333333333333333333"); console.log(d); console.log(a, b, c, d); console.log("4444444444444444444444444444444"); return a + b + c + d; }); var b = wrapped(6); console.log(b.next(2)); console.log(b.next(2)); console.log(b.next(2)); 七、async(then)函数及其内部的await(promise)指令 (1)async函数可以包含await指令,该指令会暂停原异步函数的执行,并等待右侧Promise返回结果; (2)若 Promise 正常处理,其回调resolve函数的参数作为 await 表达式的值; 示例一: function thisPromise(x) { return new Promise(function (resolve) { //此处把x(加工后)作为参数向后台发送请求 setTimeout(function () { //此处获得后台返回结果并加工为x+50,通过resolve暴露出去 resolve(x + 50); }, 500); }); } async function thisAdd(x) { //var thisAdd = async function(x) { var a = await thisPromise(20); var b = await thisPromise(30); //此处可以加工a,b return x + a + b; //这个结果作为参数传给后面的then参数 } thisAdd(10).then(function (total) { console.log(total); //1 秒后出打印结果 }); 八、promise内部机制模拟和校验 //1、promise模拟 function custPromise(callback) { this.value = null; this.status = "pending"; this.cbArray = []; callback(this.resolve.bind(this)); } custPromise.prototype.then = function (success) { var that = this; if (this.status == "pending") {//success为异步函数时 return new custPromise(function (resolve) {//同步将then参数放在实例参数里 that.cbArray.push(function () {//push参数就是下面的callbackIn var result = success(that.value);//success来自哪个实例,that.value就来自哪个实例 if (result instanceof custPromise) { result.then(resolve); } else { resolve(result); //上面result.then(resolve)执行时,产生了这里的resolve } }); }); } if (this.status == "resolve") {//success为同步函数时 return new custPromise(function (resolve) { var result = success(that.value); if (result instanceof custPromise) { result.then(resolve); } else { resolve(result); } }); } }; custPromise.prototype.resolve = function (value) { this.value = value; this.status = "resolve"; if (this.cbArray.length > 0) { this.cbArray.forEach(function (callbackIn) { callbackIn(); //callbackIn就是上面的push参数 }); } }; //2、promise验证 //第1个上实例的自身参数为异步时,它的then参数为异步或同步的情况 //第1个上实例的自身参数为同步时,它的then参数为异步或同步的情况 new custPromise(function (resolve) { setTimeout(function () { resolve(1); }, 2000); }) .then(function (value) { return new custPromise(function (resolve) { setTimeout(function () { resolve(value * 2); }, 1000); }); }) .then(function (value) { return new custPromise(function (resolve) { setTimeout(function () { resolve(value * 2); }, 1000); }); }) .then(function (value) { return new custPromise(function (resolve) { resolve(value * 2); }); }) .then(function (value) { return new custPromise(function (resolve) { resolve(value * 2); }); }) .then(function (value) { return value * 2; }) .then(function (value) { console.log(value) }); 九、多态 同一操作作用于不同的对象上面,可以产生不同的执行结果。比如你说“叫”,鸭子听了会发出“嘎嘎声”,鸡听了会发出“咯咯声”。 1、非多态代码示例 var makeSound = function(animal) { if(animal instanceof Duck) { console.log('嘎嘎嘎'); } else if (animal instanceof Chicken) { console.log('咯咯咯'); } } var Duck = function(){} var Chiken = function() {}; makeSound(new Chicken()); makeSound(new Duck()); 2、多态的代码示例 var makeSound = function(animal) { animal.sound(); } var Duck = function(){} Duck.prototype.sound = function() { console.log('嘎嘎嘎') } var Chiken = function() {}; Chiken.prototype.sound = function() { console.log('咯咯咯') } makeSound(new Chicken()); makeSound(new Duck()); 十、原型链 (1)函数类或对象类或普通函数_的原型(直接找原型,简单) (2)函数类或对象类或普通函数或普通对象_所在类的原型(先找类再找原型,复杂) (3)函数类或对象类或普通函数或普通对象_所在类的原型_之所在类的原型...(先找类再找原型,复杂) var obj = {} function fn(){} 1、函数类或对象类或普通函数的原型 (1)Object.prototype={}; (2)Function.prototype={}; (3)fn.prototype = {}; 2、函数类或对象类或普通函数或普通对象_所在类的原型 (1)Function.__proto__ === Function.prototype (2)Object.__proto__ === Function.prototype (3)fn.__proto__ === Function.prototype; (4)obj.__proto__ === Object.prototype; 3、函数类或对象类或普通函数或普通对象_所在类的原型_之所在类的原型... (1)Function.__proto__.__proto__ === Function.prototype.__proto__ === Object.prototype (2)Object.__proto__.__proto__ === Function.prototype.__proto__ === Object.prototype (3)Function.__proto__.__proto__.__proto__ === Function.prototype.__proto__.__proto__ === Object.prototype.__proto__ === null (4)Object.__proto__.__proto__.__proto__ === Function.prototype.__proto__.__proto__ === Object.prototype.__proto__ === null 4、new出来的对象 function AAA() {} AAA.prototype.bbb = function () {}; var aaa = new AAA(); console.log(aaa.__proto__ === AAA.prototype); console.log(aaa.__proto__.__proto__ === Object.prototype); //https://www.jianshu.com/p/686b61c4a43d 附:原型链继承 Drag.prototype.__proto__ = EventEmitter.prototype;//这是更安全的继承方法,一般在Node里都是采用这种方式实现继承。IE不支持 Drag.prototype = new EventEmitter;//相对这种方式来说,上边的写法更安全 十一、Object.create(proto[, propertiesObject]) 1、参数 (1)proto:新创建对象的原型对象 (2)propertiesObject:新创建对象的(可)枚举属性 2、返回值 (1)一个新对象,带着指定的原型对象和属性 3、实例 var myProto={proto:1}; var youProto={ enumer:{ enumerable: true, value: "custom" } }; var thisProto=Object.create(myProto,youProto) console.log(thisProto) console.log(thisProto.enumer) console.log(thisProto.__proto__===myProto) 十二、Object.defineProperty() 1、语法:Object.defineProperty(myObject, prop, descriptor) 2、参数: (1)myObject要定义或修改的属性所在的对象 (2)prop要定义或修改的属性的名称 (3)descriptor要定义或修改的属性的描述符,包含A、configurable,B、enumerable,C、数据描述符(2项)或存取描述符(2项) 3、返回值:myObject 4、作用:定义或者修改myObject的属性 5、configurable,默认为false。为true时,prop可删,描述符可改 6、enumerable,默认为false。为true时,prop可枚举 7、数据描述符: (1)value,属性值,可以是数值、对象、函数等,默认为 undefined。 (2)writable,默认为false。为true时,prop可重写。 8、存取描述符: (1)get,属性的getter函数,当访问prop时,会调用此函数,该函数的返回值被用作属性值,默认为undefined。 (2)set,属性的setter函数,当属性值被修改时,会调用此函数,该函数接受1个参数,默认为undefined。 示例一 var myObj = { thisValue: 5 }; Object.defineProperty(myObj, "key", { configurable: false, enumerable: false, value: function () { console.log(this); return this.key+1; }, writable: true, //value: "myValue", //writable: false, }); myObj.key = 5; console.log(myObj.key); 示例二 var myObj = { thisValue: 5 }; Object.defineProperty(myObj, "key", { configurable: false, enumerable: false, get: function () { console.log(this); return key+2; }, set: function (value) { console.log(this); key = value + 1; }, }); myObj.key = 5; console.log(myObj.key); 附、vue响应式相关代码 function def(obj, key, val, enumerable) { Object.defineProperty(obj, key, { configurable: true, enumerable: !!enumerable, value: val, writable: true, }); } Object.defineProperty(obj, key, { configurable: true, enumerable: true, get: function reactiveGetter() { var value = getter ? getter.call(obj) : val; return value; }, set: function reactiveSetter(newVal) { var value = getter ? getter.call(obj) : val; dep.notify(); }, }); 十三、与parseFloat()相关 原文地址:https://yq.aliyun.com/ziliao/92498?spm=5176.8246799.blogcont.20.cUDmIE 1、Number() (1)如果是Boolean值,true和false值将分别被转换为1和0。 (2)如果是数字值,只是简单的传入和返回。 (3)如果是null值,返回0。 (4)如果是undefined,返回NaN。 (5)如果是字符串: A、如果字符串中只包含数字时,将其转换为十进制数值,忽略前导0 B、如果字符串中包含有效浮点格式,如“1.1”,将其转换为对应的浮点数字,忽略前导0 C、如果字符串中包含有效的十六进制格式,如“0xf”,将其转换为相同大小的十进制数值 D、如果字符串为空,将其转换为0 E、如果字符串中包含除上述格式之外的字符,则将其转换为NaN (6)如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,然后再依照前面的规则转换返回的字符串值。 例: var num1 = Number("Hello world"); //NaN var num2 = Number(""); //0 var num3 = Number("0000011"); //11 2、parseInt() (1)处理整数的时候parseInt()更常用。parseInt()函数在转换字符串时,会忽略字符串前面的空格,知道找到第一个非空格字符。 (2)如果第一个字符不是数字或者负号,parseInt() 就会返回NaN,同样的,用parseInt() 转换空字符串也会返回NaN。 (3)如果第一个字符是数字字符,parseInt() 会继续解析第二个字符,直到解析完所有后续字符串或者遇到了一个非数字字符。 (4)parseInt()方法还有基模式,可以把二进制、八进制、十六进制或其他任何进制的字符串转换成整数。 (5)基是由parseInt()方法的第二个参数指定的,所以要解析十六进制的值,当然,对二进制、八进制,甚至十进制(默认模式),都可以这样调用parseInt()方法。 例: var num1 = parseInt("AF",16); //175 var num2 = parseInt("AF"); //NaN var num3 = parseInt("10",2); //2 (按照二进制解析) var num4 = parseInt("sdasdad"); //NaN 3、parseFloat() (1)与parseInt() 函数类似,parseFloat() 也是从第一个字符(位置0)开始解析每一个字符。也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。 (2)也就是说,字符串中第一个小数点是有效的,而第二个小数点就是无效的了,它后面的字符串将被忽略。 (3)parseFloat() 只解析十进制,因此它没有第二个参数指定基数的用法 (4)如果字符串中包含的是一个可解析为正数的数(没有小数点,或者小数点后都是零),parseFloat() 会返回整数。 例: var num1 = parseFloat("123AF"); //123 var num2 = parseFloat("0xA"); //0 var num3 = parseFloat("22.5"); //22.5 var num4 = parseFloat("22.3.56"); //22.3 var num5 = parseFloat("0908.5"); //908.5 parseInt() 和parseFloat() 的区别在于: parseFloat() 所解析的字符串中第一个小数点是有效的,而parseInt() 遇到小数点会停止解析,因为小数点并不是有效的数字字符。 parseFloat() 始终会忽略前导的零,十六进制格式的字符串始终会被转换成0,而parseInt() 第二个参数可以设置基数,按照这个基数的进制来转换。 4、customParseInt:字符串类型的数字转换成数字类型的数字、数字类型的数字和字符串类型的非数字保持原样 function customParseInt(num) { var tempNum = parseInt(num); if (typeof tempNum === 'number' && !isNaN(tempNum)) { return tempNum; } return num; }; console.log(customParseInt(1)) console.log(customParseInt("1")) console.log(customParseInt("闪烁")) 4、整型范围 (1)有负号整型范围 Int8:[-128:127] Int16:[-32768:32767] Int32:[-2147483648:2147483647] Int64:[-9223372036854775808:9223372036854775807] (2)无负号整型范围 UInt8:[0:255] UInt16:[0:65535] UInt32:[0:4294967295] UInt64:[0:18446744073709551615] 十四、jQuery实现鼠标跟随 所谓鼠标跟随,一般就是指鼠标移到哪张图片上,那该张图片的放大图片就会出现,并且放大图片会随着鼠标在该张图片上移动而移动。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> * { margin: 0; padding: 0; } img { border: none; } .box { 660px; position: relative; } .box .mark { position: absolute; 400px; height: 300px; display: none; } .box .mark img { 100%; } .box img { 150px; float: left; margin: 5px; } </style> </head> <body> <div class="box" id="box"> <img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=e95708d565639d99576ae7cb00729334" realImg="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=5328802dc943fc046e109f70359add0a" alt=""/> <img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=9e5459a7c0098c27adf4bdd73889caa9" realImg="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=846f4d1987765dc4cfd5a06fcdd2dcc1" alt=""/> <img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=3cd1c8e301007f0c94850139ac79cb5a" realImg="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=747bf3f7092ebd2b0bf9fcd27e28bbe5" alt=""/> <img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=f391169b2cf678aa6fd253cf40d9821d" realImg="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=fec8d2f20fad1f28d540337a831e89d0" alt=""/> <div id="mark" class="mark"><img src="" alt=""/></div> </div> <script src="http://s0.kuaizhan.com/res/skin/js/lib/jquery-2.0.3.min.js"></script> <script> //1.鼠标移入哪张图片的时候,让他对应的大图显示; //2.当鼠标在img中移动的时候,大图跟着走; var $box=$('.box'); var $aImg=$box.children('img'); var $mark=$('.mark'); var $offset=$box.offset(); $aImg.mouseover(function(){ //当鼠标移入每张图片的时候,让mark显示,并且,让mark里面的img标签,src属性值为当前这个图片的realImg属性上拿到的值; $mark.show().find('img').attr('src',$(this).attr('realImg')); }); $aImg.mousemove(function(e){ //拿鼠标的x坐标,减去$box距离body的left位置; var left= e.clientX-$offset.left+10; var top= e.clientY-$offset.top+10; $mark.css({left:left,top:top}) }); $aImg.mouseout(function(){ $mark.hide(); }) </script> </body> </html> 十五、jQuery实现文档树效果 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> * { margin: 0; padding: 0; list-style: none; } .box { 250px; height: auto; padding: 20px; background: lightgrey; margin: 0 auto; } .box li { line-height: 30px; /*注意:height没有被设置,可以根据实际需要自动调整*/ position: relative; } .box li em { position: absolute; left: 0; top: 7px; 16px; height: 16px; background-image: url(""); background-size: 100%; cursor: pointer; } .box li em.open { background-image: url(""); background-size: 100%; } .box li span { padding-left: 20px; /*因为span前面的em已经绝对定位,脱离文档流了,所以span的左边界直达 li*/ } .box ul { display: none; } .two { margin-left: 20px; } .three { margin-left: 40px; } .four { margin-left: 40px; } /*ul.box下的li显示,其中有折叠的li加em; ul.box下的ul隐藏,其内部的li是没法显示的*/ </style> </head> <body> <ul class="box"> <li><em></em><span>第一级第一个</span> <ul class="two"> <li><span>第二级第一个</span></li> <li><em></em><span>第二级第二个</span> <ul class="three"> <li><em></em><span>第三级第一个</span> <ul class="four"> <li><span>第四级第一个</span></li> <li><span>第四级第二个</span></li> </ul> </li> <li><span>第三级第二个</span></li> </ul> </li> <li><em></em><span>第二级第三个</span> <ul class="three"> <li><span>第三级第一个</span></li> <li><span>第三级第二个</span></li> </ul> </li> </ul> </li> <li><em></em><span>第一级第一个</span> <ul class="two"> <li><span>第二级第一个</span></li> <li><em></em><span>第二级第二个</span> <ul class="three"> <li><em></em><span>第三级第一个</span> <ul class="four"> <li><span>第四级第一个</span></li> <li><span>第四级第二个</span></li> </ul> </li> <li><span>第三级第二个</span></li> </ul> </li> </ul> </li> </ul> <script src="http://s0.kuaizhan.com/res/skin/js/lib/jquery-2.0.3.min.js"></script> <script> /*思路: * 1.让前面有em的span加上小手效果; * 2.点击span or em的时候,看他父容器下是否有ul,如果有,让其显示,否则,隐藏 * */ var $box=$('.box'); var $aSpan=$box.find('span'); //1.让前面有em的span加上小手效果; $aSpan.each(function(index,item){ //if($(item).prev().length){ $(item).css('cursor','pointer');};思路1: $(item).prev('em').next('span').css('cursor','pointer'); //思路2: }); //2.点击span or em的时候,看他父容器下是否有ul,如果有,让其显示,否则,隐藏 $box.click(function(e){ //当点击的事件源是em or span的时候,我们看其父级下是否有ul // 如果有:展开让其闭合,闭合就让其展开; if(e.target.tagName.toLowerCase()=='em' || e.target.tagName.toLowerCase()=='span'){ var $parent=$(e.target).parent(); var $ul=$parent.children('ul'); if($ul){ if($ul.css('display')=='block'){//展开,让其闭合 //当闭合的时候,让当前容器下,所有的em都移除open,所有的ul都隐藏; $parent.find('ul').hide(); $parent.find('em').removeClass('open'); }else{ //闭合让其展开 $ul.show(); $parent.children('em').addClass('open'); } } } }) </script> </body> </html> 十六、jQuery方法扩展(选项卡) 在jQuery上扩展方法,通过点击实现选项卡的切换。本实例在jQuery的类上扩展,即$.extend({chooseCard:函数}),通过$.chooseCard('#box')调用;有别于$.fn.extend({chooseCard:函数})扩展,通过$().chooseCard('#box')调用。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> * { margin: 0; padding: 0; } .box { 312px; border: 2px red solid; margin: 0 auto; } ul { overflow: hidden; } li { list-style: none; background: red; float: left; 100px; height: 30px; line-height: 30px; text-align: center; border: 2px solid orange; } li.on { background: green; } .box div { background: green; display: none; 312px; height: 200px; font-size: 30px; border-top: none; } .box div.on { display: block; } </style> </head> <body> <div class="box" id="box"> <ul> <li class="">中国</li> <li>日本</li> <li>韩国</li> </ul> <div class="on">中国是老大</div> <div>日本是老二</div> <div>韩国是老三</div> </div> <script src="http://s0.kuaizhan.com/res/skin/js/lib/jquery-2.0.3.min.js"></script> <script> (function ($) { $.extend({ chooseCard: function (idStr) { var $box = $(idStr); var $li = $box.find("li"); console.log($li); var $aDiv = $box.find("div"); $li.click(function () { $(this) .css({ height: "32px", "border-bottom": "none" }) .siblings("li") .css({ height: "30px", "border-bottom": "2px solid orange" }); $(this).addClass("on").siblings("li").removeClass("on"); $aDiv .eq($(this).index()) .addClass("on") .siblings("div") .removeClass("on"); }); }, }); })(jQuery); </script> <script> $(function(){ $.chooseCard('#box'); }) </script> </body> </html> 十七、复选框全选、反选(<input type='checkbox'/>) (1)获取复选框状态:$("#allSelect").prop("checked") (2)改变复选框状态:$("#allSelect").prop("checked",false) (3)翻转复选框状态:item.checked = !item.checked; (4)判断复选框是否被选中:if ($(this).is(':checked')) (5)找到所有被选中的复选框:myDiv.find("input:checked"); (6)获取所有复选框:$("#single input:checkbox")或$("#single input[type=checkbox]"); (7)获取所有被选中的复选框:$("#single input:checkbox:checked")或$("#single input[type=checkbox]:checked"); <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.9.0/jquery.js"></script> </head> <body> <span>全选</span><input type="checkbox" id="allSelect"><br> <span>反选</span><input type="checkbox" id="reverseSelect"> <div id="single"> <input type="checkbox"> <input type="checkbox"> <input type="checkbox"> <input type="checkbox"> </div> </body> </html> <script> $("#allSelect").click(function () { $("#single") .children() .each(function (index, item) { item.checked = $("#allSelect").prop("checked"); }); $("#reverseSelect").prop("checked", false); }); $("#reverseSelect").click(function () { $("#single") .children() .each(function (index, item) { item.checked = !item.checked; }); $("#reverseSelect").prop("checked", true); singleInput(); }); $("#single") .children() .click(function (index, item) { $("#reverseSelect").prop("checked", false); singleInput(); }); function singleInput() { if ( $("#single input:checkbox:checked").length == $("#single input:checkbox").length ) { $("#allSelect").prop("checked", true); } else { $("#allSelect").prop("checked", false); } } </script> 十八、jQuery中的width()、innerWidth()、outerWidth()的区别总结 (1)width():其宽度范围是所匹配元素的宽度width; (2)innerWidth():其宽度范围是所匹配元素的宽度width+padding; (3)outerWidth():其宽度范围是所匹配元素的宽度width+padding+border; (4)outerWidth(true)其宽度范围是所匹配元素的宽度width+padding+border+margin; 十九、jQuery实例无new构建 (function(window) { var jQuery = function(selector, context) { return new jQuery.prototype.init(selector, context, rootjQuery); }, jQuery.prototype = { init: function( elem, options, prop, end, easing, unit ) { this.elem = elem; this.prop = prop; this.easing = easing || jQuery.easing._default; this.options = options; this.start = this.now = this.cur(); this.end = end; this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); }, } jQuery.prototype.init.prototype = jQuery.prototype; })(window); 二十、业务逻辑 (1)不同的项目有不同的功能,不同的功能需要不同的实现,实现这些核心功能的代码就叫业务逻辑。 (2)实现核心功能的代码就叫业务逻辑。