Javascript初学者笔记

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);

函数

  1. 声明函数
function 函数名() {
	// 函数体
}
  1. 调用函数
function sayHello() {
	console.log('Hello World!');
	sayHello();
}
  1. 函数的参数
// 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文档

堆和栈

  1. 栈:由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据库中的栈;
    简单数据类型存放到栈里,存放的是值。
  2. 堆:存储复杂类型,一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
    复杂数据类型,首先在栈里面存储地址(十六进制表示),然后将这个地址指向堆里面的数据
================================分割线=====================================

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() 方法
它是一个方法(推荐使用),IE9之前不支持可以使用attachEvent()代替
<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>

阻止链接跳转                  可以使用 javascript:void(0);或者javascript:;替换#来实现

克隆节点

<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 document location navigation screen history

window具有双重身份,既是js访问浏览器的接口,也是一个全局对象。

window对象的常见事件

窗口加载事件

window.onload = function () {}
// 或
window.addEventListener('load', function () { });
document.addEventListener('DOMContentLoaded ', function () { });
事件说明
load等页面内容全部加载完毕,包含页面DOM元素 图片 CSS等
DOMContentLoadedDOM加载完毕就可以执行

定时器

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的异步是通过回调函数实现的。一般而言异步任务有以下三种类型:

  1. 普通事件,如click、resize等
  2. 资源加载,如load、error等
  3. 定时器,包括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的区别

offsetstyle
可以得到任意样式表中的样式值只能得到行内样式表中的样式值
获取的值没有单位获取的是带有单位的字符串
Width属性包含padding+border+widthwidth不包含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手指状态发生了改变的列表,从无到有,从有到无变化

本地存储

  1. 数据储存在用户浏览器中
  2. 设置、读取方便,甚至页面刷新不丢失数据
  3. 容量较大,sessionStorage约5M、localStorage约20M
  4. 只能存储字符串,可以将对象JSON.stringify()编码后存储

window.sessionStorage

  1. 生命周期为关闭浏览器窗口
  2. 在同一个窗口(页面)下数据共享
  3. 以键值对的形式存储使用

存储数据

sessionStorage.setItem(key,value)

获取数据

sessionStorage.getItem(key)

删除数据

sessionStorage.removeItem(key,value)

删除所有数据

sessionStorage.clear()

window.sessionStorage

  1. 生命周期永久生效
  2. 可以多窗口(页面)共享(同一浏览器可以共享)
  3. 以键值对的形式存储使用

存储数据

localStorage.setItem(key,value)

获取数据

localStorage.getItem(key)

删除数据

localStorage.removeItem(key,value)

删除所有数据

localStorage.clear()

-------------------------------------------------------------------------
前往下一篇文章-jQuery初学

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值