文章目录
介绍
ES和JS的关系
ES【ECMAScript】是一种脚本语言的标准,JS是基于ES标准实现的编程语言。ES为JS提供了规则基础,在这个基础上JS又扩展了一些实用的新内容,这个内容我们称作Web APIs,里面包含了DOM、BOM、File、XMLHttpRequest等模块。
- DOM文档对象模型:定义了一套操作HTML文档的API。
- BOM浏览器对象模型:定义了一套操作浏览器窗口的API。
ES和Node.js的关系
Node.js是一个JS的运行环境,它允许在服务器端运行JS代码。ES为Node.js提供了规则基础,在这个基础上Node.js又扩展了一些实用的内容,这些内容我们称为Server APIs,里面包含了http、url、os、path、net、fs等模块。
DOM
DOM【Document Object Model】是将整个html文档的每一个标签元素视为一个对象,这个对象包含了许多的属性和方法,通过操作这些属性或者调用这些方法来实现对html的动态更新,为实现网页特效以及用户交互提供技术支撑。
DOM树
html文档可以用树状结构来描述,我们称为DOM树。DOM树能直观的体现标签和标签之间的关系。
DOM节点
节点是文档树的组成部分,每一个节点都是一个 DOM 对象,主要分为元素节点、属性节点、文本节点等。
- 【元素节点】其实就是 HTML 标签,如上图中
head
、div
、body
等都属于元素节点。 - 【属性节点】是指 HTML 标签中的属性,如上图中
a
标签的href
属性、div
标签的class
属性。 - 【文本节点】是指 HTML 标签的文字内容,如
title
标签中的文字。 - 【根节点】特指
html
标签。
document
document
是 JavaScript 内置的专门用于 DOM 的对象。
<script>// document 是内置的对象
console.log(typeof document);// 1. 通过 document 获取根节点
console.log(document.documentElement);// 对应 html 标签// 2. 通过 document 节取 body 节点
console.log(document.body);// 对应 body 标签// 3. 通过 document.write 方法向网页输出内容
document.write('Hello World!');</script>
获取DOM对象
- querySelector 返回满足条件的第一个对象。
- querySelectorAll 返回满足条件的元素集合,是个伪数组【有length属性并能通过索引访问元素,但是没有数组的所有方法】。
- getElementById 根据标签的id来获取标签节点。
- getElementsByTagName 根据标签名来获取标签节点集合。
- 任何DOM对象都有一个nodeType属性,来检测节点类型。
- 获取html元素的DOM对象:document.documentElement
- 获取body元素的DOM对象:document.body
<body><h3>查找元素类型节点</h3><p>从整个 DOM 树中查找 DOM 节点是学习 DOM 的第一个步骤。</p><ul><li>元素</li><li>元素</li><li>元素</li><li>元素</li></ul><script>const p = document.querySelector('p')// 获取第一个p元素const lis = document.querySelectorAll('li')// 获取所有的li元素</script></body>
操作元素内容
文本内容修改
innerText
将文本内容添加/更新到任意标签位置,文本中包含的标签不会被解析。
<script>// innerText 将文本内容添加/更新到任意标签位置const intro = document.querySelector('.intro')// intro.innerText = '嗨~ 我叫李雷!'// intro.innerText = '<h4>嗨~ 我叫李雷!</h4>'</script>
innerHTML
将文本内容添加/更新到任意标签位置,文本中包含的标签会被解析。
<script>// innerHTML 将文本内容添加/更新到任意标签位置const intro = document.querySelector('.intro')
intro.innerHTML ='嗨~ 我叫韩梅梅!'
intro.innerHTML ='<h4>嗨~ 我叫韩梅梅!</h4>'</script>
常用属性修改
<script>// 1. 获取 img 对应的 DOM 元素const pic = document.querySelector('.pic')// 2. 修改属性
pic.src ='./images/lion.webp'
pic.width =400;
pic.alt ='图片不见了...'</script>
样式属性修改
- 通过修改style属性,来实现对样式的动态修改。通过元素节点获得的
style
属性本身的数据类型也是对象,如box.style.color
、box.style.width
分别用来获取元素节点 CSS 样式的color
和width
的值。<body><divclass="box">随便一些文本内容</div><script>// 获取 DOM 节点const box = document.querySelector('.box') box.style.color ='red' box.style.width ='300px'// css 属性的 - 连接符与 JavaScript 的 减运算符// 冲突,所以要改成驼峰法 box.style.backgroundColor ='pink'</script></body>
- 借助类名来操作CSS,如果修改的样式比较多,直接通过style属性修改比较繁琐,我们可以借助css类名的形式。
<head><style>.pink{background: pink;color: hotpink;}</style></head><body><divclass="box">随便一些文本内容</div><script>// 获取 DOM 节点const box = document.querySelector('.box')// 因为class是关键字,所以使用className去代替 box.className ='pink'</script></body>
className是用新值替代旧值,如果需要添加一个类,需要保留之前的类名。通过classList方式可以追加和删除类名:<head><style>div{width: 200px;height: 200px;background-color: pink;}.active{width: 300px;height: 300px;background-color: hotpink;margin-left: 100px;}</style></head><body><divclass="one"></div><script>// 1.获取元素// let box = document.querySelector('css选择器')let box = document.querySelector('div')// add是个方法 添加 追加// box.classList.add('active')// remove() 移除 类// box.classList.remove('one')// 切换类(元素如果有one类名,就给它去掉,如果没有,就给它加上) box.classList.toggle('one')//查看类 box.classList.contains('one')//查看有没有包含某个类,如果有则返回true,么有则返回false</script></body>
表单元素属性修改
正常的有属性有取值的跟其他的标签属性没有任何区别
获取:DOM对象.属性名
设置:DOM对象.属性名= 新值
<body><inputtype="text"value="请输入"><buttondisabled>按钮</button><inputtype="checkbox"name=""id=""class="agree"><script>// 1. 获取元素let input = document.querySelector('input')// 2. 取值或者设置值 得到input里面的值可以用 value// console.log(input.value)
input.value ='小米手机'
input.type ='password'// 2. 启用按钮let btn = document.querySelector('button')// disabled 不可用 = false 这样可以让按钮启用
btn.disabled =false// 3. 勾选复选框let checkbox = document.querySelector('.agree')
checkbox.checked =false</script></body>
自定义属性
在html5中推出来了专门的data-自定义属性
在标签上一律以data-开头
在DOM对象上一律以dataset对象方式获取
<body><divdata-id="1"> 自定义属性 </div><script>// 1. 获取元素let div = document.querySelector('div')// 2. 获取自定义属性值
console.log(div.dataset.id)</script></body>
操作元素节点
上面的DOM操作是针对元素节点的属性或文本的,针对于元素节点本身也能进行操作。
插入节点
- 得到新的DOM节点
- 在哪个位置插入这个节点
<p>在现有 dom 结构基础上插入新的元素节点</p><hr><!-- 普通盒子 --><divclass="box"></div><!-- 点击按钮向 box 盒子插入节点 --><buttonclass="btn">插入节点</button><script>// 点击按钮,在网页中插入节点const btn = document.querySelector('.btn')
btn.addEventListener('click',function(){// 1. 获得一个 DOM 元素节点const p = document.createElement('p')
p.innerText ='创建的新的p标签'
p.className ='info'// 复制原有的 DOM 节点const p2 = document.querySelector('p').cloneNode(true)
p2.style.color ='red'// 2. 插入盒子 box 盒子
document.querySelector('.box').appendChild(p)
document.querySelector('.box').appendChild(p2)})</script>
createElement
动态创建任意 DOM 节点cloneNode
复制现有的 DOM 节点,传入参数 true 会复制所有子节点appendChild
在末尾(结束标签前)插入节点
再来看另一种情形的代码演示:
<p>在现有 dom 结构基础上插入新的元素节点</p><hr><buttonclass="btn1">在任意节点前插入</button><ul><li>HTML</li><li>CSS</li><li>JavaScript</li></ul><script>// 点击按钮,在已有 DOM 中插入新节点const btn1 = document.querySelector('.btn1')
btn1.addEventListener('click',function(){// 第 2 个 li 元素const relative = document.querySelector('li:nth-child(2)')// 1. 动态创建新的节点const li1 = document.createElement('li')
li1.style.color ='red'
li1.innerText ='Web APIs'// 复制现有的节点const li2 = document.querySelector('li:first-child').cloneNode(true)
li2.style.color ='blue'// 2. 在 relative 节点前插入
document.querySelector('ul').insertBefore(li1, relative)
document.querySelector('ul').insertBefore(li2, relative)})</script>
结论:
insertBefore
在父节点中任意子节点之前插入新节点
删除节点
首先由父元素删除子节点,其次是要删除哪个子节点。
<body><!-- 点击按钮删除节点 --><button>删除节点</button><ul><li>HTML</li><li>CSS</li><li>Web APIs</li></ul><script>const btn = document.querySelector('button')
btn.addEventListener('click',function(){// 获取 ul 父节点let ul = document.querySelector('ul')// 待删除的子节点let lis = document.querySelectorAll('li')// 删除节点
ul.removeChild(lis[0])})</script></body>
查找节点
- 父子关系:父获子:parent.childNodes:所有子节点,回车换行会被认为是空白文本节点。parent.children:只获取元素类型的节点。子获父【以相对位置查找节点,实际应用非常灵活】:childNode.parentNode:父节点childNode.parentNode.parentNode:爷爷节点
- 兄弟关系【以相对位置查找节点】node.previousSibling :获取前一个节点node.nextSibling:获取后一个节点
间歇函数
setInterval是JS的内置函数,作用是间隔固定时间自动重复执行指定的函数,也叫定时器函数。
<script>// 1. 定义一个普通函数functionrepeat(){
console.log('不知疲倦的执行下去....')}// 2. 使用 setInterval 调用 repeat 函数// 间隔 1000 毫秒,重复调用 repeatsetInterval(repeat,1000)</script>
事件
事件用来描述发生在DOM对象上的行为,当事件发生时,我们可以调用一些函数。
事件监听
结合DOM使用事件时,需要为DOM添加事件监听,等待事件触发时,便立即调用一个函数。
addEventListener就是用来给DOM元素添加事件监听的方法,它的两个参数是事件类型和事件回调。
<body><h3>事件监听</h3><pid="text">为 DOM 元素添加事件监听,等待事件发生,便立即执行一个函数。</p><buttonid="btn">点击改变文字颜色</button><script>// 1. 获取 button 对应的 DOM 对象const btn = document.querySelector('#btn')// 2. 添加事件监听
btn.addEventListener('click',function(){
console.log('等待事件被触发...')// 改变 p 标签的文字颜色let text = document.getElementById('text')
text.style.color ='red'})// 3. 只要用户点击了按钮,事件便触发了!!!</script></body>
完成事件监听的步骤:首先获取DOM元素,然后为这个DOM元素添加事件监听,事件触发后调用回调函数。
事件类型
有很多的事件类型:鼠标事件、键盘事件、表单事件、焦点事件等。
鼠标事件
- mouseenter监听鼠标是否移入DOM元素
<script>// 需要事件监听的 DOM 元素const box = document.querySelector('.box');// 监听鼠标是移入当前 DOM 元素 box.addEventListener('mouseenter',function(){// 修改文本内容this.innerText ='鼠标移入了...';// 修改光标的风格this.style.cursor ='move';})</script>
- mouseleave监听鼠标是否移出DOM元素
键盘事件
keydown 键盘按下触发,keyup 键盘抬起触发
焦点事件
focus 获得焦点,blur失去焦点。
文本框输入事件
input
页面加载事件
外部资源(图片、外联CSS和JS等)加载完毕后触发的事件。
window.addEventListener('load',function(){// xxxxx})
元素滚动事件
滚动条在滚动的时候持续触发的事件。
window.addEventListener('scroll',function(){// xxxxx})
页面尺寸事件
窗口尺寸改变的时候触发的事件
window.addEventListener('resize',function(){// xxxxx})
事件对象
事件触发时,与事件相关的信息会以事件对象的形式记录下来,事件对象可以在事件回调函数的参数中接收。
<script>// 获取 .box 元素const box = document.querySelector('.box')// 添加事件监听
box.addEventListener('click',function(event){
console.log('任意事件类型被触发后,相关信息会以对象形式被记录下来...');// 事件回调函数的第1个参数即所谓的事件对象
console.log(event)
console.log(event.type)//事件类型
console.log(event.clientX/Y)//光标相当于浏览器窗口的位置
console.log(event.offSetX/Y)//光标相当于当前DOM元素的位置})</script>
事件流
事件流是对事件执行过程的描述,事件触发会有捕获和冒泡两个阶段,捕获阶段是从父到子的传导过程,冒泡阶段是从子到父的传导过程。
捕获或冒泡
当事件触发的时候,事件会先经过其祖先元素才能到达当前元素,这个过程叫捕获,然后到达当前元素后,事件又会有当前元素向祖先元素传递,这个过程叫冒泡。
当事件到达一个元素时,如果该元素监听了该事件,就会触发回调函数的执行。
一个事件,它先从上到下捕获,然后在从下到上执行,那些DOM元素会被事件经过两次,那肯定不能触发两次执行吧,是在捕获阶段执行还是在冒泡阶段执行是可以在设置监听事件时设置的,默认时在冒泡阶段执行的,如果想在捕获阶段执行,就在设置监听事件的函数addEventListener调用时,传入第三个参数为true。
<script>// 获取嵌套的3个节点const outer = document.querySelector('.outer')const inner = document.querySelector('.inner')// 外层的盒子
outer.addEventListener('click',function(){
console.log('outer...')},true)// true 表示在捕获阶段执行事件// 中间的盒子
outer.addEventListener('click',function(){
console.log('inner...')},true)</script>
默认在冒泡阶段执行事件的回调函数,如果我在当前元素阻断了事件的流动【事件对象中的event.stopPropagation方法】,那事件就不会冒泡到其祖先元素,其祖先元素也就不会执行该事件的回调函数,这就是阻止冒泡,它保证事件只在当前元素执行,不会影响到其祖先元素。
<body><divclass="outer"><divclass="inner"><divclass="child"></div></div></div><script>// 获取嵌套的3个节点const outer = document.querySelector('.outer')const inner = document.querySelector('.inner')const child = document.querySelector('.child')// 外层的盒子
outer.addEventListener('click',function(){
console.log('outer...')})// 中间的盒子
inner.addEventListener('click',function(ev){
console.log('inner...')})// 内层的盒子
child.addEventListener('click',function(ev){
console.log('child...')// 借助事件对象,阻止事件向上冒泡
ev.stopPropagation()})</script></body>
注意:鼠标经过事件
- mouseover和mouseout会有冒泡效果。
- mouseenter和mouseleave没有冒泡效果。
事件委托
大量的事件监听是比较耗费性能的,事件委托指的是利用事件流的特征来解决开发需求、提升程序效率的一些技巧。
<script>// 假设页面中有 10000 个 button 元素const buttons = document.querySelectorAll('table button');for(let i =0; i <= buttons.length; i++){// 为 10000 个 button 元素添加了事件
buttons.addEventListener('click',function(){// 省略具体执行逻辑...})}</script>
利用事件流的特征,可以对上述的代码进行优化,事件的的冒泡模式总是会将事件流向其父元素的,如果父元素监听了相同的事件类型,那么父元素的事件就会被触发并执行,正是利用这一特征对上述代码进行优化,如下代码所示:
<script>// 假设页面中有 10000 个 button 元素let buttons = document.querySelectorAll('table button');// 假设上述的 10000 个 buttom 元素共同的祖先元素是 tablelet parents = document.querySelector('table');
parents.addEventListener('click',function(){
console.log('点击任意子元素都会触发事件...');})</script>
事件对象中的属性
target
或
srcElement
属性表示真正触发事件的元素,它是一个元素类型的节点。
<script>// 假设页面中有 10000 个 button 元素const buttons = document.querySelectorAll('table button')// 假设上述的 10000 个 buttom 元素共同的祖先元素是 tableconst parents = document.querySelector('table')
parents.addEventListener('click',function(ev){// console.log(ev.target);// 只有 button 元素才会真正去执行逻辑if(ev.target.tagName ==='BUTTON'){// 执行的逻辑}})</script>
优化过的代码只对祖先元素添加事件监听,相比对 10000 个元素添加事件监听执行效率要高许多!!!
日期
//获取系统默认时间const curDate =newDate();//指定时间const date =newDate();
getFullYear 获取四位年份
getMonth 获取月份,取值为 0 ~ 11
getDate 获取月份中的每一天,不同月份取值也不相同
getDay 获取星期,取值为 0 ~ 6
getHours 获取小时,取值为 0 ~ 23
getMinutes 获取分钟,取值为 0 ~ 59
getSeconds 获取秒,取值为 0 ~ 59
时间戳
时间戳是指1970年01月01日00时00分00秒起至现在的总毫秒数。
const date =newDate();
date.getTime()//第一种
Date.now()//第二种
window
JS中,Window对象是BOM的核心,代表浏览器中打开的一个窗口(标签页),几乎所有的BOM功能都是通过Window对象来实现的,Window对象可以通过全局变量window来访问。
在浏览器环境中,通常一个窗口(标签页)就有一个独立的 Window 对象。这意味着在不同的窗口中,JavaScript 变量和函数的作用域是相互独立的,互不干扰。
像document、alert()、console.log()这些都是window的属性,window对象下的属性和方法调用的时候可以省略window。
所有通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法。
窗口操作
通过 Window 对象,你可以控制窗口的大小、位置和状态。例如,使用
window.open()
方法可以打开一个新窗口;
window.resizeTo()
和
window.moveTo()
方法可以调整窗口的大小和位置;
window.close()
方法可以关闭窗口。
对话框
Window 对象提供了三种对话框方法:
alert()
用于显示一个警告框,
confirm()
用于显示一个确认框,
prompt()
用于显示一个提示框,让用户输入信息。
定时器
- 延迟函数:让回调函数等一段时间再执行,只执行一次。
setTimeout(回调函数, 延迟时间);
清除延时函数:clearTimeout(timerId)``````<script>// 1. 开启延迟函数,延迟函数返回的还是一个正整数数字,表示延迟函数的编号let timerId =setTimeout(function(){ console.log('我只执行一次')},3000)// 1.2 延迟函数需要等待时间,所以下面的代码优先执行// 2. 关闭延迟函数clearTimeout(timerId)</script>
- 间歇函数:每隔一段时间就执行一次回调函数。
setInterval(回调函数,间隔时间);
地址(location)
window.location对象包含了当前加载页面的 URL 信息,并且可以用来导航到新的页面。
location它拆分并保存了 URL 地址的各个组成部分, 它是一个对象。
属性/方法说明href属性,获取完整的 URL 地址,赋值时用于地址的跳转search属性,获取地址中携带的参数,符号 ?后面部分hash属性,获取地址中的啥希值,符号 # 后面部分reload()方法,用来刷新当前页面,传入参数 true 时表示强制刷新protocol返回页面使用的协议,如 “http:” 或 “https:”host返回主机名和端口号,如 “www.example.com:80”hostname返回主机名,如 “www.example.com”port返回端口号pathname返回 URL 中的路径部分
<body><form><inputtype="text"name="search"><button>搜索</button></form><ahref="#/music">音乐</a><ahref="#/download">下载</a><buttonclass="reload">刷新页面</button><script>// 1. href属性 (重点) 得到完整地址,赋值则是跳转到新地址
console.log(location.href)// location.href = 'http://www.itcast.cn'// 2. search属性 得到 ? 后面的地址
console.log(location.search)// ?search=笔记本// 3. hash属性 得到 # 后面的地址
console.log(location.hash)// 4. reload 方法 刷新页面const btn = document.querySelector('.reload')
btn.addEventListener('click',function(){
location.reload(true)// 强制页面刷新 ctrl+f5})</script></body>
历史(history)
history (历史)是对象,主要管理历史记录, 该对象与浏览器地址栏的操作相对应,如前进、后退等
- back():后退
- forward():前进
- go(参数):前进后退,1是前进一个页面,-1是后退一个页面。
浏览器信息(navigator)
常用属性和方法:
- 通过 userAgent 检测浏览器的版本及平台
// 检测 userAgent(浏览器信息)(function(){const userAgent = navigator.userAgent
// 验证是否为Android或iPhoneconst 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'}})();
本地存储(localStorage和sessionStorage)
本地存储能把数据保存在浏览器中,刷新页面或关闭页面后不丢失数据。
localStorage和sessionStorage的用法基本相同,都能存储大概5M的字符串键值对数据,但是localStorage是长期保存,关闭浏览器后数据仍存在,sessionStorage在浏览器关闭后数据会被清除。
<script>// 本地存储 - localstorage 存储的是字符串 // 1. 存储
localStorage.setItem('age',18)// 2. 获取
console.log(typeof localStorage.getItem('age'))// 3. 删除
localStorage.removeItem('age')</script>
如果想存储复杂数据类型,就要先把复杂数据类型转换成JSON字符串,然后再存储到本地。
对象转JSON:JSON.stringify(对象);
JSON转对象:JSON.parse(JSON字符串);
正则表达式
定义正则表达式:
const reg =/表达式/
使用正则:
<script>// 正则表达式的基本使用const str ='web前端开发'// 1. 定义规则const reg =/web/// 2. 使用正则 test()
console.log(reg.test(str))// true 如果符合规则匹配上则返回true
console.log(reg.test('java开发'))// false 如果不符合规则匹配上则返回 false</script>
表单验证的正则直接上网搜获着问AI。vscode有个any-rule的正则插件。
字符串替换内容时可以使用正则匹配:
字符串.replace(/正则表达式/,'替换的文本')
。
检验表单规则可以在input失去焦点后触发。
版权归原作者 今夏遇你 所有, 如有侵权,请联系我们删除。