2021年02月09日 20:15:03
jQuery初学者笔记
JavaScript最初命名LiveScript,它是一种脚本语言,运行在客户端。也可以基于Node.js技术进行服务端编程。
JS作用
- 表单验证
- 网页特效
- 服务端开发(Node.js)
- 桌面程序(Electron)
- App(Cordova)
- 控制硬件-物联网(Ruff)
- 游戏开发 (cocos2d-js)
JS的组成
- ECMAScript - Javascript语法
- DOM - 页面文档对象模型
- BOM - 浏览器对象模型
JS书写位置
- 行内式
<input type="button" value="行内式" onClick="alert('Hello World!')" >
- 内嵌式
<script>
alert('Hello World!');
</script>
- 外部
<script src="xxx.js">这里不允许写任何代码</script>
注释
- 单行注释
// 这是单行注释
- 多行注释
/*
这是多行注释
*/
输入输出语句
- alert(msg) - 浏览器弹出警示框
alert('警示框');
- console.log(msg) - 浏览器控制台打印输出信息
// 在浏览器开发者工具(F12)的Console中查看
console.log('测试使用')
- prompt(info) - 浏览器弹出输入框,用户可以输入
prompt('输入框');
变量
// 声明变量
var age;
// 给变量赋值
age = 18;
// 变量的初始化
var myname = '落叶';
// 声明多个变量
var employeename = 'Kevin',
phonenumber = 186,
address = 'xxxx';
// 声明变量的特殊情况
// 1. 只声明不赋值,结果是undefined未定义的
var sex;
// 2. 不声明不赋值,会报错
console.log(tel);
// 3. 不声明直接使用,是可以的,但是不提倡使用。
email = 'xxxx@xx.com';
变量命名规范
- 由字母(A-Za-z)、数字(0-9)、下划线(_)、美元符号($)组成,如:usrAge, num01, _name
- 严格区分大小写。var app;和var App;是两个变量
- 不能以数字开头。18age 是错误的
- 不能是关键字、保留字。如:var、for、while
- 变量名必须有意义,最好是英文单词。
- 遵守驼峰命名法。首字母小写,后面单词的首字母需要大写。如:myFirstName
变量类型
Javascript是一种弱类型或者说动态语言。变量的类型在程序运行过程中被自动确定。
var age = 18; // 这是一个数字型
var myName = 'Pianpianluoye'; // 这是一个字符串
var a = b = c = 9; //等同于 var a = 9; b = 9; c = 9;
var e = 9 , f = 9 , g = 9; // 等同于 var e = 9; var f = 9; var g = 9;
// JavaScript 拥有动态类型,相同变量可以作用不同类型
var x = 6; // x 为数字
var x = 'Material'; // x 为字符串
简单数据类型
- Number - 数字型,包含整型值和浮点型值,默认值为0
// 数字型最大值
console.log(Number.MAX_VALUE);
// 数字型最小值
console.log(Number.MIN_VALUE);
// 无穷大
alert(Infinity);
// 无穷小
alert(-Infinity);
// Nan - 代表一个非数值
alert(NaN);
// 判断非数字,非数字为true,数字为false
console.log(isNaN(12)); // false
- Boolean - 布尔类型,默认值false
// Boolean类型参与运算预算时 true = 1 false = 0
console.log(true + 1); // result: 2
console.log(false + 1); // result: 1
- String - 字符串类型,默认值""
由于给改变字符串的值会在内存中开辟一个新的空间存储,所以不要大量的拼接字符串 - 字符串的不可变性
// 字符串类型必须要加引号,因为HTML中使用的是双引号,建议JS里使用单引号
var strName = 'Pianpianluoye';
var strAddress = "Pianpianluoye";
// 如果引号嵌套,可以外双内单或外单内双的规则
var strProject = '这是一个"项目"描述';
var strType = "这是一个'类型'描述";
字符串转义符
- \n - 换行
- \\ - 斜杠
- \’ - 单引号
- \" - 双引号
- \t - 缩进
- \b - 空格
字符串拼接
// 字符串拼接 +
// 只要有字符串类型和其他类型的拼接,结果一定是字符串拼接,数字相加,字符相连口诀。
console.log('str1' + 'str2');
console.log('我' + 18 + '岁');
// 含有变量的字符串拼接
var age = 18;
console.log('我' + age + '岁');
- Undefined - 未定义类型,默认值undefined
// 如果一个变量声明未赋值,就是undefined未定义数据类型
var str;
console.log(str);
var variable = undefined;
console.log(variable + '未定义类型'); // result:undefined未定义类型
console.log(variable + 1); // result:NaN
- Null - 空值,默认值为null
// Null 代表空值
var space = null;
console.log(space + '空值'); // result:null空值
console.log(space + 1); // result:1
进制
- 八进制:数字前加0,表示八进制
// 八进制表示 0 ~ 7
var num = 010;
- 十六进制:数字前加0x,表示十六进制
// 十六进制表示 0 ~ 9 a ~ f
var = 0x9;
获取数据类型
// 获取变量的数据类型
var num = 10;
console.log(typeof num);
var date = null;
console.log(typeof date); // 结果输出类型为 object!!!
// 判断对象类型
var arr = [];
console.log(arr instanceof Array);
console.log(Array.isArray(arr)); // H5的新功能 ,IE9以上才支持。
数据类型转换
数字转换成字符串
// 数字转换成字符串 toString()
var num = 1;
alert(num.toString());
// 数字转换成字符串 String()
var num = 1;
alert(String(num));
// 加号拼接字符串,也称隐士转换
var num = 1;
console.log(num + '');
字符串转换成数字
var age = '18';
var price = '18.88'
// parseInt(string)函数,将string类型转换为整数数值型
console.log(parseInt(age)); // 18
console.log(parseInt(3.14)); // 3,取整
console.log(parseInt(3.94)); // 3,取整不进位
console.log(parseInt(120px)); // 120,会去掉单位
// parseFloat(string)函数,将string类型转为成浮点数数值型
console.log(parseFloat(price)); // 18.88
// Number()强制转换函数,将string类型转换为数值型
console.log(Number(age)); // 18
console.log(Number(price)); // 18.88
// js隐士转换(-*/) 利用算术运算隐士转换为数值型
console.log('18' - 0); // 18
console.log('15' * 1); // 15
console.log('16' / 1); // 16
转换成布尔值
// 代表空、否定的值会被转换成false,如:''、0、NaN、null、undefined。其余值都会转换成true。
console.log(Boolean('')); //false
console.log(Boolean('true')); //true
运算符
算术运算符
// + 加
// - 减
// * 乘
// / 除
// % 取余
// 不要直接判断两个浮点数是否相等
// 因为浮点数精度,运算时会出问题
表达式和返回值
// 任何表达式都会有一个返回值
var num = 1 + 1;
递增和递减运算符
var num = 1;
// 前置递增,先自加1后返回值
// ++num; 等同于 num = num + 1;
console.log(++num + 15); // 17
// 后置递增,先返回原值后自加
// num++; 等同于 num = num + 1;
console.log(num++ + 15); // 16
// 此时num的值已从1自加成2
console.log(num); // 2
var num1 = 5;
// 前置递减,先自减1后返回值
// num1; 等同于 num1 = num1 - 1;
console.log(--num1 + 15); // 19
// 后置递减,先返回原值后自减
// num1--; 等同于 num1 = num1 - 1;
console.log(num-- + 15); // 20
// 此时num1的值已从5自减成4
console.log(num1--); // 4
var num2 = 20;
var result = num2++ + ++num2; // 42
// num++ 和 ++num 单独使用时没有任何区别
// num-- 和 --num 单独使用时没有任何区别
比较运算符
// 比较运算符中的等于是 ==
console.log(25 == '25'); // true == 会默认转换数据类型
// 比较运算符中的不等于是 !=
console.log(25 != '25'); // false != 会默认转换数据类型
// 比较运算符中的全等是===
console.log(18 === 18); // true
console.log(18 === '18'); // false 要求值和数据类型完全一致
// 比较运算符中的不全等于是!==
console.log(18 !== 18); // false
console.log(18 !== '18'); // true
逻辑运算符
- && - 与
// 两边都为true才为true
console.log(3 > 5 && 6 > 4); // false
console.log(3 < 5 && 6 > 4); // true
- || - 或
// 两边都为false才为false,否则就是true
console.log(3 > 5 || 6 > 4); // true
console.log(3 > 5 && 6 < 4); // false
- ! - 非
console.log(!true); // false
console.log(!(3 > 5)); // true
短路运算(逻辑中断)
当有多个表达式(值)时,左边的表达式值可以确定结果时,就不再继续运算右边的表达式的值。
// 为值的时候,除了0 '' null undefined NaN全是真
// 如果第一个表达式的值为真,则返回表达式2
// 如果第一个表达式的值为假,则返回表达式1
console.log(123 && 456); // 456
console.log(0 && 456); // 0
console.log(0 && 1 + 2 && 342 * 523); // 0
// 如果第一个表达式的值为真,则返回表达式1
// 如果第一个表达式的值为假,则返回表达式2
console.log(123 || 456); // 123
console.log(0 || 456); // 456
console.log(0 || 1 + 2 || 342 * 523); // 3
var num = 0;
console.log(123 || num++);
console.log(num); // 0 , 逻辑中断,num++不运算。
赋值运算符
var num = 10;
num = num + 1; num++;
num = num + 2; num += 2;
num = num - 2; num -= 2;
num = num * 2; num *= 2;
num = num / 2; num /= 2;
num = num % 2; num %= 2;
运算符的优先级
优先级 | 运算符 | 顺序 |
---|---|---|
1 | 小括号 | () |
2 | 一元运算符 | ++ - - ! |
3 | 算术运算符 | 先* / 后 + - |
4 | 关系运算符 | > >= < <= |
5 | 相等运算符 | == != === !== |
6 | 逻辑运算符 | 先 与 后 或 |
7 | 赋值运算符 | = |
8 | 逗号运算符 | , |
流程控制
IF语法结构
if (条件表达式) {
// 执行语句1;
};
if (条件表达式) {
// 执行语句1;
} else {
// 执行语句2;
};
if (条件表达式1) {
// 执行语句1;
} else if (条件表达式2) {
// 执行语句2;
} else {
// 执行语句3;
};
三元表达式
// 如果表达式条件为真,则返回表达式1的值,如果表达式条件为假,则返回表达式2的值
var num = 10;
var result = num > 5 ? 'Yes' : 'No';
SWITCH 语句
// 表达式条件值 和case后面的值是全等条件
switch (表达式) {
case value1:
执行语句1;
break;
case value2:
执行语句2;
break;
...
default:
执行最后的语句;
};
循环
for 循环
for (初始化变量; 条件表达式; 操作表达式) {
// 循环体
};
for (var i = 1; i<=100; i++) {
console.log('Hello World!');
};
//------------------------------------------
var sum = 0
for (var i = 1; i <= 100; i++) {
sum += i;
};
console.log(sum)
while 循环
// 当条件表达式为真时执行循环体
while (条件表达式) {
// 循环体代码
}
do while 循环
// 先执行一次循环体,在判断条件
do {
// 循环体代码
} while (条件表达式)
Continue
用于立即跳出本循环,继续下一循环。
Break
用于立即跳出整个循环。
复杂数据类型
数组
一组数据的集合。
创建数组
// new 关键字创建数组
var arr = new Array(2); // 2代表数组的长度
var arr2 = new Array(2, 3); // 2和3代表数组元素
var arr1 = new Array();
// 利用数组字面量创建数组
var arr2 = [];
var arr3 = [1,2,3,4,5,true,'P']; // 元素用逗号分开,元素的类型可以是任意类型。
数组的索引
用来访问数组元素的序号(数组下标从0开始)
// 访问数组元素
var arr3 = [1,2,3,4,5,true,'P'];
console.log(arr3[3]);
// 遍历数组
// arr3.length 数组的长度是元素的个数
for (i = 0; i < arr3.length; i++) {
console.log(arr[i]);
}
新增数组元素
可以通过修改length长度
var arr = [1,2,3,4,5,true,'P'];
arr.length = 10;
可以通过修改索引号
var arr = [1,2,3,4,5,true,'P'];
arr[8] = 'R';
arr[13] = 'U';
// push 在数组的末尾添加一个或者多个元素,push有返回值,是数组的长度。
var arr = [1,2,3,4,5,true,'P'];
arr.push(4,'S');
// unshift 在数组的最前面添加一个或者多个元素, unshift有返回值,是数组的长度。
arr.unshift(0,'G');
// pop 删除数组的最后一个元素, 返回值是删除的元素。
arr.pop();
// shift 删除数组的第一个元素, 返回值是删除的元素。
arr.shift();
// reverse 翻转数组。
arr.reverse();
// sort 排序数组。
var arrSort = [1,12,73,4,5]
arrSort.sort(); // 数组元素超过一位的时候排序会有问题,sort是按照第一位的大小进行排序
// 解决方法
arrSort.sort(function(a, b) {
return a - b; // 升序
// return b - a; // 降序
});
// indexOf返回数组元素的索引,从前往后, 未发现元素返回-1
arr.indexOf('5');
// lastIndexOf返回数组元素的索引,从后往前, 未发现元素返回-1
arr.lastIndexOf('5');
数组转换为字符串
var arr = [1, 2, 3];
// 1. toString
arr.toString(); // 1,2,3
// 2. join
arr.join(); // 1,2,3
arr.join('-') // 1-2-3
其他众多方法可以去MDN查询
// concat()
// slice()
// splice()
冒泡排序
冒泡排序是一种简单的排序算法,它重复的走过要排序的数列,一次比较两个元素,如果他们的顺序错误就把它们交换过来。走访数列的工作是重复的进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。
var arr = [4, 3, 5, 1, 7];
for (var i = 0; i <= arr.length - 1; i++) { // 外循环,用来确定比较几轮
// arr.length - i 内循环都走完之后会确定一个最大值,
// 所以下一轮的内循环不需要arr.length - 1的次数,
// 只需要arr.length - 1再减去外循环的次数i即可,不需要做无用的比较。
for (var j = 0; j <= arr.length - i - 1; j++) { // 内循环,用来做每轮的交换次数
if (arr[j] > arr[j + 1]) {
var tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
console.log(arr);
函数
- 声明函数
function 函数名() {
// 函数体
}
- 调用函数
function sayHello() {
console.log('Hello World!');
sayHello();
}
- 函数的参数
// 1. 形参
function 函数名(形参1, 形参2, 形参3) {
// 函数体
}
// 2. 实参
函数名(实参1, 实参2, 实参3);
// 形参无实参传递值时,为undefined类型。
// 3. 函数的返回值
function 函数名() {
// return 需要返回的结果;
}
function getAge (age) {
return age;
}
console.log(getAge(18));
// return 后面的代码不会执行,并且只能返回一个值(最后一个值)
// 返回多个值可以放到数组里实现 return [1,2,3,4];
// 没有写return的话函数就返回undefined
arguments
函数的一个内置对象,所有函数都有,arguments对象存储了传递的所有实参。
arguments是一个伪数组(具有数组的length属性、按照索引的方式进行存储、它没有真正数组的一些方法)
function arg(){
console.log(arguments);
}
arg(1,2,3);
函数表达式声明函数,由于函数没有名字也叫匿名函数。
var 变量名 = function (){
console.log('函数表达式');
};
// 调用
变量名();
函数的形参可以看成是局部变量
如果函数内部没有声明直接赋值的变量也属于全局变量
在JS中,es6中才增加的块级作用域,es6之前是没有块级作用域的。
块级作用域 {} , if {} 、 for {} 作用域链,内部函数可以访问外部函数的变量。
预解析
JS引擎运行js分两步:预解析、代码运行
JS引擎会把js里面所有的var还有function提升到当前作用域的最前面
变量预解析
又叫变量提升,就是把所有的变量声明提升到当前作用域的最前面,不提升赋值操作。
函数预解析
又叫函数提升,就是把所有的函数声明提升到当前作用域的最前面,不调用函数。
对象
创建对象
字面量创建
// var obj = {};
var obj = {
uname: '',
age: 20,
sex: '男'
sayHello: function () {
console.log('Hello World!');
}
};
// 调用对象方法
console.log(obj.uname);
console.log(obj['sex']);
obj.sayHello();
new Object创建对象
var obj = new Object();
obj.uname = 'Pianpianluoye';
obj.age = 20;
obj.sex = '男';
obj.sayHello = function() {
console.log('Hello World!');
}
利用构造函数创建对象
构造函数,是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new运算符一起使用。
// 构造函数名,首字母大写。因为new会返回这个新对象,所以构造函数里不需要return。
function Employees(uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sayHello = function(say) {
console.log(say);
}
}
var pply = new Employees('Pianpianluoye', 25, '男');
console.log(pply.name);
console.log(pply['age']);
pply.sayHello('Hello World!');
遍历对象
for (var k in obj) {
console.log(k); // 输出的是属性名
console.log(obj[k]); // 输出的是属性值
}
内置对象
对象分为:自定义对象、内置对象、浏览器对象
MDN Web文档
堆和栈
- 栈:由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据库中的栈;
简单数据类型存放到栈里,存放的是值。- 堆:存储复杂类型,一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
复杂数据类型,首先在栈里面存储地址(十六进制表示),然后将这个地址指向堆里面的数据
================================分割线=====================================
DOM
文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口。
- 文档:一个页面就是一个文档,DOM中使用document表示
- 元素:页面中的所有标签都是元素,DOM中使用element表示
- 节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示
- DOM把以上内容都看作是对象
获取元素
通过ID获取
getElementById()
<div id = "time">2021-02-07</div>
<script>
var timer = document.getElementById('time'); // 返回的是一个元素对象
console.dir(timer); // 打印输出,更好的查看timer里面的属性和方法
</script>
通过标签名获取
getElementByTagName()
<body>
<ul id = "ul">
<li id="li1" class="li">test1</li>
<li id="li2" class="li">test2</li>
<li>test3</li>
<li>test4</li>
<li>test5</li>
</ul>
<script>
var lis = document.getElementsByTagName("li");
console.log(lis);
console.log(lis[0]);
// 根据父元素获取子元素
var ul = document.getElementsByTagName('ul');
console.log(ul[0].getElementsByTagName('li'));
var ul1 = document.getElementById('ul');
console.log(ul1.getElementsByTagName('li'));
// 根据类名获取元素 H5新功能
var lis = document.getElementsByClassName('li');
console.log(lis);
// 使用querySelector 返回指定选择器的第一个元素对象 H5新功能
var firstLi1 = document.querySelector('.li'); // 通过类名选择器查询
console.log(firstLi1);
var firstLi2 = document.querySelector('#li1') // 通过ID选择器查询
console.log(firstLi2);
var firstLi3 = document.querySelector('li') // 通过标签选择器查询
console.log(firstLi3);
// 使用querySelectorAll 返回指定选择器的所有元素对象 H5新功能
var firstLiAll = document.querySelector('li') // 通过标签选择器查询
console.log(firstLiAll);
</script>
</body>
获取body标签
var bodyElement = document.body;
获取html标签
var htmlElement = document.documentElement;
事件
传统注册事件
// 1. 获取事件源
// 2. 注册事件(绑定事件)
// 3. 添加事件处理程序
<button id="btn">test</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
alert('Hello World!');
}
</script>
监听注册事件
addEventListener() 方法 |
<body>
<button>监听注册事件</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', function () {
alert('监听事件!');
})
</script>
</body>
删除事件(解绑事件)
传统方法 |
eventTarget.onclick = null;
监听方法 |
// eventTarget.removeEventListener(type,listener[,useCapture]);
<body>
<button>解绑注册事件</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', fn) // 里面的fn函数不需要加小括号()
function fn() {
alert('监听事件!');
btn.removeEventListener('click', fn);
}
</script>
</body>
DOM事件流
事件流描述的是从页面中接收事件的顺序。
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。
<body>
<div>
<button>捕获/冒泡阶段</button>
</div>
<script>
var btn = document.querySelector('button');
// 捕获阶段:如果addEventListener的第三个参数为true则为捕获阶段,document->html->body->div->button
// btn.addEventListener('click', function () {
// alert('捕获阶段btn');
// }, true)
// var div = document.querySelector('div');
// div.addEventListener('click', function () {
// alert('捕获阶段div');
// }, true)
// 冒泡阶段:如果addEventListener的第三个参数为false或者空则为捕获阶段, button->div->body->html->document
btn.addEventListener('click', function () {
alert('捕获阶段btn');
}, false)
var div = document.querySelector('div');
div.addEventListener('click', function () {
alert('捕获阶段div');
}, false)
</script>
</body>
注意:有些事件是没有冒泡的。
事件对象
// event 就是一个事件对象,写在侦听函数里,event可以随意命名比如evt、e等
// 考虑兼容问题IE 6\7\8要写window.event
// e = e || window.event; 解决兼容问题
div.onclick = function(event){}
阻止对象默认行为
// 监听注册方式
e.preventDefault(); // 方法,标准写法,推荐
// 传统注册方式
e.preventDefault(); // 方法,标准写法,推荐
window.event..returnValue; // 属性,IE 6、7、8 使用
return false; // 缺点是return后面的语句不会再执行
阻止冒泡
e.stopPropagation();
// IE 6、7、8
window.event.cancelBubble = true;
事件委托(代理、委派)
不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
<body>
<ul>
<li>test1</li>
<li>test2</li>
<li>test3</li>
<li>test4</li>
<li>test5</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
e.target.style.backgroundColor = 'blue';
})
</script>
</body>
常用键盘事件
键盘事件 | 触发条件 |
---|---|
onkeyup | 按键被松开时触发 |
onkeydown | 按键被按下时触发 |
onkeypress | 按键被按下时触发 但是它不识别功能键:ctrl shift 箭头等 |
执行顺序:keydown -> keypress -> keyup
操作元素
element.innerText:从起始位置到终止位置的内容,但它去除html标签(不识别html标签),同时空格和换行也会去掉
element.innerHTML:从起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
<body>
<button id="btn">test</button>
<div>Hello World!</div>
<p></p>
<script>
// 1. 获取元素
var btn = document.getElementById('btn');
var div = document.querySelector('div');
// 2. 注册事件
btn.onclick = function () {
div.innerText = 'Hi!';
}
// 直接加载
var p = document.querySelector('p');
p.innerHTML = '<strong>Hello World!</strong>'; // 推荐使用innerHTML
</script>
</body>
表单元素
<body>
<button id="btn">test</button>
<input type="text" value="Hi">
<script>
// 1. 获取元素
var btn = document.getElementById('btn');
var input = document.querySelector('input');
// 2. 注册事件
btn.onclick = function () {
input.value = 'Hello World!'; // 表单里的值 文字内容是通过value来修改的
this.disabled = true; // this 指向的是事件函数的调用者btn
}
</script>
</body>
元素样式修改
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 200px;
height: 200px;
background-color: aqua;
}
</style>
</head>
<body>
<div></div>
<script>
// 1. 获取元素
var div = document.querySelector('div');
// 2. 注册事件
div.onclick = function () {
this.style.backgroundColor = 'blue';
this.style.width = '250px';
this.style.height = '250px';
}
</script>
</body>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.setting {
width: 200px;
height: 200px;
background-color: aqua;
}
.change {
width: 250px;
height: 250px;
background-color: rgb(43, 255, 0);
}
</style>
</head>
<body>
<div class="setting"></div>
<script>
// 1. 获取元素
var div = document.querySelector('div');
// 2. 注册事件
div.onclick = function () {
this.className = 'change'; // 会覆盖原有类名
this.className = 'setting change'; // 保留原有类名setting
}
</script>
</body>
切换背景图
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
background: url(images/1.jpg) no-repeat center top;
}
li {
list-style: none;
}
</style>
</head>
<body>
<ul class="test">
<li><img src="images/1.jpg"></li>
<li><img src="images/2.jpg"></li>
<li><img src="images/3.jpg"></li>
<li><img src="images/4.jpg"></li>
</ul>
<script>
// 1. 获取元素
var imgs = document.querySelector('.test').querySelectorAll('img');
// 2. 注册事件
for (var i = 0; i < imgs.length; i++) {
imgs[i].onclick = function () {
document.body.style.backgroundImage = 'url(' + this.src + ')';
}
}
</script>
</body>
自定义属性操作: H5约束命名都以"data-"开头
// 获取属性值
<body>
<div id="test" data-index="1" data-select-index="X"></div>
<script>
var div = document.querySelector('div');
console.log(div.id); // 获取内置属性值
console.log(div.getAttribute('data-index')); // 主要获取自定义属性值
// H5 新增获取自定义属性值的方法, IE11 以上才支持
console.log(div.dataset.index);
console.log(div.dataset['index']);
// 自定义属性中有多个-时,按驼峰命名法的名字获取属性值 , IE11 以上才支持
console.log(div.dataset.selectIndex);
console.log(div.dataset['selectIndex']);
</script>
</body>
// 设置属性值
<body>
<div id="test" data-index="1" class="nav"></div>
<script>
var div = document.querySelector('div');
div.id = 'changeTest'; // 设置内置属性值
div.setAttribute('data-index', 2); // 主要设置自定义属性值
div.className = 'nav2';
div.setAttribute('class', 'footer');
</script>
</body>
// 移除属性值
<body>
<div id="test" data-index="1" class="nav"></div>
<script>
var div = document.querySelector('div');
div.removeAttribute('data-index');
</script>
</body>
节点操作
利用父子兄节点关系获取元素,逻辑性强,但兼容性稍差。
一般,节点至少拥有nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)这个三个基本属性。
- 元素节点 nodeType 为 1
- 属性节点 nodeType 为 2
- 文本节点 nodeType 为 3 (文本节点包含文字、控制、换行等)
node.parentNode // 获取最近父节点元素
parentNode.childNodes //标准方法 获取所有的子节点包含元素节点和文本节点(一个集合)
parent.children; //非标准方法,获取所有元素节点。推荐!
node.nextSibling; // 下一个兄弟节点,包含元素节点和文本节点
node.previousSibling; // 上一个兄弟节点,包含元素节点和文本节点
node.nextElementSibling; // 下一个元素节点 IE9以上支持
node.previousElementSibling; // 上一个元素节点 IE9以上支持
创建节点
<body>
<ul></ul>
<script>
// 1. 创建节点
var li = document.createElement('li');
</script>
</body>
添加节点
<body>
<ul></ul>
<script>
var li = document.createElement('li');
// 2. 添加节点
var ul = document.querySelector('ul');
ul.appendChild(li); // 在后面追加节点
</script>
</body>
<body>
<ul>
<!-- <li></li> -->
</ul>
<script>
// 1. 创建节点
var li = document.createElement('li');
// 2. 添加节点
var ul = document.querySelector('ul');
ul.appendChild(li); // 在后面追加节点
// 3.
var a = document.createElement('a');
ul.insertBefore(a, ul.children[0]); // ul里的第一个元素前添加元素
</script>
</body>
删除节点
<body>
<button>Delete Node</button>
<ul>
<li>Li1</li>
<li>Li2</li>
<li>Li3</li>
<li>Li4</li>
<li>Li5</li>
</ul>
<script>
// 1. 获取元素
var ul = document.querySelector('ul');
var btn = document.querySelector('button');
// 2.删除元素
// ul.removeChild(ul.children[0]);
btn.onclick = function () {
if (ul.children.length == 0) {
this.disabled = true;
} else {
ul.removeChild(ul.children[0]);
}
}
</script>
</body>
克隆节点
<body>
<button>Clone Node</button>
<ul>
<li>Li1</li>
<li>Li2</li>
</ul>
<script>
// 1. 获取元素
var ul = document.querySelector('ul');
var btn = document.querySelector('button');
// 2.删除元素
// ul.removeChild(ul.children[0]);
btn.onclick = function () {
// cloneNode(); 括号内为空或者false为浅克隆只复制标签不复制内容,为true时为深克隆
var cloneLi = ul.children[0].cloneNode();
ul.appendChild(cloneLi);
}
</script>
</body>
BOM
BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window。
window具有双重身份,既是js访问浏览器的接口,也是一个全局对象。
window对象的常见事件
窗口加载事件
window.onload = function () {}
// 或
window.addEventListener('load', function () { });
document.addEventListener('DOMContentLoaded ', function () { });
事件 | 说明 |
---|---|
load | 等页面内容全部加载完毕,包含页面DOM元素 图片 CSS等 |
DOMContentLoaded | DOM加载完毕就可以执行 |
定时器
1. setTimeout()
<script>
// 单位毫秒
// setTimeout(function () {
// alert('时间到了!');
// }, 2000)
function time() {
alert('时间到了!');
}
setTimeout(time, 3000);
// setTimeout('time()', 3000); // 不提倡这么写
var time1 = setTimeout(time, 3000); // time1 被称为标识符
</script>
clearTimeout(time1); // 关闭定时器
2. setInterval()
重复调用一个函数,每隔这个时间就去调用一个回调函数。
setInterval(time, 3000);
var time1 = null;
btn.addEventListener('click', function() {
time1 = setInterval(function () {
....
}, 1000);
})
clearInterval(time1);
执行机制
JS是单线程语言,在HTML5提出Web Worker标准后利用多核CPU的计算能力,允许JS脚本创建多个线程。于是JS中出现了同步和异步。 |
1. 先执行执行栈中的同步任务。
2. 异步任务(回调函数)放入任务队列中。
3. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环(event loop)
同步任务
同步任务都在主线程上执行,形成一个执行栈。
异步任务
JS的异步是通过回调函数实现的。一般而言异步任务有以下三种类型:
- 普通事件,如click、resize等
- 资源加载,如load、error等
- 定时器,包括setInterval、setTimeout等
异步任务相关回调函数添加到任务队列中(任务队列也称消息队列)
location对象
window对象给我们提供了一个location属性用于获取或设置窗体的URL(Uniform Resource Locator 统一资源定位符),并且可以用于解析URL。
protocol://host[:port]/path/[?query]#fragment |
组成 | 说明 |
---|---|
protocol | 通信协议 常用的http, ftp, maito等 |
host | 主机(域名)www.baidu.com |
port | 端口号 可选,省略时使用方案的默认端口 如http是80 |
path | 路径 由 零或多个’/'符号隔开的字符串,一般用来表示主机上的一个目录或文件地址 |
query | 参数 以键值对的形式通过&符号分隔开来 |
fragment | 片段 #后面内容 常见于链接 锚点 |
location对象的属性
对象属性 | 返回值 |
---|---|
location.href | 获取 或 设置整理URL |
location.host | 返回主机(域名) |
location.port | 返回端口号 如果未写返回空字符串 |
location.pathname | 返回路径 |
location.search | 返回参数 |
location.hash | 返回片段 |
location对象的方法
对象方法 | 返回值 |
---|---|
location.assign() | 跟href一样,可以跳转页面(也称为重定向页面) |
location.replace() | 替换当前页面,因为不记录历史,所以不能后退页面 |
location.reload() | 重新加载页面,相当于刷新按钮或按F5 如果参数为true 强制刷新ctrl+f5 |
navigator对象
该对象包含有关浏览器的信息,最常用的是userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值。
history对象
对象方法 | 作用 |
---|---|
back() | 后退功能 |
forward() | 前进功能 |
go(参数) | 前进后退功能 参数如果是1 前进一个页面, 如果是-1 后退一个页面 |
网页端特效
元素偏移量 - offset
- 获得元素距离带有定位父元素的位置
- 获得元素自身的大小
- 返回的数值不带单位
offset常用属性
属性 | 作用 |
---|---|
element.offsetParent | 返回作为该元素带有定位的父级元素 如果父级元素没有定位则向上找,如果到body还没有就返回body 注意与parentNode的区别 |
element.offsetTop | 返回元素相对于带有定位的父级元素上方的偏移 |
element.offsetLeft | 返回元素相对于带有定位的父级元素左边框的偏移 |
element.offsetWidth | 返回自身包括padding、边框、内容区的宽度,返回值不带单位 |
element.offsetHeight | 返回自身包括padding、边框、内容区的高度,返回值不带单位 |
offset与style的区别
offset | style |
---|---|
可以得到任意样式表中的样式值 | 只能得到行内样式表中的样式值 |
获取的值没有单位 | 获取的是带有单位的字符串 |
Width属性包含padding+border+width | width不包含padding和border的值 |
Width等属性是只读属性 | width等是可读写属性 |
获取元素的大小位置offset比较合适 | 更改元素值需要用style |
元素可视区 - client
client翻译过来就是客户端,我们使用client系列的相关属性来获取元素可视区的相关信息。通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。
client系列属性 | 作用 |
---|---|
element.clientTop | 返回元素上边框的大小 |
element.clientLeft | 返回元素左边框的大小 |
element.clientWidth | 返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位 |
element.clientHeight | 返回自身包括padding、内容区的高度,不含边框,返回数值不带单位 |
立即执行函数
不需要调用,立刻就能执行的函数。
// 两种写法
(function (形参1, 形参2) { })(实参1, 实参2);
(function () { }());
最大的作用:立即执行函数里面所有的变量都是局部变量。
元素滚动 - scroll
scroll系列属性 | 作用 |
---|---|
element.scrollTOP | 返回被卷去的上侧距离,返回值不带单位 |
element.scrollLeft | 返回被卷去的左侧距离,返回值不带单位 |
element.scrollWidth | 返回自身实际的宽度,不含边框,返回值不带单位 |
element.scrollHeight | 返回自身实际的高度,不含边框,返回值不带单位 |
三大系列对比
系列 | 作用 |
---|---|
element.offsetWidth | 返回自身包括padding、边框、内容区的宽度,返回值不带单位 |
element.clientWidth | 返回自身包括padding、内容区的宽度,不含边框,返回值不带单位 |
element.scrollWidth | 返回自身实际的宽度,不含边框,返回值不带单位 |
注意页面滚动的距离通过window.pageXOffset获得
mouseenter和mouseleave不会冒泡
移动端端特效
touch触屏事件
触屏touch事件 | 说明 |
---|---|
touchstart | 手指触摸到一个DOM元素时触发 |
touchmove | 手指在一个DOM元素上滑动时触发 |
touchend | 手指在一个DOM元素上移开时触发 |
触摸事件对象(TouchEvent)
触摸列表 | 说明 |
---|---|
touches | 正在触摸屏幕的所有手指的一个列表 |
targetTouches | 正在触摸当前DOM元素上的手指的一个列表 |
changedTouches | 手指状态发生了改变的列表,从无到有,从有到无变化 |
本地存储
- 数据储存在用户浏览器中
- 设置、读取方便,甚至页面刷新不丢失数据
- 容量较大,sessionStorage约5M、localStorage约20M
- 只能存储字符串,可以将对象JSON.stringify()编码后存储
window.sessionStorage
- 生命周期为关闭浏览器窗口
- 在同一个窗口(页面)下数据共享
- 以键值对的形式存储使用
存储数据
sessionStorage.setItem(key,value)
获取数据
sessionStorage.getItem(key)
删除数据
sessionStorage.removeItem(key,value)
删除所有数据
sessionStorage.clear()
window.sessionStorage
- 生命周期永久生效
- 可以多窗口(页面)共享(同一浏览器可以共享)
- 以键值对的形式存储使用
存储数据
localStorage.setItem(key,value)
获取数据
localStorage.getItem(key)
删除数据
localStorage.removeItem(key,value)
删除所有数据
localStorage.clear()
-------------------------------------------------------------------------
前往下一篇文章-jQuery初学