单行注释//
,快捷键:ctrl + /
块注释/**/
,快捷键:shift + alt + A
document.write('输出内容')
alert('输出内容')
console.log('输出内容')
prompt('提示内容')
let 变量名 = 值
(let 不允许多次声明同一个变量)const 变量名 = 值
number(数字型)
string(字符串型)
boolean(布尔型)
undefined(未定义型)
null(空类型)
typeof运算符
typeof 变量 / typeof(变量)
//通过+运算符实现字符串拼接
document.write('大家好,我叫' + name + ',今年' + age + '岁')
//通过模板字符串实现字符串拼接
document.write(`大家好,我叫${name},今年${age}岁`)
Number(数据)
parseInt(数据)
parseFloat(数据)
String(数据)
变量.toString(进制)
+= -= *= /= %=
,对变量进行赋值的运算符++(自增) --(自减)
,前置自增(先自加再使用)后置自增(先使用再自加)>
左边是否大于右边<
左边是否小于右边=
左边是否大于或等于右边<=
左边是否小于或等于右边==
左右两边值是否相等===
左右两边是否类型和值都相等!==
左右两边是否不全等,(比较结果为boolean类型,即只会得到 true 或 false)=
:单等是赋值==
:是判断===
:是全等
注意:
1. 开发中判断是否相等,强烈推荐使用===
2. 字符串比较,是比较的字符对应的ASCII码
3. NaN不等于任何值,包括它本身
4. 不同类型之间比较会发生隐式转换
&&
(逻辑与):符号两边都为true结果才为true,一假则假||
(逻辑或):符号两边有一个true就为true,一真则真!
(逻辑非):true变false,false变true,真变假,假变真if(条件){ 满足条件要执行的代码 }
条件 ? 满足条件执行的代码 : 不满足条件执行的代码
switch(数据) { case 值1: 代码1 break default: 代码n break }
while(循环条件) { 循环体 }
for(变量起始值; 终止条件; 变量变化量) { 循环体 }
break(退出循环)、continue(结束本次循环,继续下次循环)
数组是一种可以按顺序保存数据的数据类型。
let 数组名 = [数据1, 数据2, …, 数据n]
数组名[下标]
for (let i = 0; i < 数组名.length; i++) { 数组名[i] }
数组.push(新增内容)
:将一个或多个元素添加到数组的末尾,并返回该数组的新长度数组.unshift(新增内容)
:将一个或多个元素添加到数组的开头,并返回该数组的新长度数组.pop(删除内容)
:从数组中删除最后一个元素,并返回该元素的值数组.shift(删除内容)
:从数组中删除第一个元素,并返回该元素的值数组.splice(起始位置, 删除的个数)
:删除指定元素函数是被设计为执行特定任务的代码块。
函数语法:
function 函数名() { 函数体 }
函数名()
function 函数名(参数列表) { 函数体 }
函数名(传递的参数列表)
作用域:
匿名函数:
function() { 函数体 }
,匿名函数是没有名字的函数, 无法直接使用立即执行函数:
( function() { 函数体 } )();
注意:
对象是一种无序的数据集合。
let 对象名 = {属性名:属性值, 方法名:函数}
对象名.属性
对象名.属性 = 新值
对象名.新属性 = 新值
delete 对象名.属性
对象['属性']
方法名:function(){方法体}
for(let k in 对象名){循环体}
注意:
内置对象-Math:
random
:生成0-1之间的随机数(包含0不包括1)ceil
:向上取整floor
:向下取整max
:找最大数min
:找最小数pow
:幂运算abs
:绝对值Math.floor(Math.random() * (M - N + 1)) + N
:生成N-M之间的随机数let、var、function、if、else、switch、case、break
int、short、long、char
n、m、show
10 + 3 age >= 1
if() for()
const
:用于不会发生变化的常量let
:用于会发生变化的变量//声明常量
const names = [1, 2, 3]
//声明变量
let num = 18
document.querySelector('css选择器')
document.querySelectorAll('css选择器')
//返回CSS选择器匹配到的第一个元素
document.querySelector('.box')
//返回CSS选择器匹配的NodeList(对象集合)
document.querySelectorAll('h2')
元素.innerText = 属性
元素.innerHTML = 属性
//只识别文本,不解析标签
username.innerText = '刘德华'
//能识别文本,解析标签
username.innerHTML = '刘德华'
元素.属性 = 值
元素.style.样式属性 = 值
元素.className = '类名'
元素.classList.add('类名')
:追加一个类元素.classList.remove('类名')
:删除一个类元素.classList.toggle('类名')
:切换一个类元素.classList.contains('类名')
:查看是否包含某个类//操作元素常用属性
pic.title = '标题'
//操作元素样式属性
box.style.width = '200px'
//操作元素类名
box.className = 'active'
//通过classList操作元素类名
box.classList.add('active')
表单元素.属性名 = 值
<input></input>
//通过JS新增或修改表单元素属性
doucument.querySelector('input').value = '用户名'
doucument.querySelector('input').type = 'password'
对象.dataset.自定义属性
//通过data-自定义属性来设置自定义属性
<div class="box" data-id="10">盒子</div>
//通过dataset来获取自定义属性的值
console.log(document.quertSelector('.box').dataset.id)
setInterval(函数, 间隔时间)
clearInterval(间歇函数名)
//定义一个函数
function repeat() {
console.log('我是一个函数')
}
//开启定时器
let timer = setInterval(repeat, 1000)
//关闭定时器
clearInterval(timer)
元素对象.addEventListener('事件类型', 要执行的函数)
事件源
、事件类型
、事件处理程序
click(鼠标点击)
、mouseenter(鼠标经过)
、mouseleave(鼠标离开)
focus(获得焦点)
、blur(失去焦点)
keydown(键盘按下触发)
、keyup(键盘抬起触发)
input(用户输入事件)
[属性名 = 属性值]
例:[type = password]
元素.addEventListener('click', function(e)){ }
trim()
例:text.value.trim()
//控制台输出事件对象e的key值
console.log( e.key )
window.函数
,所以 this 指代 window//使当前环境对象的颜色样式为红色
this.style.color = 'red'
input:checked
选择含有checked属性的对象//这个function就是一个匿名的回调函数
box.addEventListener('click', function(){
'匿名回调函数'
})
事件流指的是事件完整执行过程中的流动路径,经过的两个阶段为:捕获阶段、冒泡阶段
DOM.addEventListener(事件类型, 事件处理函数, 是否使用捕获机制)
DOM.addEventListener(事件类型, 事件处理函数, 是否使用捕获机制)
e.stopPropagation()
e.preventDefault()
btn.onclick = null
DOM.removeEventListener(事件类型, 事件处理函数, [获取捕获或者冒泡阶段])
mouseenter
和 mouseleave
没有冒泡效果 (推荐)e.target.tagName
//如果点击的对象是ul中的li标签,颜色变为红色
document.querySelector('ul').addEventListener('click', function (e) {
if (e.target.tagName === 'LI') {
e.target.style.color = 'red'
}
})
页面加载事件:
load
//load事件,加载外部资源完毕时触发
window.addEventListener('load', function(){})
//DOMContentLoaded事件,初始的HTML文档被加载和解析完后触发
document.addEventListener('DOMContentLoaded', function(){})
元素滚动事件:
scroll
元素.scrollTop
元素.scrollLeft
document.documentElement
元素.scrollTo(x, y)
//scroll事件,滚动条在滚动时持续触发
window.addEventListener('scroll', function(){
//获取往上滚动被卷去的大小
cosnt n = document.documentElement.scrollTop
console.log(n)
})
//把内容滚动到指定坐标
window.scrollTo(0, 1000)
页面尺寸事件:
resize
元素.clientWidth
元素.clientHeight
//resize事件,会在窗口尺寸改变的时候触发
window.addEventListener('resize', function(){
//获取元素的可见部分宽高
let w = document.documentElement.clientWidth
let h = document.documentElement.clientHeight
})
获取宽高:
元素.offsetWidth
元素.offsetHeight
获取位置:
元素.offsetLeft
元素.offsetTop
元素.getBoundingClientRect()
//获取元素的自身宽
document.querySelector('.box').offsetWidth
//获取元素的自身高
document.querySelector('.box').offsetHeight
//获取元素距离自己定位父级元素的左距离
document.querySelector('.box').offsetLeft
//获取元素距离自己定位父级元素的上距离
document.querySelector('.box').offsetTop
//返回元素的大小及其相对于视口的位置
document.querySelector('.box').getBoundingClientRect()
实例化:
const date = new Date()
日期对象方法:
日期对象.getFullYear()
获得年份(获取四位年份)日期对象.getMonth()
获得月份(取值为 0 ~ 11)日期对象.getDate()
获取月份中的每一天(不同月份取值也不相同)日期对象.getDay()
获取星期(取值为 0 ~ 6)日期对象.getHours()
获取小时(取值为 0 ~ 23)日期对象.getMinutes()
获取分钟(取值为 0 ~ 59)日期对象.getSeconds()
获取秒(取值为 0 ~ 59)时间戳:
日期对象.getTime()``+new Date()``Date.now()
DOM节点:DOM树里每一个内容都称之为节点
节点类型:元素节点、属性节点、文本节点
查找节点:
子元素.parentNode
父元素.childNodes
父元素.children
元素.nextElementSibling
元素.previousElementSibling
操作节点:
document.createElement( '标签名' )
父元素.appendChild(要插入的元素)
父元素.insertBefore(要插入的元素,在哪个元素前面)
元素.cloneNode(布尔值)
父元素.removeChild(要删除的元素)
//创建一个li标签节点
const li = document.createElement('li')
//插入li标签到ul的最后一个子元素后
ul.appendChild(li)
//插入li标签到ul的第一个子元素前
ul.insertBefore(li, ul.children[0])
//将ul的第一个子元素克隆给li1
const li1 = ul.children[0].cloneNode(true)
//将ul的第一个子元素删除
ul.removeChild(ul.children[0])
触摸事件:
touchstart
touchmove
touchend
JS插件就是别人写好的一些代码,我们只需要复制对应的代码,就可以直接实现对应的效果。
学习插件的基本过程:
BOM(Browser Object Model)是浏览器对象模型
setTimeout(回调函数,等待的毫秒数)
clearTimeout(延时函数)
//开启定时器,2秒后控制台输出内容
let timer = setTimeout(function() {
console.log('时间到了')
}, 2000)
//清除定时器
clearTimeout(timer)
概念:
同步和异步:
执行机制:
由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环(event loop)
location 的数据类型是对象,它拆分并保存了 URL 地址的各个组成部分
常用属性和方法:
location.href
location.search
location.hash
location.reload(true)
navigator的数据类型是对象,该对象下记录了浏览器自身的相关信息
常用属性和方法:
navigator.userAgent
检测浏览器的版本及平台// 检测 userAgent(浏览器信息)
!(function () {
const userAgent = navigator.userAgent
// 验证是否为Android或iPhone
const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/)
const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/)
// 如果是Android或iPhone,则跳转至移动站点
if (android || iphone) {
location.href = '[http://m.itcast.cn](http://m.itcast.cn/)' }
})()
history 的数据类型是对象,主要管理历史记录,该对象与浏览器地址栏的操作相对应,前进、后退、历史记录等
常用属性和方法:
history.back()
history.forward()
history.go(参数)
随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案。
localStorage:
localStorage.setItem(key, value)
localStorage.getItem(key)
localStorage.removeItem(key)
sessionStorage:
sessionStorage.setItem(key, value)
sessionStorage.getItem(key)
sessionStorage.removeItem(key)
//存储数据('uname', '张三')
localStorage.setItem('uname', '张三')
//获取数据, 都加引号
const name = localStorage.getItem('uname')
//删除数据, 只删除名字
localStorage.removeItem('uname')
//修改数据, 如果原来有这个键是改, 如果没有这个键则是增
localStorage.setItem('uname', '李四')
本地只能存储字符串,无法存储复杂数据类型
JSON.stringify(复杂数据类型)
本地存储里面取出来的是字符串,不是对象,无法直接使用
JSON.parse(JSON字符串)
//定义一个复杂数据类型
const goods = {name: '张三', age: 18}
//把复杂数据类型转换成JSON字符串, 存入本地存储
localStorge.setItem('goods', JSON.stringify(goods))
//取出本地存储, 把JSON字符串转换成对象
const obj = JSON.parse(localStorge.getItem('goods'))
map方法:
数组.map(function (ele, index) { return ele })
join方法:
数组.join('参数')
//定义一个数组
const arr = [10, 20, 30]
//利用map方法遍历数组, 对数组中每个元素加10并且拼接一个字符'元'
const newArr = arr.map(function (item) {
return item + 10 + '元'
})
//把数组中所有元素转换成一个字符串, 并且元素之间以*分隔
console.log(arr.join('*'))
正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式,在 JavaScript中,正则表达式也是对象
正则表达式通常用来查找、替换那些符合正则表达式的文本,许多语言都支持正则表达式
作用:
语法:const 变量名 = /表达式/
作用:定义正则表达式
注意:其中/ /是正则表达式字面量
语法:regObj.test(被检测字符串)
作用:判断是否有符合规则的字符串,返回的是布尔值
注意:其中regObj是定义的正则表达式
语法:regObj.exec(被检测字符串)
作用:检索符合规则的字符串,找到返回数组,否则返回null
//定义一个字符串
const str = 'javascript'
// 定义正则表达式规则
const reg = /java/
// 判断是否有符合规则的字符串
console.log(reg.test(str)) // 返回布尔值
// 检索符合规则的字符串
console.log(reg.exec(str)) // 返回数组
元字符是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能
元字符分类:
^
:表示匹配行首的文本(以谁开始)$
:表示匹配行尾的文本(以谁结束)*
:重复零次或更多次+
: 重复一次或更多次?
:重复零次或一次{n}
:重复n次{n,}
:重复n次或更多次{n,m}
:重复n到m次[]
:匹配字符集合(使用连字符 - 表示一个范围)[^]
:取反符号(对范围取反,注意要写到中括号里面).
:匹配除换行符之外的任何单个字符\d
:匹配0-9之间的任一数字,相当于[0-9]\D
:匹配所有0-9以外的字符,相当于 [^0-9]\w
:匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]\W
:除所有字母、数字和下划线以外的字符,相当于 [^A-Za-z0-9_]\s
:匹配空格 (包括换行符、制表符、空格符等),相等于[\t\r\n\v\f]\S
:匹配非空格的字符,相当于 [^\t\r\n\v\f]//边界符:精确匹配'哈哈哈'
/^哈哈哈$/
//量词:2~5个哈
/^哈{2,5}$/
//字符类-匹配字符集合:第一个字符为1~9, 后面的4个以上字符为0~9
/^[1-9][0-9]{4,}$/
//字符类-取反符号:一个除了a~z的字符
/^[^a-z]$/
//字符类-除换行符:2个以上除换行符之外的任意字符
/^.{2,}$/
//预定义类:四个0~9的数字 - 1~2个0~9的数字 - 1~2个0~9的数字
/^\d{4}-\d{1,2}-\d{1,2}/
修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等
/表达式/修饰符
i
是单词 ignore 的缩写,正则匹配时字母不区分大小写g
是单词 global 的缩写,匹配所有满足正则表达式的结果替换方法:
字符串.replace(/正则表达式/, '替换文本')
//修饰符i, 不区分大小写
//修饰符g, 匹配所有结果
//替换方法replace, 把符合正则表达式的文本替换成替换文本
str.replace(/java/ig, 'Python') //把str中所有java或JAVA文本替换成Python
作用域(scope)规定了变量能够被访问的"范围",离开了这个"范围"变量便不能被访问
局部作用域分为:
const o = .cloneDeep(obj) //通过.cloneDeep()方法实现深拷贝
通过JSON.stringify()实现:
```javascript
const o = JSON.parse(JSON.stringify(obj)) //把对象转换成JSON数据再转换成对象
异常处理是指预估代码执行过程中可能发生的错误
if (!x || !y) { throw new Error('没有参数传递过来') }
通过try/catch
捕获错误信息(浏览器提供的错误信息),try试试、catch拦住、finally最后
try {
const p = document.querySelector('.p')
p.style.color = 'red'
} catch (err) {
// 拦截错误,提示浏览器提供的错误信息,但是不中断程序的执行
console.log(err.message)
throw new Error('你看看,选择器错误了吧')
//终止代码继续执行
return
}finally {
//不管程序对不对,一定会执行的代码
alert('一定会执行的代码')
}
在程序中添加debugger代码,在运行的时候会直接跳转到debugger位置进行断点调试
使用场景:程序员进行调试时使用
普通函数:
普通函数的调用方式决定了this的值,即谁调用this的值指向谁
普通函数没有明确调用者时this值为window,严格模式下没有调用者时this的值为 undefined
箭头函数:
箭头函数中的this与普通函数不同,也不受调用方式的影响,事实上箭头函数中并不存在this
注意:
JavaScript中还允许指定函数中this的指向,有3个方法可以动态指定普通函数中this的指向
语法:fun.call(thisArg, arg1, arg2, ...)
作用:使用 call 方法调用函数,同时指定被调用函数中 this 的值
说明:
语法:fun.apply(thisArg, [argsArray])
作用:使用 apply 方法调用函数,同时指定被调用函数中 this 的值
说明:
语法:fun.bind(thisArg, arg1, arg2, ...)
作用:bind 方法不会调用函数,但是能改变函数内部this 指向
说明:
相同点:
区别点:
主要应用场景:
防抖就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间
利用Lodash库的_.debounce()
方法实现防抖:
<script src="./lodash.min.js"></script>
const box = document.querySelector('.box')
let i = 1
function mouseMove() {
box.innerHTML = i++
}
box.addEventListener('mousemove', _.debounce(mouseMove, 500))
box.addEventListener('mousemove', _.throttle(mouseMove, 500))
利用定时器实现防抖:
const box = document.querySelector('.box')
let i = 1
function mouseMove() {
box.innerHTML = ++i
}
function debounce(fn, t) {
let timeId
return function () {
// 如果有定时器就清除
if (timeId) clearTimeout(timeId)
// 开启定时器
timeId = setTimeout(function(){fn()}, t)
}
}
box.addEventListener('mousemove', debounce(mouseMove, 200))
节流就是指连续触发事件,但是在 n 秒中只执行一次函数
利用lodash的_.throttle()
方法实现节流:
<script src="./lodash.min.js"></script>
const box = document.querySelector('.box')
let i = 1
function mouseMove() {
box.innerHTML = i++
}
box.addEventListener('mousemove', _.throttle(mouseMove, 500))
利用定时器实现节流:
const box = document.querySelector('.box')
let i = 1
function mouseMove() {
box.innerHTML = i++
}
function throttle(fn, t) {
let timer = null
return function () {
if(!timer){
timer = setTimeout(function() {
fn()
// 清空定时器
timer = null
}, t)
}
}
box.addEventListener('mousemove', throttle(mouseMove, 500))