标识符命名规则:
*1.由数字、字母、下划线、美元符($)组成
*2.首字符不能是数字
*3.不用使用保留字和关键字
元素对象
*1.通过id获取对象
* document.getElementById('id');
*2.通过css选择器获取元素
* document.querySelector('.box')
* document.querySelector('#div + span') // + > ~
* document.querySelectorAll('div')
鼠标事件
* 点击事件 onclick
* 鼠标移入事件 onmouseover
* 鼠标移除事件 onmouseout
什么是函数?
- 封装的任意条的语句,代表一个功能的组成;
- 声明一个函数: 关键字 function 函数名( ){….};
- 函数的调用
1.函数名( )
2.通过事件调用 - *匿名函数
匿名函数不能单独存在,可以通过事件调用;
cssText
div.style.cssText=”
获取属性需要注意的事项
1.属性操作获取的颜色不一定准确
// console.log(box.style.background);
2.属性的读取,读取的都是行间的样式,如果行间没有设置,那么是获取不到的。
// console.log(box.style.display);
3.图片的src属性,获取到的是一个绝对路径
console.log(img.src);
innerHTML
innerHTML 表示元素标签内的 html 内容的
元素.innerHTML 获取某个元素内的html内容
元素.innerHTML = '新的内容'; 修改某个元素内的html内容
innerHTML 获取到的内容和操作的内容都是字符串
字符串
字符串:由0个或者多个字符组成的字符序列,并且放在一对引号或者反引号中。
2.length 用来获取某个字符串的长度的,它只能读不能写 字符串.length
字符串一但创建,就不能修改。
简单的字符串操作:字符串的拼接 运算符 +
当做加法运算的时候,如果表达式里面有一个是字符串,那么不做加和操作,而是做字符串的拼接操作。而且在数学运算符号中,只有+是这样的。
反引号用法:
// leaveMessage.innerHTML += <li> <div><span> ${val} </span> </div>
</li>;
classList
// 元素.classList 它是元素的所有的class的一个集合
// 元素.classList.add('class的名字');
// 元素.classList.remove('class的名字');
// console.log(box.classList);
// box.classList.add('box2');
// box.classList.add('box3');
//
// box.classList.remove('box2');
* 比较操作符
== 只比较值,而不比较数据类型
=== 严格比较,不仅仅比较值,而且还比较类型
> 大于号、 >= 大于等于
< 小于号、 <= 小于等于
! 取反、非
布尔
*他们操作的结果,最终返回的要么是一个 true,要么是一个false,这两个值叫做 布尔值
布尔值,仅有两个值 true 和 false
true: 代表真
false: 代表假
true 和 'true', 以及 false 和 'false' 不是一回事
// console.log(!false);
// console.log(!!(1 > 2));
// 判断的基本语法
if(条件){
条件成立时候执行的代码(这里面的代码只有当条件成立的时候才会执行)
}
if(条件1){
条件1成立时候的代码
}else{
如果条件1不成立那么执行这里面的代码
}
if(条件1){
条件1成立的代码
}else if(条件2){
条件2成立的代码
}else if(...){
....
}else{
上面条件都不成立的时候
}
只要有一个条件成立,那么后面的条件即使成立也不会执行。
三元操作符
三元操作符又叫做三元表达式
// 条件成立吗 ? 成立就执行这句话 : 条件不成立执行的代码;
// var age = 19;
//
// age >= 18 ? alert(1) : alert(2);
//
// if(age >= 18){
// alert(1)
// }else{
// alert(2);
// }
// 三元表达式一般情况下多用在赋值操作
// var a = 2 > 1 ? 0 <= 2 ? 3 : 4 : 5;
// var age = 19;
// age >= 18 ? alert(1) : ''; // 如果不想做什么也要写个空字符串
如果发现眼下的已知条件解决不了当下的问题,那么首先想到一件事,回过头去声明一个变量。(创建一个开关)
自增自减
* 自增和自减
* 自增就是某个数值+1,自减就是某个数值-1
*
* 自增分为前自增和后自增,在单独使用的时候没有任何区别。
* 只有当在运算或者在其他表达式中的时候,那么前自增是自己先加1,然后再参与运算,后自增先参与运算,自己再加1
for套for注意
当循环嵌套循环的时候,两个循环不能用同一个变量
二位数组知识点
一维数组
var arr1 = [1, 2, 3, 4];
二维数组(非对称数组和对称数组)
var arr1 = [ // 非对称二维数组
['a', 'b', 'c'],
['d', 'e'],
[1, 2, 3, 4, 5]
];
var arr2 = [ // 对称二维数组
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
var arr3 = [
[1], // 第一次循环 1
[2, 3], // 第二次循环 2
[4, 5, 6] // 第三次循环 3
];
// 第几次循环就循环几次(99乘法表)
选项卡
选项卡原来:用一组元素控制另一组元素;
一组元素控制另一组元素的时候首先想到的是自定义属性;
这个自定义属性要控制方去添加而不是被控制的一族元素
js中的数据类型
基本数据类型
Undefined 未定义
Null 空
Number 数字 (Infinity & -Infinity)
boolean 布尔
string 字符串
symbol 字符类型
引用数据类型
object(对象)
-{}
-dom元素
-[]数组
-function
-js里除了基本数据类型,剩下的都是对象。
使用typeof 要判断的数据 来区分数据类型
基本数据类型和引用数据类型的区别
var a=1;
var b=a;
a=3;
console.log(a); //3
console.log(b); //1
var arr1=[1,2];
var arr2=arr1;
arr[0]=10;
console.log(arr1); //[10,2]
console.log(arr2); //[10,2]
引用数据类型复制的不是数据而是引用
---------------------------------
console.log([]===[]); //false
console.log([1,2,3]===[1,2,3]) //false
var fn1=function (){};
var fn2=function (){};
console.log(fn1===fn2); //false
如何区分数据类型
console.log(typeof 1); //'number'
console.log(typeof 'abc'); //'string'
console.log(typeof undefined) //'undefined'
console.log(typeof null); //'object'
console.log(typeof true); //'boolean'
console.log(typeof (function fn(){})) //'function'
console.log(typeof [1,2]); //'object'
console.log(typeof document.querySelector('.box'); //'object'
// 如何判断某个数据是不是数字?
// var a = 1;
// if(typeof a === 'number'){ // typeof 的返回结果都是一个字符串
// console.log('Is a number');
// }
undefined:
1.如果如果变量声明,但没有初始化,那么默认储存的值就是undefined
2.如果一个对象的属性名不存在,你去访问它,也是undefined
3.一个函数,如果没有返回值,那么执行之后的结果是undefined
null类型:
1.只有一个值,那就是null,代表空
undefined 实际上是派生自null,所以在比较值的时候是相等的。
// var a;
// console.log(a); // undefined
// console.log(window.abc); // undefined
// var arr1 = [1, 2, 3]
// console.log(arr1[100]);
// console.log(typeof null); 'object'
// 返回 'object' 是JS的一个bug
// 凡是 在内存中 转换成 二进制 前3位是0的,使用typeof判断都会返回'object',null代表空,它转成二进制 全是 0,所以也返回 'object'
// console.log(undefined == null); // true
// console.log(undefined === null); // false
// var o1 = null; // 代表把这变量初始化为一个空对象引用
//
// o1 = []; // 将来要保存为要给对象的时候
// 判断一个数据是不是null的时候不能使用typeof
var n = null;
if(n === null){
console.log('Is a null');
}
函数也是一种数据
typeof 函数,返回的不是 'object' 而是 'function'
* - 函数也是对象,但是它是一个可以执行的对象,所以很有必要和普通的对象做一个区分。
函数声明和函数表达式
函数声明可以直接调用 如:fn1();
函数表达式不能在变量声明之前去使用
判断是否为函数
if(typeof xxx==='function'){
console.log('is a function')
}
函数表达式的名字
var fn = function ffn(){
// alert(3);
console.log(ffn); // 这个函数名字,只能在这个函数内部可以使用。
};
fn(); // 3
// ffn();
字典数据类型
对象类型的数据结构又成为字典类型的数据结果,和数组非常类似,但是不同于数组的是,数组的 key 只能是 从 0 开始的 数字,而对象数据结构的 key 可以是 任意的 字符串
定一个对象使用 {}, 对象主要包括 属性 和 方法,每个属性或者方法都由 键值对 (key 和 value) 组成
自定义一个对象
var obj1 = {};
var obj2 = {
a: 1,
'abc': [1, 2, 3],
'b-2': 'str',
fn1: function(){alert(1)},
fn2(){alert(2)}
};
// console.log(obj2['b-2']);
//
// obj2.a = 10;
// console.log(obj2);
// 调用对象里面的方法
// obj2.fn1();
// obj2.fn2();
// console.log(obj2.length) undefined
// console.log(typeof {});
var obj3 = {
'0': 'a',
'1': 'b',
'2': 'c',
'3': 'd',
length: 4
};
// for(var i=0; i<obj3.length; i++){
// console.log(obj3[i]);
// }
// console.log(obj3['0']);
// console.log(obj3[0]);
// ------------------------------------
// <div class="box">123</div>
// var div = {
// tagName: 'div',
// types: {
// class: 'box'
// },
// innerHTML: '123'
// };
数据类型转换
JS里面进行数据类型转换的时候只能转换成以下三种
Number (数字)
String (字符串)
Boolean (布尔值)
字符串
字符串:由0个或者多个字符组成的集合,并且放到单引号、双引号、或者反引号中
属性:length 代表字符串的长度,length属性只能读取,不能写,字符串一旦创建,不能修改
将其他数据类型转换成字符串的方法
-String(要转换的数据)
-要转换的数据.toString()
-undefined和null不能用这个方法
String(); String 是js系统的内置函数
// console.log(String(undefined)); // 'undefined'
// console.log(String(null)); // 'null'
// console.log(String(123)); // '123'
// function fn(){}
// console.log(String(fn)); // 'function fn(){}'
// console.log(String([1, 2, 3])); // 1,2,3
// console.log(String({a: 1, b: 2})); // [object Object]
// console.log(String(document.querySelector('.box')));
// ----------------------------------------------
// ele.toString();
// console.log(10..toString());
// console.log(undefined.toString()); // 报错
// console.log(null.toString()); // 报错
// console.log(true.toString()); // 'true'
var obj = {a: 1};
console.log(obj.toString()); // [object Object]
// ------------------------------------------------
// 像这样直接去调用某个方法进行转换的称为显示类型转换
// 隐式数据类型转换,是JS引擎帮你自动做的事情。
// console.log('a' + 1); // 'a1'
// console.log('1' * 2); // 2
// console.log('abc' * 1); // NaN
// console.log('123' * 1); // 123 // 最快的把数字字符串转换为数字
// console.log(100 + ''); // '100'
布尔值:
true 真
false 假
转布尔值的方法:
Boolean(要转换的数据)
// console.log(Boolean(0)); // false
// console.log(Boolean(NaN)); // false
// 除了 0 和 NaN 其它的转布尔值 都是 true
// console.log(Boolean(undefined)); // false
// console.log(Boolean(null)); // false
// 除了空字符串转布尔值是假的其他的都是真的
// console.log(Boolean('')); // false
// console.log(Boolean(' ')); // true
// 所有的对象都是真的
// -------------------------------------------
// var i = 0;
// if(i){
// alert(1)
// }
// var arr = [];
//
// if(arr){
// console.log(11111);
// }
// 取反的返回值(结果)一定是个布尔值
// 最快的转布尔值的方法: !!数据
// console.log(!![]); // true
// -------------------------------------------------
// console.log({}.toString() === {}.toString()); // true
// console.log([] == ![]); // true
// [] == ![] ==> [] == false == 会优先向数字类型转换
逻辑与或非
* 逻辑与 &&
* 逻辑或 ||
* 逻辑非 ! 返回值一定是一个布尔值
// 当在赋值的时候
// 逻辑与 会一直向后找,直到找到第一个转布尔值为false的值,如果没有就是最后一个值
// 逻辑或 会一直向后找,直到找到第一个转布尔值为true的值,如果没有就返回最后一个
类数组
类数组:可以使用索引取到对应的值,也具有length属性,但是length属性只可以读取,不可以修改。
// var str = 'abcd';
// console.log(str[0]);
// console.log(str[1]);
// console.log(str[str.length - 1]);
// 字符串也是类数组
// for(var i=0; i<str.length; i++){
// console.log(str[i]);
// }
// ----------------------------------------------
var str = 'skadhasjd1dsad2dasdf3fgg';
for(var i=0; i<str.length; i++){
if(str[i]*1 === str[i]*1){
console.log(str[i]);
}
}
函数
函数:可以对任意多条语句进行封装,代表一个功能的整体。
函数的分类:
-函数声明
-函数表达式
-匿名函数
函数是一种特殊格式的对象,所以函数也是一种数据。
一个完整的函数定义:
关键字 function fn函数名(参数1,参数2...){
代码1;
代码2;
return;
}
function add(a,b){
console.log(a+b)
}
函数表达式
var fn = function(){
console.log(1);
};
//fn(); 必须在声明之后调用这个函数
函数表达式(匿名函数)
(function(){
console.log(2);
})(); //函数表达式的自执行
(function fn(){
console.log(2);
})
fn();
!function (){
console.log(2);
}();
~function (){
console.log(2);
}();
函数的参数以及使用
function add(a,b){//a b叫做形参,形式上的参数,可有可无
// var a: ==>当我调用函数的时候 a=1;
// var b: ==>当我调用函数的时候 b=2;
console.log(a);
console.log(b);
console.log(a + b);
}
add(1, 2); // a b叫做实参,就是实际传入函数的参数
add();
add(3, 4);
// 实参和形参是一一对应的。
arguments 对象
arguments:函数内部存在的一个对象,是一个类数组,它的作用是:保存实参的集合
function fn1(){
console.log(arguments)
}
fn1(1,2,3);
求2个数字加和
function add1(){
var num1=arguments[0];
var num2=arguments[2];
console.log(num1+num2);
}
add1(1,2);
求任意多个数字的家和
function add(){
var arg=arguments,num=0;
for(var i=0; i<arg.length;i++){
num+=arg[i];
}
console.log(num);
}
add(1,2,3); //6
add(4,5,6,7)//22
函数的返回值
函数中的 return
这个return你写不写,它都在那里,静静的看着你
function fn(){
console.log(1);
return[1,2,3];
}
fn(); //1
console.log(fn); // 1
console.log(fn()); //[1,2,3]
var ret=fn();
console.log(ret);
// -----------------------------------------
// function out(){
// return function (a, b){
// console.log(a + b);
// }
// }
// var f = out(); // f = function (a, b){console.log(a + b);}
// var r = f(1, 2); // 3
// console.log(r); // undefined
// out()(1,2); // 3
var a = 1;
function fn1(){
a++; // 2
console.log(++a); //3
return --a; //
console.log(a+=2);
}
console.log(fn1()); // 3 2
console.log(a); // 2
作用域
浏览器运行js脚本至少包含三个部分:
编译器:负责把js代码编译成计算机可以识别的数据(语法分析和词法分析)
js引擎:负责对编译后的代码进行逐行运行。
作用域:用来管理标识符的一套规则,它规定了每个标识符可以在范围内被访问和修改
// console.log(a); // 报错
// ---------------------------------------
//
// console.log(a); // undefined 01010101010
//
// var a = 2; // 010101010110
// console.log(a); // 2;
// ---------------------------------------
// a = 3;
//
// console.log(a); // 3
//
// var a = 2;
//
// console.log(a); // 2
// --------------------------------------
// fn();
//
// function fn(){
// console.log(1);
// }
// --------------------------------------
// console.log(fn); // 函数
//
// function fn(){
// console.log(2);
// }
//
// var fn = 1; // 1
//
// console.log(fn);
//
// console.log(fn); // 1
// -------------------------------------------------------
作用域:主要包括全局作用域和局部作用域(通常指函数作用域)
函数作用域:凡是在函数内部,都属于函数作用域。
全局作用域:出了函数作用域,那么就属于全局作用域
var a=10;
function fn(){
//一旦进入一个新的作用域的时候,首先要进行预解析
var b=30;
console.log(b);
}
fn();
console.log(a);
作用域链:规定了标识符的查找顺序,只能由内向外查找,而不是由外向内查找。
// function fn(){
// var a = 1;
// console.log(a); // 1
// a++; // 2
//
// fn();
// }
// console.log(a);
// 函数内部声明的变量,在函数外部是访问不到的。
---------------------------------------------------------
// var a = 1;
//
// function fn(){
// console.log(a); // undefined
// var a = 2;
// console.log(a++); // 2
// }
//
// fn();
//
// console.log(a); // 1
// -------------------------------------------------
// var a = 1;
//
// function fn(){
// console.log(a); // 1
//
// a = 3;
//
// console.log(++a); // 4
// console.log(b);
// }
//
// fn();
// console.log(a); // 4
// --------------------------------------------------
var a = 1;
var b = 5;
function fn1(){
console.log(++a); // NaN
var a = 10;
fn2();
function fn2(){
console.log(a++); // 10
console.log(b); // 5
}
}
fn1();
console.log(a); // 1
闭包
栈:LIF0==>last in first out 后进先出,凡是储存在栈中的变量,都会被操作系统自动释放,在js中通常储存局部变量
堆:它是一种树状的数据结构。在js当中,引用数据类型,通常会储存在堆中。堆中的数据不会被自动释放。
垃圾回收器:对不再引用的数据进行回收(释放内部空间)
静态区:在js当中,全局变量都存放在这个区域。不会被垃圾回收器回收
// var a = 1;
//
// function qq(){
// var b = 2;
// }
//
// qq();
//
// console.log(b);
// ----------------------------------------------
// var ret;
//
// function fn1(){
// var a = 1;
// ret = function (){
// console.log(a++);
// }
// }
//
// fn1();
// ret(); // 1
// ret(); // 2
// ret(); // 3
// 闭包:函数就是闭包,但是通常是只函数嵌套函数。当一个函数可以记住它被声明的作用域,并且可以访问那个作用域里面的所有的标识符,就会形成闭包。
// ---------------------------------------------------------------
// function fn(){
// var a = 1;
// return function (){
// console.log(a++);
// }
// }
//
// var f = fn();
// f(); // 1
// f(); // 2
// f(); // 3
// f = f(); // 4
// f(); // 报错
// f = fn();
// f();
// -----------------------------------------------
var btns = document.querySelectorAll('button');
// for(var i=0; i<btns.length; i++){
// btns[i].index = i;
// btns[i].onclick = function (){
// alert(this.index);
// }
// }
for(var i=0; i<btns.length; i++){
(function (i){
btns[i].onclick = function (){
alert(i);
};
})(i);
}
获取计算后的样式
/**
* 浏览器实际显示元素的样式成为计算后的样式。
* 使用 getComputedStyle(ele).attr 来获取对应的样式
*/
var box = document.querySelector('.box');
console.log(getComputedStyle(box).top);
// 比如获取元素的宽度
// getComputedStyle(box).width ==> '200px'
// -----------------------------------------------
// 获取 transform 对应的样式
console.log(getComputedStyle(box).transform);
// matrix(0.707107, 0.707107, -0.707107, 0.707107, 0, 0)
// 获取的是一个 矩阵
for in 循环
for...in 循环式用来遍历对象的
for(var key in obj){
key 代表这个obj对象的属性名
对象每个数据对应的值:obj[key]
}
var obj={a:1,b:2,c:'abc'};
for(var item in obj){
console.log(item);//每个属性
console.log(obj[item]);//每个属性对应的值
}
var arr=['a','b','c','d','e','f']
// for(var key in arr){
console.log(key);
console.log(arr[key]);
}
// in操作符,可知道这个属性是否在这个对象当中
console.log('a' in arr); //true
console.log('x' in arr); //false
console.log('toString in arr') //ture
定时器
定时器分为两种:
重复型定时器:以指定的时间间隔,做同一件事情,只要不停止,一直做下去
延时型定时器:在指定的时间间隔后,做一件事情,只做一次
重复型定时器:
setInterval(fn,delay,arg1,arg2...)
fn:要做的事情;
delay:时间间隔(单位是ms) 1s=1000ms
arg1,arg2...: 如果fn有参数,这些代表fn的参数
返回值:当前定时器的编号(不同的浏览器返回的这个编号是不一样的)
html5的最新规范,规定了定时器最短时间间隔是4ms
// setInterval(function() {
// console.log(1);
// }, 1000);
function fn(n){
// console.log(n);
}
var t1 = setInterval(fn, 1000, 1);
var t2 = setInterval('fn(1)', 1000);
var t3 = setInterval('fn(1)', 1000);
var t4 = setInterval('fn(1)', 1000);
console.log(t1, t2, t3, t4);
延时型定时器
setTimeout(fn,delay,arg1,arg2)
参数和setInterval一样的,返回值也是当前定时器的编号;
function(){
console.log('hello');
}
setTimeout(fn,1000);
清除定时器
clearInterval(清除定时器编号)
clearTimeout清除定时器编号)
这个2个方法的参数,无论你给他什么样的数据类型,它都不会报错。
var n=0
var timer=setInterval(function(){
console.log(++n);
if(n>50){
clearInterval(timer);
}
},1000)
----------------------------------------------------
var timer2=setTimeout(function(){
console.log('hello');
},1000)
document.onclick=function(){
clearTimeout(timer2);
}
时间对象
时间对象:js里的时间对象是基于1970年1月1日00:00:00(格林威治时间)
创建时间对象:new Date();
单独使用new Date()那么代表你计算机当前系统的时间
//这个时间是你的代码读取的时候的时间,并且不会自动更新
var time=new Date();
console.log(time);
//时间对象分解
var now=new Date();
- now.getFullyear();
- now.getMonth();
- now.getDate();
- now.getHours();
- now.getMinutes();
- now.getSeconds();
- now.getMilliseconds();
* now.getTime();//timestamp,时间戳,获取的是1970年1月1日00:00:00到现在的毫秒数
* 获取timestamp的简写形式:Date.now();
------------------------------------------------------
设置时间对象
设定日期对象
- 1.new Date('yyyy month dd hh:mm:ss')
- 2.new Date('month dd yyyy')
- 3.new Date(yyyy,month,dd,hh,mm,ss)
- 4.new Date(yyyy,month,dd)
- 5.new Date(timestamp)
* var time=new Date('2016 10 24 23:00:00')
* var time=new Date('10 24 2016 23:00:00')
* var time=new Date(2016,10,24,23,00,00)
* var time=new Date('2016 10 24')
* var time=new Date(2016,10,24)
//如果设置了不存在的日期,那么就会自动跳转
var time=new Date(2018,1,30);
var time=new Date(2018,1,0);
var time=new Date(2018,12,1);
// 假设你对象的生日是5月25号,那么2018年过生日的时候是星期几。
// var time = new Date(2018, 4, 25);
//
// console.log(time.getDay());
// var arr = [0, 0, 0, 0, 0, 0, 0];
// 求 2017 - 3017 5月25号生日的分布情况
// for(var i=2017; i<=3017; i++){
// arr[new Date(i, 4, 25).getDay()]++;
// }
// console.log(arr);
// ---------------------------------------------------
// 单独设置某个值
/**
* - setFullYear(year[,month[,date]]);
* - setMonth(month[,date]);
* - setDate(date);
* - setHours(h[,m[,s,[,ms]]]);
* - setMinutes(m[,s[,ms]]);
* - setSeconds(s[,ms]);
*/
// var time = new Date();
// time.setFullYear(2018, 7, 20);
// time.setMonth(1, 20);
// time.setDate(2);
// time.setHours(8);
// time.setMinutes(24);
// time.setSeconds(43);
// console.log(time);
// --------------------------------------------------
// 计算当月有多少天
// var now = new Date();
//
// now.setMonth(now.getMonth() + 1);
// now.setDate(0);
//
// console.log(now.getDate());
获取元素到定位父级的距离
定位父级:就是某个元素相对于谁去定位的那个元素;
获取元素到定位父级的距离:
ele.offsetLeft 获取left值
ele.offsetTop 获取top值
上面两个方法,不需要元素一定是定位的
var box = document.querySelector('.box');
console.log(box.offsetLeft);
console.log(box.offsetTop);
获取元素的宽和高
ele.offsetWidth/ele.offsetHeight
获取元素边框(包括边框)以里的大小
ele.clientWidth/ele.clientHeight
获取元素边框(不包含边框)以里的大小
ele.getBoundingClientRect()
获取 元素到屏幕左侧和上侧(到body)的绝位置
获取元素的offsetWidth和offsetHeight
var box = document.querySelector('.box');
console.log(box.getBoundingClientRect());
让一个物体运动
让一个物体运动起来必须要知道的几个量:
time:已经运动的时间
begin:起始位置
change:总路程
duration:总时间
比如匀速运动,可以表示当前物体位置为:
current=begin+change/duration*time
//获取这个要运动的元素的起始位置
var begin=box.offsetLeft;
//获取元素要运动的距离
var change=wrap.offsetLeft-box.offsetWidth;
设定一个运动的总时间
var durationg=2000;
var timer;
starMove.onclick=function(){
if(timer) return;
//设定起始时间
var setTime = Date.now();
timer=setInterval(function(){
var time=Date.now-startTime;
if(time>durationg){
time=duration;
clearInterval(timer)
timer=null;
}
//当前更新的位置
var currentPos=change/durationg*time+begin;
box.style.left= currentPos;
},14);
}
动画帧函数
动画帧函数:
Window.requestAnimationFrame()
window.cancelAnimationFrame()
//他们的用法和setTimeout是非常相似的。
var timer;
var m=0;
functiong fn(){
timer=window.requestAnimationFrame(fn);
console.log(m);
}
fn();
documengt.onclick=function(){
window.cancelAnimationFrame(timer);
}
回调函数
回调函数:就是当做参数传入到另外要给函数的函数
this指向
this:js的关键字,在不同的环境下代表不同的指向;
主要分为以下几种情况
全局作用域下:this==>window
函数作用域下:
ele.事件=事件处理函数,这里的this 就是触发这个事件的元素对象
对象.函数(),某个对象调用自身的某个方法(函数)的时候,那么这个函数内的this就是调用这个函数的那个对象
函数直接调用,那么相当于window对象去调用这个函数,所有函数内的this指的是window
下面三个方法,可以修改函数内部的this指向
fn.call(要指向的对象,参数1,参数2,...)
fn.apply(要指向的对象,[参数1,参数2...]===>(数组或者是类数组))
call和apply的作用是一模一样的,只是参数有区别
fn.bind(要指向的对象,参数1,参数2,...)
bind方法不会立即执行当前这个函数,而是返回的是一个新的函数,并且这个新的函数里面的this永远指向调用bind时候所指定的那个对象
错误的时间对象参数
如果 new Date()里面所传的参数是一个错误的, 那么会得到的结果是: Invalid Date
var time=nes Date(‘aa bb cc’);
console.log(time);
console.log(typeof time);
命名空间和分号
// 在添加新功能或者开发单独的功能的时候,如果使用一个单独的JS文件,那么尽量使用一个匿名函数包裹起来,形成命名空间,这样可以防止和外面的变量产生冲突。
;(function (){
// 新的代码
})();
// -------------------------------
document.onclick = function (){
console.log(1);
}
(function (){
console.log(2);
})();
// 以上代码会报错
将时间对象转换成UTC或者GMT标准时间字符串使用下面两个方法:
date.toUTCStringg()
date.toGMTString()
上面两种方法与toString()的区别在于toString()转换出来的字符串中有中文。
字符串
indexOf(searchValue[,fromIndex])
indexOf方法返回调用String对象中第一次出现的指定的索引,开始在fromIndex进行搜索,如果未找到该值,则返回-1。
searchValue:一个字符串表示被查找的值
fromIndex:表示调用该方法的字符串中开始查找的位置。可以是任意整数,默认值为0。如果fromIndex<0 则查找整个字符串(相当于传值为0),如果fromIndex>=str.length,则该方法返回-1,除非被查找的字符串是一个空字符串,此时返回str.length
var str = 'hello,javascript!';
console.log(str.indexOf('sc'));
console.log(str.indexOf('x'));
console.log(str.indexOf('a')); // 如果有多个一样的,默认只找第一个
console.log(str.indexOf('a', 7)); // 7
console.log(str.indexOf('a', 8)); // 9
console.log(str.indexOf('a', -8)); // 7
console.log(str.length);
console.log(str.indexOf('', 1000)); // 17
charCodeAt(index)
返回对应位置字符的Unicode编码;
index: 一个大于等于 0,小于字符串长度的整数。如果不是一个数值,则默认为 0。
* https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%88%97%E8%A1%A8
*/
var str1 = 'az';
var str2 = 'AZ';
var str3 = '09'; // 48 --- 57
// console.log(str1.charCodeAt(0)); // 97
// console.log(str2.charCodeAt(0)); // 65
// console.log(str3.charCodeAt(0)); // 48
fromCharCode.html
string.fromCharCode(num1,....numN);
该方法返回使用指定的Unicode值序列创建的字符串;
console.log(String.fromCharCode(97,98,99));
repeat
str.repeat(count);
repeat 构造并返回一个新的字符串,该字符串包含被连接在一起的指定数量的字符串副本。
count:介于0和正无穷大之间的整数:[0,+∞)。表示在新构造的字符串中重复了多少遍原字符串。
var str='我很帅';
var newStr=str.repeat(3);
console.log(newStr);
substr
str.sunstr(start[,length])
substr方法返回一个字符串从指定位置开始到指定字符结束的字符
start:开始提取字符的位置。如果为负值,则被看做 strLength+start,其中 strLength 为字符串的长度(例如,如果 start 为 -3,则被看作 strLength-3)。如果 start 为负值且 abs(start) 大于字符串的长度,则 substr 使用 0 作为开始提取的索引。
length: 可选。提取的字符数。如果length为0,则substr返回一个空字符串。如果忽略length,则substr提取字符知道字符串结尾。
substring
str.substring(indexStart,[,indexEnd])
sunstring方法返回一个字符串在开始索引到结束索引之间的一个子集,或从开始索引值到字符串的末尾的一个子集。
indexStart:一个0到字符串长度之间的整数
indexEnd:可选。一个0到字符串之间的整数
如果indexStart等于indexEnd,substring返回一个空字符。
如果省略indexEnd,substring提取字符一直到字符串末尾。
如果任一参数大于stringName.length,则被当做stringName.length。
如果indexStart大于indexEnd,则substring的执行效果就像两个参数调换了一样。例如:str.substring(0,1)==str.subsring(1,0)。
slice
str.slice(startIndex,[,endIndex]);
var str = 'javascript';
// console.log(str.slice(0, 4)); // 'java'
// console.log(str.slice(4)); // 'script'
console.log(str.slice(4, 0)); // ''
console.log(str.slice(-2, -1)); // 8 -- 9 'p'
console.log(str.slice(-1000, -1)); // 0 --- 9
split
str.split([separator[,limit]])
split方法使用指定的分割字符串将一个Sthing对象分割成字符串数组,以将字符串分隔为子子字符串,以确定每个拆分的位置
separator: 指定表示每个拆分应发生的点的字符串。separator 可以是一个字符串或正则表达式。 如果纯文本分隔符包含多个字符,则必须找到整个字符串来表示分割点。如果在str中省略或不出现分隔符,则返回的数组包含一个由整个字符串组成的元素。如果分隔符为空字符串,则将str原字符串中每个字符的数组形式返回。
*
* limit: 一个整数,限定返回的分割片段数量。当提供此参数时,split 方法会在指定分隔符的每次出现时分割该字符串,但在限制条目已放入数组时停止。如果在达到指定限制之前达到字符串的末尾,它可能仍然包含少于限制的条目。新数组中不返回剩下的文本。
*
* 找到分隔符后,将其从字符串中删除,并将子字符串的数组返回。如果没有找到或者省略了分隔符,则该数组包含一个由整个字符串组成的元素。如果分隔符为空字符串,则将str转换为字符数组。如果分隔符出现在字符串的开始或结尾,或两者都分开,分别以空字符串开头,结尾或两者开始和结束。因此,如果字符串仅由一个分隔符实例组成,则该数组由两个空字符串组成。
toLowerCase()
str.toLoWerCase()
会将调用该方法的字符串值转为小写形式,并返回
var str = 'getElementById';
console.log(str.toLowerCase()); // getelementbyid
console.log(str);
toUpperCase()
将调用该方法的字符串值转换为大写形式,并返回
var str = 'getElementById';
console.log(str.toUpperCase()); // GETELEMENTBYID
console.log(str);
trim
方法会从一个字符串的两端删除空白字符。
var str=' abc '
console.log(str.trim());
console.log(str.trimLeft());
console.log(str.trimRight());
数组
new array()
创建数组
var arr=[]
var arr=new Array()
当 new Array() 的参数只有一个,并且这个参数是一个数字的时候,那么代表创建一个长度为这个数字的空数组
// var arr = new Array(5);
// console.log(arr); // [empty × 5]
判断是不是一个数组 Array.isArray(数据)
/**
* Array.isArray(数据)
*
* 可以判断这个数据是不是数组,如果是那么就返回true,否则就是false
*/
// console.log(typeof []); // 'object'
// console.log(typeof {}); // 'object'
function test(){
var arr = [];
var obj = {};
console.log(Array.isArray(arr));
console.log(Array.isArray(arguments));
console.log(Array.isArray(obj));
}
test();
Array.from(类数组)
把类数组转成数组
var str='abcd'
console.log(Array.from(str)) //['a','b','c','d']
indexOf
arr.indexOf(item)
indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在则返回-1
var arr = [1, 2, 3];
console.log(arr.indexOf(2)); // 1
console.log(arr.indexOf(10)); // -1
push(),pop()
push()方法 将一个或者多个元素添加到数组的末尾,并且返回新数组的长度
pop()方法 从数组中删除最后一个元素,并返回被删除的元素的值此方法更改数组的长度
shift(),unshift()
arr.shift()
shift() 方法从数组中删除第一个元素,并返回被删除的那个元素的值,此方法更改数组的长度
arr.unshift()(element1,.....elementN)
unshift() 方法将一个或者多个元素添加到数组的开头,并返回新数组的长度
splice
arr.splice(start)
arr.splice(start,deleteCount);
arr.splice(start,deleteCount,item1,item2,...)
splice()方法通过删除现在元素和、或添加新元素来更改一个数组的内容
start:指定修改的开始位置(从0计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值则表示从数组末位开始的第几位(从1数);
deleteCount:整数,表示要移除的数组元素的个数。如果deleteCount是0; 则不移除元素,这种情况下则至少添加一个新元素。如果deleteCount大于start之后的总数则从start后面的元素都将被删除(含第start位)
item1,item2,...要添加进数组的元素,从start位置开始。如果不指定,则splice()将只删除数组元素
注意:返回值是一个数组,包含了被删除的元素。
var arr = ['a', 'b', 'c'];
console.log(arr.splice(1, 1)); // ['b']
console.log(arr);
console.log(arr.splice(1, 1, 1, 2));
console.log(arr);
console.log(arr.splice(1));
console.log(arr);
slice
arr.slice(start [,end]);
slice()方法返回一个从开始位置到结束位置(不包含结束)选择的数组的一部分浅拷贝到一个新的数组对象,原数组不会被修改。
var arr = [1, 2, 3];
// var arr2 = arr.slice();
//
// arr2[0] = 'a';
//
// console.log(arr2);
// console.log(arr);
console.log(arr.slice(1, 2));
arr.forEach
arr.forEach(cb [,thisArg])
forEach() 方法对数组的每个元素执行一次提供的函数。
callback 为数组中每个元素执行的函数,该函数接收三个参数:
-currentValue (当前值) 数组中正在处理的当前元素
-index(索引) 数组中正在处理的当前元素索引
-array forEach() 方法正在操作的数组
thisArg: 可选参数。 当执行回调函数时用作this的值(参考对象)
返回值:undefined
var arr=['a','b','c','d'];
arr.forEach(function(item,index,self){
console.log(item,index);
console.log(self)
},document);
map
arr.map(cb,[,thisArg])
map() 方法创建一个新数组,其结果是该数组中的每一个元素都调用一个提供的函数后返回的结果。
callback 为数组中每个元素执行的函数,该函数接收三个参数:
--currentValue (当前值)数组中正在处理的当前元素
--index(索引) 数组中正在处理的当前元素的索引
--array forEach() 方法 正在操作的数组
thisArg: 可选参数。 当执行回调函数时 用作this的值(参考对象)
返回值:新数组
var arr = [1, 2, 3];
var ret = arr.map(function (item, index, self){
// return 1;
return item * 2;
});
console.log(ret);
filter
arr.filter(cb,[,thisArg])
filter() 方法创建一个新的数组,其中包含通过所提供函数实现的测试的所有元素。
callback 为数组中每个元素执行的函数,该函数接收三个参数:
* - currentValue(当前值) 数组中正在处理的当前元素。
* - index(索引) 数组中正在处理的当前元素的索引。
* - array forEach()方法正在操作的数组。
*
* thisArg: 可选参数。当执行回调 函数时用作this的值(参考对象)。
*
* 返回值: 一个新的通过测试的元素的集合的数组
*
* filter 不会改变原数组。
var arr = [1, 'a', '12', 23, 'b', 100];
var ret = arr.filter(function (item, index){
return typeof item === 'string';
});
console.log(ret);
every
arr.forEach(cb[,thisArg])
*
* every() 方法测试数组的所有元素是否都通过了指定函数的测试。
*
* callback 为数组中每个元素执行的函数,该函数接收三个参数:
* - currentValue(当前值) 数组中正在处理的当前元素。
* - index(索引) 数组中正在处理的当前元素的索引。
* - array forEach()方法正在操作的数组。
*
* thisArg: 可选参数。当执行回调 函数时用作this的值(参考对象)。
*
* 返回值: 布尔值
*/
// 测试数组中的每一项,如果每一项都通过测试那么最终结果就是true,否则就是false
var arr = [11, 12, 19, 23];
var ret = arr.every(function (item){
return item > 10;
});
console.log(ret);
some
* arr.some(cb[,thisArg])
*
* some 为数组中的每一个元素执行一次 callback 函数,直到找到一个使得 callback 返回一个“真值”(即可转换为布尔值 true 的值)。如果找到了这样一个值,some 将会立即返回 true。否则,some 返回 false。callback 只会在那些”有值“的索引上被调用,不会在那些被删除或从来未被赋值的索引上调用。
*
* callback 为数组中每个元素执行的函数,该函数接收三个参数:
* - currentValue(当前值) 数组中正在处理的当前元素。
* - index(索引) 数组中正在处理的当前元素的索引。
* - array forEach()方法正在操作的数组。
*
* thisArg: 可选参数。当执行回调 函数时用作this的值(参考对象)。
*
* 返回值: 布尔值
*/
var arr = [11, 9, 20, 30, 40];
var ret = arr.some(function (item){
// return item < 10;
return item === 21;
});
console.log(ret);
find
arr.find(cb,[,thisA])
find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回undefined。
callback 为数组中每个元素执行的函数,该函数接收三个参数:
* - currentValue(当前值) 数组中正在处理的当前元素。
* - index(索引) 数组中正在处理的当前元素的索引。
* - array forEach()方法正在操作的数组。
*
* thisArg: 可选参数。当执行回调 函数时用作this的值(参考对象)。
var arr = [19, 9, 17, 21];
var ret = arr.find(function (item){
return item < 10;
});
console.log(ret);
findIndex
arr.forEach(cb[,thisArg])
*
* findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
*
* callback 为数组中每个元素执行的函数,该函数接收三个参数:
* - currentValue(当前值) 数组中正在处理的当前元素。
* - index(索引) 数组中正在处理的当前元素的索引。
* - array forEach()方法正在操作的数组。
*
* thisArg: 可选参数。当执行回调 函数时用作this的值(参考对象)。
*
*/
var arr = [19, 9, 17, 21];
var ret = arr.findIndex(function (item){
return item < 10;
});
console.log(ret); // 1
join
* arr.join(separator)
*
* join() 方法将数组(或一个类数组对象)的所有元素连接到一个字符串中。
*
* separator: 指定一个字符串来分隔数组的每个元素,默认为 ","。
*/
var arr = ['java', 'scr', 'ipt'];
console.log(arr.join());
console.log(arr.join('-'));
console.log(arr.join(' '));
reverse()
arr.reverse()
*
reverse() 方法将数组中元素的位置颠倒。
*/
var arr = ['a', 2, 3, 4, 'f'];
arr.reverse();
// arr.reverse();
console.log(arr);
sort()
sort() 方法在适当的位置对数组的元素进行排序,并返回数组。sort 排序不一定是稳定的。默认排序顺序是根据字符串Unicode编码
*/
// var arr = [2, 1, 4, 5, 3];
//
// arr.sort();
//
// console.log(arr);
// -----------------------------
// var arr = [2, 1, 4, 5, 11, 23, 3];
//
// arr.sort();
//
// console.log(arr);
// -----------------------------
// var arr = ['c', 'a', 'b'];
//
// console.log(arr.sort());
//
// console.log(arr);
// ------------------------------
var arr = [2, 1, 4, 5, 11, 23, 3];
// arr.sort(function (a, b){
// // console.log(a, b);
// return a > b;
// });
//
// console.log(arr);
// arr.sort(function (a, b){
// return a < b;
// });
//
// console.log(arr);
// -----------------------------
// Math.random(); 是JS的随机数,返回的是[0, 1)之间的随机小数
arr.sort(function (){
return Math.random() - 0.5;
});
console.log(arr);
fill()
/**
* arr.fill(value)
* arr.fill(value, start)
* arr.fill(value, start, end)
*
* fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。
*/
var arr = [1, 2, 3, 4];
// arr.fill(0);
// arr.fill(0, 1)
// arr.fill(0, 1, 3);
console.log(arr);
concat
* arr.concat(arr1, arr2, arr3...);
*
* 将 arr 和 后面参数里面的数组 拼接起来,返回拼接之后的数组
*/
var arr = [1, 2];
var arr1 = [3, 4];
var arr2 = ['a', 'b'];
// var ret = arr.concat(arr1, arr2);
//
// console.log(arr);
//
// console.log(ret);
// ... 代表扩展运算符
// var ret = [...arr, ...arr1, ...arr2];
//
// console.log(ret);
// function fn(){
// var arg = [...arguments];
// console.log(arg);
// }
//
// fn(1, 2, 3);
// ------------------------------------
var btns = document.querySelectorAll('button');
console.log(btns);
console.log(...btns);
[...btns].filter(function (item){
/**
* ele.classList.contains(cls)
* 如果元素有这个cls那么返回值是true
* 否则就是一个false
*/
return item.classList.contains('btn')
}).forEach(function (item){
item.onclick = function (){
alert(this.innerHTML);
};
});
Math对象
包含了数学中的常数和一些属性与方法
console.log(Math);
//Math.abs(x);
//求x这个数值的绝对值
console.log(Math.abs(0)); // 0
console.log(Math.abs(-10)); // 10
Math.PI: 代表圆周率,也就是圆的周长和直径的比值
3.14159
代表弧度单位
// console.log(Math.PI); // 180度
// 1 角度 等于 Math.PI / 180 的弧度
/**
* 三角函数
* - Math.sin(弧度) 正弦值
* - Math.cos(弧度) 余弦值
* - Math.tan(弧度) 正切值
*
* 反三角函数
* - Math.asin(x) x ==> [-1, 1]
* - Math.acos(x) x ==> [-1, 1]
* - Math.atan(x) 返回值:(-Math/PI/2, Math.PI/2)
* 上面这三个x都是一个弧度
*
* * - Math.atan2(y, x); // 得到的是一个弧度
*/
// console.log(Math.sin(Math.PI/2));
// console.log(Math.sin(-Math.PI/2));
// console.log(Math.sin(Math.PI));
// console.log(Math.tan(Math.PI/4));
// console.log(Math.atan2(100, 300));
// console.log(Math.atan2(100, 100) * 180 / Math.PI); // 45
Math.ceil(num) //向上取整
console.log(Math.ceil(1.2)); //2
console.log(Math.ceil(-1.2)); //-1
Math.floor(1.95) //1
Math.floor(-1.1) //-2
Math.round(num) //四舍五入
Math.round(1.5) //2
Math.round(-1.5) //-1
Math.round(-2.4) //-2
Math.round(-2.5) //-2
Math.round(-2.1) //-2
Math.round(-2.6) //-3
Math.max(num1,num2,num3) 求其中的最大值
Math.max(1,3,4,5,1,0,4,1) //5
Math.max.apply(null,[2,3,5,4,1]) //5
Math.max.apply(this,[2,3,5,4,1]) //5
Math.max(...arr)
Math.min(num1, num2, num3...) 求其中的最小值
var arr = [3, 1, 4, 5, 2];
// console.log(Math.min.apply(null, arr));
// console.log(Math.min.apply(this, arr));
console.log(Math.min(...arr));
Math.random() //随机数 返回 [0, 1) 之间的随机小数
求任意范围之间的随机数公式:
* Math.random() * (最大值 - 最小值) + 最小值
function rp(arr, int){
var min = Math.min(...arr);
var max = Math.max(...arr);
var ret = Math.random() * (max - min) + min;
return int ? Math.round(ret) : ret;
}
var box = document.querySelector('.box');
box.style.backgroundColor = `rgb(${rp([50, 255], true)}, ${rp([50, 255], true)}, ${rp([50, 255], true)})`;
Math.pow(x,y) 返回 x 的y 次幂
Math.pow(7,2) //49
Math.pow(2,3) //8
3**99
Math.sprt(num) 求num的开二次方
// 例: 求两点间的距离
var p1 = {
x: 100,
y: 100
};
var p2 = {
x: 600,
y: 200
};
var dx = p1.x - p2.x;
var dy = p1.y - p2.y;
var distance = Math.sqrt(dx**2 + dy**2);
DOM
DOM ----> document object model (文档对象模型)
概念: DOM是针对XML的扩展,就是为JS操作页面元素提供了一套应用程序编程接口(API)。DOM把整个文档映射成一个树状结构,它里面的所有的东西都是一个结点。比如说,一个div元素对象,就称为一个元素节点。而节点是这些对象的父级。
/**
* 节点至少拥有nodeType、nodeName和nodeValue这三个基本属性。节点类型不同,这三个属性的值也不相同
*/
// 元素节点 Node.ELEMENT_NODE(1)
// 属性节点 Node.ATTRIBUTE_NODE(2)
// 文本节点 Node.TEXT_NODE(3)
// CDATA节点 Node.CDATA_SECTION_NODE(4)
// 实体引用名称节点 Node.ENTRY_REFERENCE_NODE(5)
// 实体名称节点 Node.ENTITY_NODE(6)
// 处理指令节点 Node.PROCESSING_INSTRUCTION_NODE(7)
// 注释节点 Node.COMMENT_NODE(8)
// 文档节点 Node.DOCUMENT_NODE(9)
// 文档类型节点 Node.DOCUMENT_TYPE_NODE(10)
// 文档片段节点 Node.DOCUMENT_FRAGMENT_NODE(11)m
// DTD声明节点 Node.NOTATION_NODE(12)
var link = document.querySelector('a');
console.log(link.nodeType); // 1
console.log(link.nodeName); // 'A'
console.log(link.nodeValue); // null
// 1 2 3 8 9
创建一个dom元素并插入
/**
* 1 ele.parentNode 可以获取到ele的父节点
* 2 ele.offsetParent 可以获取到ele的定位的父节点
*/
// ele.children 可以获取到 ele 的第一层的所有的元素子节点
// 并且是 动态获取
// querySelectorAll 不是动态获取的
previousElementSibling 获取ele上一个兄弟元素节点
nextElementSibling 获取ele的下一个兄弟元素节点
firstElementChild 获取第一个字节点
lastElementChild 获取最后一个子节点
document.createElement(标签的名字tag);
可以创建一个DOM元素
parent.appendChild(ele); 把 ele 这个元素对象插入到 parent 这个父容器的最后
parent.insertBefore(newEle, target); 把 newEle 这个元素放到父容器为 parent 的 target 元素的前面
var link = document.createElement('a');
link.href = 'https://www.google.com';
link.innerHTML = '谷歌';
var box = document.querySelector('.box');
var target = document.querySelector('.target');
var p = document.createElement('p');
p.innerHTML = '这是新插入的节点<br />';
console.log(p.appendChild(link));
console.log(box.appendChild(p));
DOM 的剪切操作
var box1 = document.querySelector('.box1');
var box2 = document.querySelector('.box2');
// var leftLastEle = box1.lastElementChild;
//
// box2.appendChild(leftLastEle);
var rightFirstEle = box2.firstElementChild;
//box1.appendChild(rightFirstEle);
/* box1.insertBefore(rightFirstEle, box1.children[2]); */
DOM 的删除操作
parent.removeChild(ele); 删除 parent 父容器下面的 ele 元素
DOM 的克隆操作
* ele.cloneNode([deep]); 克隆 ele 这个节点,如果传了 deep参数为 true 那么就是深克隆,如果不传 deep 只是克隆当前这个 节点,不会克隆它里面的节点,深度克隆,会克隆里面的节点,但是事件是不会克隆的
DOM 的替换操作
parent.replaceChild(new, old) 把 parent 下的 old 节点替换成 new 节点 (剪切操作)
DOM操作表格###—————————–10.23
// 通过 table.tHead 可以获取到表格头
// 通过 table.tFoot 可以获取到表格脚
// 通过 tbody.rows[index] 获取到某个tbody里面的index行
// table.tBodies[0].rows // 第一个tBody里面的所有的 行
// table.tBodies[0].rows[0] // 第一个tBody里面的第一行
// 通过 row.cells[index] 获取到某一行里面的第index个单元格
// table.tBodies[0].rows[0].cells 获取到 rows[0]的所有的单元格
// table.tBodies[0].rows[0].cells[1] 获取到 rows[0]的所有的单元格中的第二个
DOM创建表格
// 创建表格头 table.createTHead(); 创建并返回被创建的thead元素,然后会自动插入table
// var thead = table.createTHead();
// 创建表格体 table.createTBody(); 创建并返回被创建的tbody元素,然后会自动插入table
// table.createTBody();
// 创建表格脚 table.createTFoot(); 创建并返回被创建的tfoot元素,然后会自动插入table
// table.createTFoot();
// 通过 tbody.insertRow(_pos_); 向tbody中指定位置添加一行tr,并返回这个元素
// 通过 tr.insertCell(_pos_); 向 tr中 指定位置 添加一个单元格 td 并返回这个元素
// table.deleteTHead(); 删除表格头
// table.deleteTFoot(); 删除表格脚
// table.tNodes[_pos_].deleteRow(_pos_) 删除对应位置的行
// table.tNodes[_pos_].rows[_pos_].deleteCell(_pos_) 删除对应行的对应位置的单元格
DOM 操作表格
// document.forms 获取到页面上所有的表单
// froms.someInputName 获取到对应name的表单内部元素
// console.log(document.forms);
DOM 操作补充
/**
* 快速的获取body document.body
* 快速的获取html document.documentElement
* 快速的获取title doucment.title (可读可写)
*/
HTML5 自定义属性
/**
* data-属性名="value" 代表html5的自定义属性
*
* 在JS中 使用 ele.dataset 可以获取到所有自定义属性的集合
*
* 如果data-后面是一个驼峰命名的,那么会把所有的字母都变成小写。
* 如果想使用驼峰命名,比如 divEle,需要写成 data-div-ele
*/
DOM的属性操作
/**
* ele.getAttribute('属性名') 可以拿到元素身上属性对应的值
* ele.setAttribute('属性名', '属性值')
*/
var img = document.getElementById('img');
console.log(img.getAttribute('src')); // './xdd.jpg'
img.setAttribute('class', 'img'); //设置属性名和属性值
BOM
BOM Browser Object Model 浏览器对象模型,它的核心是 window 对象,同时 window 又是JS的顶层对象
/**
* 1 alert() 弹出带确定按钮的提示框
* 2 prompt() 带文字提示和确定按钮的弹框
* 3 confirm() 待确定和取消按钮的提示框
*/
--------------------------------------------------------
/**
* 一个完整的url地址
* https://www.xxx.com:80/a/b/c?a=1&b=2&c=3#abc
* - https 称为协议 protocol
* - www.xxx.com:80 称为 host
* - www.xxx.com 称为 hostname
* - /a/b/c 称为路径
* - ?a=1&b=2&c=3 称为 queryString 查询字符串
* - #abc 成为hash
*/
// window.location.href 可以获取到当前的url地址
// window.location.href = url 也可以设置当前的url地址
---------------------------------------------------------
获取用户的浏览器代理信息
window.navigator.userAgent
// 判断是否是移动端
function isMb(){
var ret = false;
var device = ['iPhone', 'Android', 'iPad'];
var userAgent = window.navigator.userAgent;
device.forEach(function(item, i) {
if(userAgent.indexOf(item) !== -1){
ret = true;
}
});
return ret;
}
/**
* window.location.search 可以获取到查询字符串,从 ? 到 # 之间的内容,包括 ? 不包括 #
*
* 修改了 queryString 会刷新浏览器
*/
------------------------------------------------
/**
* 当 hash 改变的时候会触发 hashchange 事件
*/
// window.onhashchange = function (){
// alert(window.location.hash);
// };
------------------------------------------------------
/**
* window.history 对象 主要包括了 浏览器的 前进后退等方法
*
* window.history.back() 跳转到上一帧
* window.history.forward() 跳转到下一帧
*/
---------------------------------------------------
/**
* window.screen.width / height
* 获取设备的分辨率
*
* window.screen.availWidth / Height
* 获取可用的窗口大小
*/
----------------------------------------------------
/**
* window.location.search = value
* 可以设置 queryString
*/
---------------------------------------------------
/**
* window.location.hash = value
* 可以设置hash
*/
事件
/**
* 1 事件:事件是文档或者浏览器窗口中发生的 特定的 交互瞬间。
* 2 事件名:例如 click mouseover load ...
* 3 事件处理函数:当执某个事件发生的时候,执行的对应的函数称为事件处理函数,如果一个元素发生了某件事,但是没有这件事对应的事件处理函数,那么这种情况称为事件流失。
* 4 事件流:事件流描述的是元素对象从页面中接收事件的顺序。事件发生时会在元素节点与根节点之间按照特定的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流。
* - 事件冒泡: 事件的传播是从最具体的事件目标到最不具体的事件目标。即从DOM树的叶子到根。(推荐)
* - 事件捕获: 事件的传播是从最不特定的事件目标到最特定的事件目标。即从DOM树的根到叶子。
*/
ele.addEventListener('事件名', 事件处理函数, 是否捕获);
是否捕获:默认值是 false,也就是不捕获
ele.removeEventListener('事件名', 事件处理函数, 是否捕获);
注意:要和添加的事件处理函数一一对应
e.stopPropagation() 组织冒泡
----------------------------------------
/**
* 事件委托:就是当需要给某个元素下的某个子节点添加事件的时候,由于子节点触发事件的时候会发生事件冒泡,冒泡的父节点,所以当需要给多个子节点添加相同的事件的时候,可以把这个事件委托给父节点来做,通过事件源来判断触发事件的对象是什么,然后执行指定好的事件处理函数即可。
*/
系统事件
/**
* 1 load 当加载完成时候触发
* 2 scroll 当滚动条滚动的时候触发
* 3 resize 当浏览器窗口大小发生改变的时候触发
*/
获取滚动条的滚动距离
document.documentElement.scrollTop / scrollLeft
document.body.scrollTop / scrollLeft(低版本谷歌浏览器)
window.addEventListener('scroll', function (e){
console.log(document.body.scrollTop);
});
document.addEventListener('click', function (e){
document.documentElement.scrollTop = 0;
});
鼠标事件
/**
* 1 click
* 2 mouseover
* 3 mouseout
*
* 4 mouseenter 鼠标移入 (不冒泡)
* 5 mouseleave 鼠标移出 (不冒泡)
*
* 6 mousemove 鼠标抚摸事件
*
* 7 dblclick 鼠标双击事件(触发双击的前提一定会触发两次单击事件)
*
* 8 mousedown 鼠标按下事件
* 9 mouseup 鼠标抬起事件
*
*/
想让一个元素跟随鼠标移动,那么别忘了给这个元素添加定位
document.addEventListener('mousemove', function (e){
var x = e.pageX, y = e.pageY;
box.style.left = (x - box.offsetWidth / 2) + 'px';
box.style.top = (y - box.offsetHeight / 2) + 'px';
});
阻止默认行为:
preventDefault()
鼠标右键菜单事件: contextmenu
表单事件
/**
* 1 focus 当获取到焦点的时候触发
* 2 blur 当失去焦点的时候触发
* 3 select 选中文本的时候触发
* 4 change 表单的value改变之后,失去焦点的时候触发
* 5 input 实时监听表单的变化
*/
键盘事件
/**
* keydown 键盘按下
* keyup 键盘抬起
* keypress 键盘按下 不包括功能键
*/
拖拽原理
/**
* 1 鼠标在当前元素身上按下的时候可以移动鼠标
* 2 移动鼠标元素跟着鼠标的位置进行移动
* 3 抬起鼠标元素停止在当前抬起鼠标的位置
*/
ele.getBoundingClientRect()
width:ele的宽度
height:ele的高度
left:ele的左边框到浏览器窗口左边的距离
right:ele的右边框到浏览器窗口左边的距离
top:ele的上边框到浏览器窗口上边的距离
bottom:ele的下边框到浏览器窗口上边的距离
限制推拽范围、基于九宫格的碰撞检测、基于通用拖拽函数(20171030)
滚轮事件
/**
* 1.在火狐浏览器下,使用滚轮事件,必须使用DOM2级事件监听的形式,监听 'DOMMouseScroll'
*
* 2.在谷歌、IE其它浏览器下使用 mousewheel 事件
*/(20171101)
Json
/**
* JSON: JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。
*
* JSON实际上就是一种字符串格式的对象。
* JSON对象和JSON字符串可以互相转换
*
* JSON.parse(json数据) 可以将json字符串转换成对象
* JSON.stringify(对象数据) 可以将普通的对象转换成json字符串
*
* 注意事项:
* - JSON里面的key必须用双引号包起来
* - JSON里面的数据不能有函数
*/
// JSON的应用:深拷贝
let obj1 = {
a: [1, 2, 3,['a','c']],
b: 2
};
let obj2 = {};
obj2 = JSON.parse(JSON.stringify(obj1));
obj2.a[3][0] = 10;
console.log(obj2);
console.log(obj1);
本地存储
/**
* localStorage 本地存储
* - setItem: 储存数据
* - getItem: 读取数据
* - removeItem: 删除数据
* - clear: 清空数据
*/
// 清空本地所有数据
// localStorage.clear();
// 添加一条数据
localStorage.setItem('name','xiaoming');
// 获取一条数据
console.log(localStorage.getItem('name'));
// 删除一条
//localStorage.removeItem('name');
正则表达式
正则表达式(Regular Expression)
* 使用单个字符串来描述、匹配一系列符合某个语句规则的字符串
* (按照某种 规则 去匹配符合条件的字符串)
/*
* 1 /abc/ 正则的字面量表示法
* 2 new RegExp(规则, 修饰符)
*/
/**
* 修饰符:
* g: global 全文搜索,不添加,搜索到第一个就会停止
* i: ignore case 忽略大小写,默认区分大小写
* m: multiple lines 多行搜索
*/
表达式 描述
[abc] 查找方括号之间的任何字符。
[^abc] 查找任何不在方括号之间的字符。
[0-9] 查找任何从 0 至 9 的数字。
[a-z] 查找任何从小写 a 到小写 z 的字符。
[A-Z] 查找任何从大写 A 到大写 Z 的字符。
[A-z] 查找任何从大写 A 到小写 z 的字符。
[adgk] 查找给定集合内的任何字符。
[^adgk] 查找给定集合外的任何字符。
(red|blue|green) 查找任何指定的选项。
元字符 描述
. 查找单个字符,除了换行和行结束符。
\w 查找单词字符。
\W 查找非单词字符。
\d 查找数字。
\D 查找非数字字符。
\s 查找空白字符。
\S 查找非空白字符。
\b 匹配单词边界。
\B 匹配非单词边界。
\0 查找 NUL 字符。
\n 查找换行符。
\f 查找换页符。
\r 查找回车符。
\t 查找制表符。
\v 查找垂直制表符。
\xxx 查找以八进制数 xxx 规定的字符。
\xdd 查找以十六进制数 dd 规定的字符。
\uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符。
量词 描述
n+ 匹配任何包含至少一个 n 的字符串。
n* 匹配任何包含零个或多个 n 的字符串。
n? 匹配任何包含零个或一个 n 的字符串。
n{X} 匹配包含 X 个 n 的序列的字符串。
n{X,Y} 匹配包含 X 至 Y 个 n 的序列的字符串。
n{X,} 匹配包含至少 X 个 n 的序列的字符串。
n$ 匹配任何结尾为 n 的字符串。
^n 匹配任何开头为 n 的字符串。
?=n 匹配任何其后紧接指定字符串 n 的字符串。
?!n 匹配任何其后没有紧接指定字符串 n 的字符串。
/**
* 类: 匹配某类具有某种特征类的字符,可以使用 [] 来构建一个简单的类
* 例如: [abc] 代表匹配 a或b或c,[^abc]代表匹配非a非b非c的其他字符
*/
var str = 'a1b2c3';
// console.log(str.replace(/[abc][123]/g, '0'));
// console.log(str.replace(/[^123]/g, '='));
---------------------------------------------------------
replace的高级用法
// 'a1b2c3' ==> a2b3c4
const ret = 'a1b2c3'.replace(/(\w)(\d)/g, (match, $1, $2, index, str) => {
//console.log(match);
console.log($2);
// console.log(index); // 从哪里开始匹配
// console.log(str);
return $1 + (parseInt($2) + 1);
});
console.log(ret);
search
/**
* str.search('str'|reg) 找到了就返回位置,找不到就返回-1
*
* 注意:如果参数是个正则,那么会忽略其中的g修饰符,只找第一个
*/
const str = 'hello, ni shi ge bi lao wang ma?'
console.log(str.search(/o/));
/**
* str.match(reg)
*
* 1 reg 没有全局修饰符
* - 返回一个数组
* - 数组第一个是匹配的内容
* - 数组第二个开始是匹配的子项
* - 数组里有个index属性代表匹配的位置
* - 数组里面有个input属性代表匹配字符串
* 2 reg 有全局修饰符
* - 直接返回一个数组,就是所有匹配的内容
* 3 如果没有匹配成功,那么返回的是 null
*/
console.log('a12b34c56'.match(/([a-z])(\d{2})/));
// console.log('1a2b3c4'.match(/[a-z](\d)/));
// console.log('a2b3c4'.match(/[a-z](\d)/g));
// console.log('a2b3c4'.match(/\s{2}/g));
console.log('a1b2c3'.match(/\d/g));
-----------------------------------------------------
/**
* 正则也是一个对象
*
* 以下只可以读不可以写
* global 默认是 false
* ignoreCase 默认是false
* multeline 默认是 false
* lastIndex 默认是0,代表当前匹配的结构的下一个位置,并且如果是全局匹配,那么下次会从lastIndex的位置开始查找
* source 代表原正则表达式的字符串
*/
var reg1 = /\w\d/;
var reg2 = /\w\d/gim;
var str = 'a1b2c3';
-----------------------------------------------------
/**
* reg.test('str') 用来测试某个字符串,
* 如果通过测试了返回true,否则就返回false
*/
// var str1 = '12345';
// var str2 = 'a12345';
// var reg = /^[1-9]\d{4,9}$/;
// console.log(reg.test(str1));
// console.log(reg.test(str2));
// ---------------------------------------
var str = 'a1b2c3';
var reg = /\d/g;
while(reg.test(str)){
console.log(reg.lastIndex);
}
// /\d/g.test('a1b2c3') 这样做可以每次都返回true,但是不推荐,原因每次都要向内存新申请一个对象需要的空间。
// 实际上,使用test就是为了测试字符串是否是符合规则的,所有不要加 全局 标志
// exec
--------------------------------------------------------
// [\u4e00-\u9fa5] 匹配中文
console.log('你好,老王!'.replace(/([\u4e00-\u9fa5]{2})/, 'hello'));
-------------------------------------------------------
###重复子项
/**
* \1表示重复正则第一个圆括号内匹配到的内容
* \2表示重复正则第二个圆括号内匹配到的内容
* ...
* \9
*/
// 1221
// const reg = /1221/;
const reg = /(1)(2)\2\1/;
console.log(reg.test('1221'));
-------------------------------------------------
/**
* (?=exp) 正向前瞻 匹配后面满足表达式exp的位置
* (?!exp) 负向前瞻 匹配后面不满足表达式exp的位置
*/
const str = 'Hello, he is say hi, ni shuo ta shi bu shi sha!';
const ret = str.replace(/\w(?=i)/g, 'X');
console.log(ret);
console.log(str.replace(/s(?!a)/g, 'X'));
---------------------------------------------------------
// 匹配手机号
const phoneReg = /^1\d{10}$/;
// 匹配qq
const qqReg = /^[1-9]\d{4,10}$/;
// 匹配邮箱
const emailReg = /^([a-z\d]+(\.|-|_)?)+[a-z\d]+@[a-z\d]{2,}(\.[a-z]{2,}){1,5}$/i;
// 匹配日期
const dateReg = /^\d{4}(-|/|\.)\d{2}(-|/|\.)\d{2}$/;
const cardReg = /(^\d{15}$)|(^\d{17}([0-9]|X)$)/;
面向对象20171120
/**
* 面向对象(oop)是一种编程思想。对象都是通过实例化类得到的。对象是对客观事物的抽象,类是对对象的抽象。
* - 封装: 不用关心某个类的内部实现,只需要去使用它
* - 继承:通常是类和类之间的行为,子类继承于父类
* - 多态:继承之后的子类,可以有自己独特的属性和行为
*/
/* 对象 = new 类();
对象是通过实例化类得到的,实例化的过程就是 new XXX 的过程。 */
---------------------------------------------------------
/**
* 定义一个类 使用 class 类的名字 {};
*
* 类的名字通常都是首字符大写的。
*/
class Ball {}; // Ball 就是一个类
const ball = new Ball();
console.log(ball);
// class Ball {}; 只是定义一个类,这个类里面什么都没有。
// 这样去实例化一个类,只会得到一个空对象。
-----------------------------------------------------
/**
* 在JS这个大工厂中,有一个原型产品即:对象的原型 --- Object.prototype
* 通过对象的原型,首先创造出了另外一个加强版的原型产品 --- Function.prototype (空函数)
*
* 通过 Function.prototype 这个原型产品制造出了两个非常强大机器函数:Object 和 Function
* Object 函数 用来批量生产对象
* Function 函数 用来批量生产 其它不同功能的函数
*
* Object 和 Function 都称之为构造函数,每个构造函数都有一个 prototype 属性,
* 可以生产出基于这个原型的产品,它们通过 new 构造函数 的方式去实例化自己的产品,
* 并且为每个产品打上一个标签__proto__,用来表明这个产品的原型是谁,同时每个
* prototype身上都有一个 constructor 属性,用来指明这个原型的构造函数是谁。
*
* 原型本身也是一个对象,构造函数不仅仅能生产普通的函数,也能生产构造函数。
*/
------------------------------------------------
/**
* 构造函数: 比如 new Object() 相当于 得到一个 {},那么 这个 Object 实际上就是一个构造函数,通过这个例子,可以发现构造函数的特征:
* - 使用 new 去调用的函数
* - 函数的名字的首字符是大写的(这只是个约定)
*
* 通过 new 去调用一个构造函数,称之为对象的实例化。
*
* 除了JS自带的构造函数,自己也可以去定义自己的构造函数,就像使用 class 去定义一个 类 一样。
*
*/
-----------------------------------------------------
/**
* 每个函数都有一个 prototype 属性,但是只有当这个函数当作构造函数使用的时候这个属性才会生效。
*
* 构造函数.prototype 本身是一个对象,也是这个构造函数实例化出来对象的原型,所以所有通过这个
* 构造函数实例化出来的对象都会记住并且可以访问它们自己的原型。
*
* 原型中有一个特殊的属性 constructor,它在函数创建的时候有JS引擎自动添加,用来表明这个原型
* 的构造函数是谁。但是这个属性可读可写,所以它并不可靠。同时 这个属性 是一个 不可以被枚举的。
*
* 枚举:凡是可以被for...in循环所循环到的属性,都是可以枚举的 enumerabled。反之都是不可以被
* 枚举的,比如 数组的 length 属性, 对象的 __proto__ 属性。
*/
----------------------------------------------------------
/**
* 每个被构造函数实例化出来的对象,都会记住它自己的原型(proto),而每个原型也是一个对象,
* 所以原型对象也会记住它自己的原型,最终它们都会找到一个顶级原型对象 Object.prototype
*
* 可以发现,它们之间彼此互相关联,这个关联就称之为原型链。
*
* 当访问一个对象的某个属性的时候,先在自身进行查找,如果自身没有,那么就会顺着原型链去查找,直到找到 Object.prototype
*/
// 对象.hasOwnProperty(属性),用来判断这个属性是不是这个对象自身的。
const obj = {a: 1};
const obj2={c:12};
Object.prototype.b = 2;
//xxx in obj 看 xxx 属性在不在 obj 当中,在就返回 true,否则就返回 false
console.log('a' in obj);
console.log('b' in obj); // true
// in 不能判断是否是自身的属性
console.log(obj.hasOwnProperty('a')); // true
console.log(obj.hasOwnProperty('b')); // false
----------------------------------------------------------
/**
* instanceof 运算符表示 a(对象) 是否是 b(构造函数) 的实例。
*
* [] instanceof Array 为 true, [](空数组)是一个数组(Array 类的实例)
* Array instanceof Function 为 true, Array(类构造器)是一个函数(Function 类的实例)
* [] instanceof Function 是 false, [](空数组)不是一个函数(Function 类的实例)
*
* 深入 instanceof : instanceof关键字的作用是判断实例对象是否是原型链上出现过的构造函数的实例对象
*/