文章目录
使用<script></script>标签引入,放在
body
底部
<script src='index.js'></script>
模板字符串
let firstName = "胡";
let lastName = "雪岩";
let say = `大家好,我姓${firstName},名${lastName}`;
console.log(say);
ECMAScript
基础数据类型
-
变量
-
let:可赋值变量声明
-
const:不可改变的常量声明,需要初始化
-
-
数值类型
整数,浮点数,非数值类型:NaN
-
类型转换/字符串拼接
- 隐式转换
- 数字字符串加数字,数字隐式转换为字符串
- 数字字符串与数字非加法运算,字符串转换为数字
- 数字字符串与数字字符串非加法运算,字符串隐式转换为数字
- 强制类型转换
- parseInt:将小数,整数,小数转换为整数
- parseFloat:将小数字符串转换为小数
- 隐式转换
-
运算符
== : 判断值相同
=== :后者在==基础上判断类型
-
数组
-
声明定义
-
let arr2 = new Array(1,2,'arr');
-
[1,2,'arr']
-
-
操作
-
增push(从尾加),unshift(从头加)
-
删pop(从尾删),shift(从头删)
-
改splice
//一个参数删除从开始到结束位置的所有元素,并返回删除元素 //两个参数从第一个参数往后删除第二个参数的个数 //第三个参数为替换元素
- 第一个值,整数类型,表示起始位置
- 第二个值,整数类型,表示步长(往后选几个元素,1 代表往后选 1 个元素)
- 第三个参数,要替换的数组的值
-
查indexOf
第一个参数:查询数组中参数的索引没有返回-1
第二个参数:规定开始查找位置
-
-
函数
-
自定义函数
-
用function命令声明
function 函数名称() { 函数体; }
-
函数表达式声明(匿名函数)
let 变量名 = function() { 函数体; }
let print = () => { console.log("JavaScript 真有趣"); };
-
函数声明提升:采用function命令声明可提升函数声明到顶部
-
以上两种声明方式区别
- 结尾的大括号后是否需要加“;”:
- function 命令声明:结尾的大括号后不需要加“;”
- 函数表达式:结尾的大括号后需要加“;”
- 有无声明提升:
- function 命令声明:有提升;
- 函数表达式:没有提升;
-
立即执行函数(IIFE)
(function() { console.log("这个函数只执行一次"); })();
-
-
内置函数——计时器
-
延时执行 setTimeout():用来指定某个函数或某段代码,在多少毫秒后执行,返回一个表示定时器编号的整数
let timerId = setTimeout(fun|code, delay);
console.log(1); /** * 第一个参数是代码,注意代码需用引号包裹,否则会立即执行代码 * 第二个参数是 1000,即 1000ms 后执行 console.log(2) */ setTimeout('console.log(2)', 1000); /** * 第一个参数是匿名函数 * 第二个参数是 2000,即 2s 后执行 console.log(3) */ setTimeout(function () { console.log(3); }, 2000); // 第一个参数是函数名,注意函数名后不要加小括号“()”,否则会立即执行 print4 setTimeout(print4, 3000); console.log(5); function print4() { console.log(4); }
1; 5; 2; 3; 4;
倒计时实现(递归)
// 首先定义计时总秒数,单位 s let i = 60; // 定义变量用来储存定时器的编号 let timerId; // 写一个函数,这个函数即每次要执行的代码,能够完成上述的 1、2、3 function count() { console.log(i); i--; if (i > 0) { timerId = setTimeout(count, 1000); } else { // 清除计时器 clearTimeout(timerId); } } // 首次调用该函数,开始第一次计时 count();
-
无限调用setInterval
let timerId = setInterval(func|code, delay);
-
对象
-
js的对象就是一组“键值对”集合,创建对象可以通过字面量方法和构造函数法
// 第一步:创建构造函数 function People(name, age) { this.name = name; this.age = age; } // 第二步:通过 new 创建对象实例 let person = new People('henry', 18); console.log(person);
-
自定义对象的属性操作
- 读取属性:点运算符和方括号运算符
- 属性的赋值:同上;
- 属性查看Object.keys(对象名):返回一个属性名数组
- 属性删除:delete 对象.对象属性,增加同赋值
-
遍历对象属性
-
for… in
let person = { name: 'henry', age: 18, } for (let key in person) { console.log('键名:' + key + ';键值:' + person[key]); }
-
Object.keys
let person = { name: 'henry', age: 18, } let keys = Object.keys(person); for (let i = 0; i < keys.length; i++) { console.log('键名:' + keys[i] + ';键值:' + person[keys[i]]); }
-
-
对象的继承:通过构造函数Object()或者“继承创建对象”
// 字面量 let o1 = { name: 'alice', }; // 构造函数 let o2 = new Object(); let o3 = new Object(); // 继承 funtion O4() { }; O4.prototype = o1; let o4 = new O4();
-
原型:继承的上一级对象
-
属性是否存在:in
let person = { name: 'henry', age: 18, }; 'name' in person; 'gender' in person; 'toString' in person
-
自身属性是否存在:hasOwnProperty
let person = { name: 'henry', age: 18, }; person.hasOwnProperty('name'); person.hasOwnProperty('gender'); person.hasOwnProperty('toString');
-
Object、JSON、Map
-
JOSN=》JavaScript
// 一个 JSON 字符串 const jsonStr = '{"sites":[{"name":"Runoob", "url":"www.runoob.com"},{"name":"Google", "url":"www.google.com"},{"name":"Taobao", "url":"www.taobao.com"}]}'; // 转成 JavaScript 对象 const obj = JSON.parse(jsonStr);
-
JavaScript=》JSON
const jsonStr2 = JSON.stringify(obj);
-
-
内置对象
-
Math
Math.E // 常数e。 Math.LN2 // 2 的自然对数。 Math.LN10 // 10 的自然对数。 Math.LOG2E // 以 2 为底的e的对数。 Math.LOG10E // 以 10 为底的e的对数。 Math.PI // 常数π。 Math.SQRT1_2 // 0.5 的平方根。 Math.SQRT2 // 2 的平方根。
Math.abs() // 绝对值 Math.ceil() // 向上取整 Math.floor() // 向下取整 Math.round() // 四舍五入取整 Math.max() // 最大值 Math.min() // 最小值 Math.pow() // 指数运算 Math.sqrt() // 平方根 Math.log() // 自然对数 Math.exp() // e的指数 Math.random() // 随机数
-
Storage
-
sessionStrorage:保存一次会话数据
-
localStorage:保存数据长期存在
-
数据存入setItem
window.localStorage.setItem('key', 'value)
-
读数据getItem
window.localStorage.getItem('key');
-
清楚缓存
window.localStorage.clear();
3.String
-
let len = 'here is an apple'.length; let str = 'here is an apple'; const index = str.indexOf('an'); console.log(index); // 'here' 之前有一个空格,'apple' 之后有三个空格 let str = ' here is an apple '; const trimedStr = str.trim();//str不变 console.log(str.length); console.log(trimedStr.length);
- substring(start, end): start —— 要截取的字符串的开始下标 end —— 要截取的字符串的结束下标。
- substr(start, len): start —— 要截取的字符串的开始下标 len —— 要截取的字符串的长度。
const splitedStr = 'a|b|c'.split('|'); console.log(splitedStr);
属性/方法 作用 str.length 返回字符串长度 str.indexOf(sub) 返回子字符串 sub 的开始下标,不存在则返回 -1
注意:这里的参数 sub 是个字符串变量str.trim() 字符串前后去空格 str.substring(s, e) 截取下标从 s 到 e 的子字符串
注意:这里的参数 s 和 e 是个数字变量str.substr(s, len) 截取下标从 s 开始,长度为 len 的子字符串
注意:这里的参数 s 和 len 是个数字变量str.split(pattern) 按规格 pattern 分割字符串
注意:这里的参数 pattern 是个字符串变量 -
-
Array
- 连接数组:join()
let arr = [1, 2, 3, 4]; arr.join(" "); // '1 2 3 4' arr.join(" | "); // "1 | 2 | 3 | 4" arr.join(); // "1,2,3,4"
- reverse()
let arr = ["a", "b", "c"]; arr.reverse(); // ["c", "b", "a"] arr; // ["c", "b", "a"]
- sort()
let arr = [ { name: "jenny", age: 18 }, { name: "tom", age: 10 }, { name: "mary", age: 40 }, ]; arr.sort(function (a, b) { return a.age - b.age; }); console.log(arr);
-
遍历map/forEach
-
let arr = [ { name: "jenny", age: 18 }, { name: "tom", age: 10 }, { name: "mary", age: 40 }, ]; // elem: 数组成员 // index: 成员下标 // a: 整个数组 const handledArr = arr.map(function (elem, index, a) { elem.age += 1; console.log(elem, index, a); return elem.name; }); console.log(arr); console.log(handledArr);
-
const handledArr = arr.forEach(function (elem, index, a) { elem.age += 1; console.log(elem, index, a); return elem.name; }); console.log(handledArr);
属性/方法 作用 arr.join(pattern) 按规则 pattern 连接数组,返回字符串 arr.reverse() 将原数组倒序排列 arr.sort(func) 自定义排序,根据传入的参数函数 func 将数组成员排序 arr.map(func) 根据传入的参数函数 func 对数组进行遍历操作,返回操作后的数组
函数有三个参数,依次为:数组成员、对应下标、整个数组arr.forEach(func) 根据传入的参数函数 func 对数组进行遍历操作,无返回值
函数有三个参数,依次为:数组成员、对应下标、整个数组-
Date
-
new Date()不加参数,返回当前时间
// 传入表示“年月日时分秒”的数字 let dt1 = new Date(2020, 0, 6, 0, 0, 0); console.log(dt1); // 传入日期字符串 let dt2 = new Date("2020-1-6"); console.log(dt2); // 传入距离国际标准时间的毫秒数 let dt3 = new Date(1578240000000); console.log(dt3);
-
日期运算
-
时间差:毫秒
// 传入表示“年月日时分秒”的数字 let dt1 = new Date(2020, 0, 6, 0, 0, 0); console.log(dt1); // 传入日期字符串 let dt2 = new Date("2020-1-6"); console.log(dt2); // 传入距离国际标准时间的毫秒数 let dt3 = new Date(1578240000000); console.log(dt3);
-
-
早晚比较:大小于符号
let dt1 = new Date(2020, 2, 1); let dt2 = new Date(2020, 3, 1); console.log(dt1 > dt2); // false console.log(dt1 < dt2); // true
-
解析日期字符串:Date.parse()
let dt = Date.parse("2020-1-6"); console.log(dt); // 1578240000000
-
时间对象转时间字符串:to方法
let dt = new Date(); let dtStr = dt.toJSON(); console.log(dtStr); // 2020-01-03T09:44:18.220Z
-
获取时间对象的年/月/日:get方法
let dt = new Date(); dt.getTime(); // 返回实例距离1970年1月1日00:00:00的毫秒数。 dt.getDate(); // 返回实例对象对应每个月的几号(从1开始)。 dt.getDay(); // 返回星期几,星期日为0,星期一为1,以此类推。 dt.getFullYear(); // 返回四位的年份。 dt.getMonth(); // 返回月份(0表示1月,11表示12月)。 dt.getHours(); // 返回小时(0-23)。 dt.getMilliseconds(); // 返回毫秒(0-999)。 dt.getMinutes(); // 返回分钟(0-59)。 dt.getSeconds(); // 返回秒(0-59)。
-
设置时间对象的年/月/日:set方法
let dt = new Date(); dt.setTime(ms); // 设置实例距离1970年1月1日00:00:00的毫秒数。 dt.setDate(date); // 设置实例对象对应每个月的几号(从1开始)。 dt.setFullYear(year); // 设置四位的年份。 dt.setMonth(month); // 设置月份(0表示1月,11表示12月)。 dt.setHours(hour); // 设置小时(0-23)。 dt.setMilliseconds(ms); // 设置毫秒(0-999)。 dt.setMinutes(min); // 设置分钟(0-59)。 dt.setSeconds(sec); // 设置秒(0-59)。
-
-
-
-
BOM
- screen 是整个电脑唯一的
- navigator 是整个浏览器唯一的,如果有多个浏览器就会有多个 navigator
- window 是每个网页唯一的,每个网页都有一个独立的 window
- history,location 是每个网页的信息,当然也是网页唯一的
window对象(BOM的默认对象)
Location/History
属性 | 值 | 解释 |
---|---|---|
href | https://resource.youkeda.com/wss_test/5dc54e230f101ed7c2256d0d/5e33d104680dca7ebc7a223b/index.html?time=1580454161498 | href 是整个网页地址 |
hostname | resource.youkeda.com | hostname 是网页域名 |
host | resource.youkeda.com | host 是网页域名 + 端口信息,在这里端口默认 80 省略了,所有和 hostname 一样 |
protocol | https | protocol 代表协议信息 |
origin | https://resource.youkeda.com | origin 页面来源的域名的标准形式 |
pathname | /5dc54e230f101ed7c2256d0d/5e33d104680dca7ebc7a223b/index.html | pathname 包含 url 路径部分 |
search | ?time=1580454161498 | search 表示 URL 参数 |
Location方法:reload()
setTimeout(function () {
window.location.reload();
}, 3000);
跳转到新的地址
window.location = 'https://www.youkeda.com';
History:将原始网页存到一个栈中,back(),forward();
Navigator/Screen
- Navigator属性usesrAgent
DOM
初识DOM
- 树根是 DOCUMENT,也可以称为整个页面文档
- 每个 HTML 标签我们称之为 DOM 节点,英文为Node或者ELement
- 每个 HTML 标签包裹的子标签,在树上体现为分支,称为儿子节点。比如上图,
P
和H1
都是DIV
的儿子节点。DIV
同样也是BODY
的儿子节点。 - 儿子节点类推可以得知
P
,H1
是BODY
的孙子节点。 - 所有
P
,H1
的长辈,我们称为P
和H1
的祖先节点。 P
,H1
是亲兄弟,我们称为兄弟节点。
访问DOM
-
获取DOCUMENT
window.document
-
querySelector(‘css选择器’)
-
可以利用已经得到的对象进行迭代查询
let subtitle = document.querySelector('main .core .subtitle'); console.log(subtitle.querySelector('a'));
-
选择器全量查询querySelectorAll()//返回一个类数组
DOM属性
-
DOM类别
- 元素节点
- 特性节点
- 文本节点
- 。。。。
<!DOCTYPE html> <head> <meta charset="UTF-8" /> <title>优课达</title> </head> <body> <div id="test">优课达</div> <script src="./index.js"></script> </body>
let divDom = document.querySelector('div#test'); console.log(divDom.nodeType, divDom.nodeName, divDom.nodeValue); // 获取DIV节点的第一个儿子节点,代表 '优课达' 这个字符串 let txtDom = divDom.firstChild; console.log(txtDom.nodeType, txtDom.nodeName, txtDom.nodeValue); // 获取DIV节点的id属性 let attDom = divDom.attributes.id; console.log(attDom.nodeType, attDom.nodeName, attDom.nodeValue);
节点 nodeType nodeName nodeValue 类型 divDom 1 DIV null 元素节点 txtDom 3 #text 优课达 文本节点 attDom 2 id test 特性节点 -
DOM内容
<!DOCTYPE html> <head> <meta charset="UTF-8" /> <title>优课达</title> </head> <body> <div id="test"> 优课达 <p>youkeda</p> <p>学的比别人好一点</p> </div> <script src="./index.js"></script> </body>
let divDom = document.querySelector('div#test'); console.log(divDom.outerHTML, divDom.innerHTML, divDom.innerText);
属性 值 总结 outerHTML <div id="test">优课达<p>youkeda</p><p>学的比别人好一点</p></div>
整个 DOM 的 HTML 代码 innerHTML 优课达<p>youkeda</p><p>学的比别人好一点</p>
DOM 内部 HTML 代码 innerText 优课达
DOM 内部纯文本内容 -
DOM亲属
let divDom = document.querySelector('div#test'); console.log(divDom.firstChild, divDom.lastChild); console.log('-----'); console.log(divDom.childNodes); console.log('-----'); console.log(divDom.parentNode);
属性 值 总结 firstChild 优课达
指定节点的第一个子节点 lastChild <p>学的比别人好一点</p>
指定节点的最后一个子节点 childNodes 优课达<p>youkeda</p><p>学的比别人好一点</p>
指定节点的子节点的集合 parentNode <body><div id="test">优课达<p>youkeda</p><p>学的比别人好一点</p></div><script src="./index.js"></script></body>
指定节点在 DOM 树中的父节点 -
DOM样式
<!DOCTYPE html> <head> <meta charset="UTF-8" /> <title>优课达</title> </head> <body> <h1 class="test youkeda" style="color: #FF3300; font-size: 24px;">优课达</h1> <script src="./index.js"></script> </body>
const h1Dom = document.querySelector('h1'); console.log(h1Dom.classList); console.log(h1Dom.style); console.log(h1Dom.style.color)
属性 类型 值 总结 classList DOMTokenList
类数组['test', 'youkeda']
classList 数组方式存储所有的 class 名称 style CSSStyleDeclaration
color
属性为rgb(255, 51, 0)
对象或字典的方法存储 CSSStyle -
DOM数据属性
<!DOCTYPE html> <head> <meta charset="UTF-8" /> <title>优课达</title> </head> <body> <article data-parts="3" data-words="1314" data-category="python"> ... </article> <script src="./index.js"></script> </body>
const article = document.querySelector('article'); console.log(article.dataset);//返回Map
DOM操作
- 创建标签节点
document.createElement(tagName)
、创建文本内容document.createTextNode(string)
- 添加新节点
appendChild(newNode)
:在所有儿子节点后添加、indertBefore(newNode, referenceNode)
:在目标儿子节点之前添加 - 设置样式、属性
setAttribute('style', 'width: 100%; height: 100%;');
:全量设置属性,dom.style.color = 'xxxx';
单独设置属性 - innerHTML = ‘***’将内部元素全部换成***
DOM事件addEventListener(eventName, callback)
- 点击事件
addEventListener("click", function (event) {
函数体
});
event属性
属性 | 值 | 解释 |
---|---|---|
target | <h1>优课达-学的比别人好一点</h1> | 点击事件触发的 DOM 节点,真实响应事件的节点 |
type | click | 事件名称 |
pageX/pageY | 92/47 | 鼠标事件触发的页面坐标 |
-
冒泡、捕获、委托
-
冒泡:因为儿子节点的事件,找到父节点并触发知道html根元素。阻止冒泡
// ......省略 likeBtn.addEventListener('click', function(e) { // 点击事件 e.stopPropagation() // ......省略
-
捕获:事件从根结点开始移动到当前元素被捕获
dom.addEventListener('click', function() {}, true);
-
委托:用event.target来响应
-
-
移动事件
鼠标移动事件
在上一章中,我们在完成京东图片切换的时候,已经接触到鼠标移动事件了,本节课我们详细介绍一下这块知识。
在第一小节中,我们知道这些鼠标移动事件一共有 5 个如下:
mouseenter: 指针移到有事件监听的元素内。 mouseleave: 指针移出元素范围外(不冒泡)。 mousemove: 指针在元素内移动时持续触发。 mouseover: 指针移到有事件监听的元素或者它的子元素内。 mouseout: 指针移出元素,或者移到它的子元素上。
看这个内容还是很混乱,我们把它分类一下
1. mousemove
这个是鼠标移动事件,比较简单
2. mouseenter/mouseleave
这个是鼠标进入和离开事件,但是仅仅只作用于当前 DOM 节点,不会作用于其后代节点
3. mouseover/mouseout
这个也是鼠标进入和离开事件,但和
enter/leave
不同的是:此事件除了作用于当前 DOM 节点,也会同时作用于其后代节点在平时使用中,90%我们都只会使用mouseover/mouseout,这个事件。
-
表单元素事件
-
获取焦点focus,失去焦点blur
-
事件 介绍 案例 change
当用户提交对元素值的更改时触发; change 事件不一定会对元素值的每次更改触发 1. checkbox 值修改以后
2. select 选择后
3. input 内容修改并失去焦点input
只要 value 值修改就会触发
-
-
滚动事件
window.addEventListener('scroll', function () { console.log(window.scrollY); });
网络请求
-
GET请求
fetch( 'https://www.fastmock.site/mock/b73a1b9229212a9a3749e046b1e70285/f4/f4-11-1-1' ) .then(function (response) { return response.json(); }) .then(function (myJson) { console.log(myJson); });
-
POST请求
// 把JSON数据序列化成字符串 const data = JSON.stringify({ username: 'admin', password: '123456' }); fetch( 'https://www.fastmock.site/mock/b73a1b9229212a9a3749e046b1e70285/f4/f4-11-4-1', { method: 'POST', body: data, headers: { 'content-type': 'application/json' } } ) .then(function(response) { return response.json(); }) .then(function(myJson) { console.log(myJson); });
值修改以后
2. select 选择后
3. input 内容修改并失去焦点
input
只要 value 值修改就会触发
-
滚动事件
window.addEventListener('scroll', function () { console.log(window.scrollY); });
网络请求
-
GET请求
fetch( 'https://www.fastmock.site/mock/b73a1b9229212a9a3749e046b1e70285/f4/f4-11-1-1' ) .then(function (response) { return response.json(); }) .then(function (myJson) { console.log(myJson); });
-
POST请求
// 把JSON数据序列化成字符串 const data = JSON.stringify({ username: 'admin', password: '123456' }); fetch( 'https://www.fastmock.site/mock/b73a1b9229212a9a3749e046b1e70285/f4/f4-11-4-1', { method: 'POST', body: data, headers: { 'content-type': 'application/json' } } ) .then(function(response) { return response.json(); }) .then(function(myJson) { console.log(myJson); });