JavaScript基础部分(二)
DOM(Document Object Model)
DOM是JS操作网页的接口,全称为**“文档对象模型”。其作用是将网页转为一个JS对象**,从而可以用脚本(JS)进行各种操作
概述
浏览器会根据DOM模型,将结构化文档HTML解析成一系列节点,再把这些节点组成一个树状结构(DOM Tree)::所有的节点和树状结构都有规范的对外接口::
这个是浏览器解析网页形成节点和树,JS通过DOM这个接口来操作节点和树,DOM只是一个接口规范,可以用各种语言实现,不属于JS的语法,但是JS常常用到DOM操作。没有DOM,JS脚本语言就无法控制网页
++同理POM也属于接口++
节点node
- 节点是DOM的最小组成单位,文档的树形结构(DOM树)就是由++各种不同类型++的节点组成,每一个节点都可以看成是文档树的一片叶子。++咱的p标签、div标签等都可以视为节点++
- 节点的七种类型:
- Document整个文档树的顶层节点,浏览器原生提供该节点,代表整个文档
- Document TypeDOCTYPE标签
- Element网页的各种HTML标签
- Attribute网页元素的属性
class/id
- Text标签之间或者标签包含的文本
- Comment注释
- ::DocumentFragment::文档的片段
节点树
一个文档的所有节点都是按照所在层级处理,可以抽象成一种树状结构,就是节点树
- 节点树有一个顶层/根节点::就是::下一层都是顶层节点的子节点::比如/::
- 节点之间的关系
- 父节点关系parentNode
- 子节点关系childNode
- 同级节点关系sibling
- Node.nodeType属性(了解)
- 确定节点的类型
- 对应的返回值:文档9,元素1,属性2,文本3,文档片段11
注意,我们接下来讲的…对象就是节点,有一个名词叫做节点对象每个对象(节点)都有对一个的属性和方法,我们讲解对象就是要学怎么用JS操作节点进而操作页面
document对象:获取页面中的元素!
通过名字或者选择器返回特定的元素,名字和选择器都要用引号包裹
document.getElementsByTagName()搜索HTML标签名
- 参数为标签名,如’p’以字符串的形式++参数名一次用一个++
- 返回符合条件的标签,返回值的类型是动态集合
HTMLCollection(标签个数)
::如果没有元素匹配就返回空集 - 我们返回动态集合之后怎么用集合返回单个标签呢?集合的元素形式类似于数组,所以可以
document.getElementsByTagName()[0]
直接返回单个标签
document.getElementsByClassName()搜索HTML类名
- 参数为class的名字,可以是多个名字,中间用空格隔开
document.getElementsByName()
- 用于有name属性的元素::如form表单::我们就搜索表单的name
++ByName使用率不高++
document.getElementById()使用率最高!
- 注意名字是Element没有s++因为id具有唯一性,我们不会返回多个名字相同的id,直接返回单个元素,不需要加[ ]++
以上是HTML老版本,下面是新版本::通过选择器获得元素:::
document.querySelector()
- 参数是CSS选择器!::.是类选择器,#是id选择器……::返回匹配该选择器的元素节点,只返回第一个匹配的节点,如果没有则返回null
- 如
document.querySelector('.myclass')
document.querySelectorAll()
- 大部分返回匹配选择器的节点链表啊!注意注意,它返回的是
NodeList
对象
%% 我个人认为选择器的选取有时方便特定情况下使用,比如Selector可以返回第一个元素,不需要查找整个集合再去返回首元素
HTMLCollection和NodeList
- HTMLCollection(https://link.juejin.cn/?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FWeb%2FAPI%2FHTMLCollection)
- 表示一个包含元素的集合,还提供了从该集合中选择元素的属性和方法++所以上面getElements方法除了ByName其他都是返回的HTMLCollection对象,是元素的集合++
- HTMLCollection 是动态绑定的,是一个动态集合,DOM 树发生变化,HTMLCollection也会随之变化,节点的增删是敏感的::动态获取页面DOM树的长度::
- NodeList(https://link.juejin.cn/?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FWeb%2FAPI%2FNodeList)对象是节点的集合
- NodeList 是一个静态集合,其不受 DOM 树元素变化的影响;相当于是 DOM 树快照,节点数量和类型的快照,不能感知节点增删,但可以感知节点内容的变化,比如修改
innerHTML
- 只有 NodeList 对象有包含属性节点和文本节点
- 特例:
document.getElemensByName
,也返回NodeList,但是它是动态集合
- NodeList 是一个静态集合,其不受 DOM 树元素变化的影响;相当于是 DOM 树快照,节点数量和类型的快照,不能感知节点增删,但可以感知节点内容的变化,比如修改
通常,拥有一个保持不变的列表是一件好事。但有时您可能需要一个自动更新以反映当前 UI 的列表。++了解选择器方法是返回静态集合还是动态集合也有助于防止意外的副作用和错误++
document对象:创建元素
document.createElement()
- 生成元素节点,并返回该节点,参数还是名称,如
div
document.createTextNode():创建文本信息
- 参数是文本内容::数字的引号可加可不加,但是字符必须要加上引号::
- 返回的是
#text
目前还不知道是啥 - 二者结合将文本塞到节点:
d.cE().appendChild(d.cT())
appendChild:将内容或者子元素放到容器中,此时打印节点节点中就会有内容
document.createAttribute()
- 为标签添加属性节点,参数是属性名。::此时只添加了属性,和标签没联系::显示
id=""
- 用value为属性赋值,赋值后就显示
id="root"
- 将属性塞到标签用
标签节点.setAttributeNode(name)
var name = document.createAttribute("id");
name.value = “root”;
text.setAttributeNode(name);
console.log(text);//详情见vs
将标签显示到页面之上
- 先在*中设置*一个元素比如
里面啥也不放
- 再通过
document.get...
找到元素 - 再调用元素的
appendChild
后面添加目标标签,打印中的已被修改的元素,结果元素中新增了我们的目标标签
Element对象:属性
%% Element对象对应着网页的HTML元素,每一个HTML元素在DOM树上都会转化成一个Element节点对象/元素节点
Element.id
- 可以返回id值,也可以更改元素的id值
- id值也是字符串
Element.className
- 读写当前元素节点class属性。它的值为字符串,每个class之间用空格分割
- 作用:通过操作JS修改class属性,进而与CSS之间进行交互::就比如CSS中我们增加了一个class类选择器,JS中用className新增该类选择器(类名)就可以与之对接::
Element.classList:采用List集合方法去操作class
- add():增加一个class
name.classList.add("mybox")
;直接添加,不用写之前的class - remove():移除
- contains():如果类中有括号里的类,则返回true,没有就返回false::用于判断是否包含类::
- toggle():::toggle:开关::如果类不存在就加入,存在就删除
Element.innerHTML:设置页面元素内容
- 单独则表示读取元素的内容,加上=“”就表示要修改
Element.innerText:
- 与innerHTML的区别:
- HTML可以识别标签
- Text会把标签识别成一个字符串
%% 也就是说,我们在设置页面元素内容的时候,Text就是设置的文本内容,标签一律打印,不能识别,HTML功能更加全面
Element获取元素位置
clientWidth/clientHeight:获取元素展示的宽度/高度
- 单位默认是px,包括padding内边距,不包括border和margin的宽度
- 只对块级元素生效,对于行内元素返回0
- 宽高返回的必须是整数,如果实际为小数则应四舍五入
- 常用于网页/视口
document.documentElement.clientHeight
视口(浏览器窗口)的高度document.body.clientHeight
网页可见区域的总高度(网页的实际高度)- 经过测试,视口的高度>网页的高度,网页的可见区域就是被内容撑开的区域
%% 为什么名字是client,因为带有client面对的对象是用户,所以展示的都是用户可见的高度和宽度
scrollHeight/Width
- 元素总高度,包括padding,不包括border/margin,包括溢出的不可见内容
- 也就是说,scroll和client在很多情况下返回的值是一样的,只有当页面有些内容被隐藏时才会有所区别
scrollLeft/Top:水平滚动/竖直滚动的距离
- 如果要查看整张网页水平和垂直滚动距离,就用
document.documentElement.scrollLeft/Top
- 常用在一边滚动一边显示滚动距离,这时要涉及到事件了!
offsetHeight/Width
- 元素CSS的垂直/水平高度,包含元素本身的高度、padding和border::没有外边距margin::
offsetLeft/Top
- 到定位父级左/上边界的间距,较常见::父级元素必须要有定位position才能作为间距的标准,否则标准就是整个文档::
- 注意:浏览器默认状态下是紧靠顶部,左边留有8px宽度可以设置全局选择器把margin设置为0
CSS操作
%% 上面是JS操作HTML节点元素,同时我们也希望通过JS直接操作页面中CSS样式,让三者联动起来
HTML元素的style属性
- 使用网页元素节点的
setAttribute
方法直接设置网页元素的style属性 - 一共是两个参数,第一个是属性的名字,第二个是属性的内容,注意都要写为字符串的形式++看起来就不简单啊,不怎么常用++
div.setAttribute(
‘style’,
'background-color:"red";width:5px;height:5px;'
)
元素节点的style属性
%% 与HTML元素style相比,该方法能有效地避免错误
- 用法就是找到节点,通过节点的style属性改变属性的内容,如
box.style.width = 200px;
box.style.backgroundColor = “red”; - 注意有连续.的情况之下我们就不能用-了,要用驼峰命名法连接在一起,如上面的backgroundColor
cssText属性:最佳写法
- cssText个人认为就是属性内容的总体,使用一次就可修改所有的内容!
- 相当于二者结合
`` box.style.cssText = “width:200px;height:100px;”
%% 没有必然的选择,纯看个人喜好,三者的效果是一样的
事件处理程序(给元素添加事件)
HTML事件处理
- 只需要在JS中写一个函数,然后在按钮中添加带有函数的事件,详情在vs中
- 缺点:HTML和JS没有分开++就是说在HTML中会有οnclick="函数"的代码,而这个代码就是JS语言,所以二者没有很好地分开++::容易出错误::
DOM0级事件处理
- 看DOM,获取元素,再用元素属性与函数相连如
btn.onclick=function(){...}
- 优点是HTML与JS分离,缺点是无法同时添加多个事件,新增的事件会把原来的事件覆盖
DOM2级事件处理
- 更高级的处理方式,视频就展示了一种完全不够
btn.addEventListener("click",function(){..})
用addEventListener,第一个参数是事件?第二个参数是函数定义 - 缺点:写起来麻烦
%% 总体说来,HTML是不考虑的。如果我们确定只添加一个事件那就用DOM0级,如果是多个事件就用DOM2级
事件
Event事件对象
事件(函数)发生以后,默认会产生一个事件对象,作为(函数)参数传给监听函数,监听函数就是事件函数++为啥叫监听呢?是因为这个函数(事件)不是立即触发的,需要有条件才能触发,这个等待的过程被称为监听++
++我个人认为,Event事件对象作为函数的参数其中的属性、方法可以丰富JS对事件的操作++
注意注意,参数建议写成event,我怎么用e不行啊靠!
Event对象属性
- event.target:返回事件当前所在的节点,点击谁就返回谁(HTML代码格式)
- event.type:返回一个字符串,表示事件类型。(只读)++比如返回click就表示该事件是click(鼠标)事件++
Event对象方法(相当于一条语句)
- event.preventDefult():取消浏览器对当前事件的默认行为++比如点击连接之后默认会跳转到另一个界面,用此方法之后就不会跳转++
- event.stopPropagation():阻止事件冒泡!
- 事件冒泡就是子元素、父元素嵌套时点击子元素,子元素和父元素的事件都被触发!!!!
事件类型之鼠标事件
::鼠标事件就是与鼠标相关的事件,我们上文写到的onclick就用到了事件click(单击鼠标后触发)::
click/dblclick:单击/双击
- 应用都是像
btn.ondblclick=function(){}
大部分前面都加on
,也有不加的
mousedown/up:鼠标按下或者抬起
mousemove:鼠标在节点内部移动时触发
- 当鼠标持续移动时,该事件会连续出发++速度很快啊,很快++
- 节点内部咱就设置
块级元素来个背景颜色就行了, 鼠标进入块就开始迅速触发事件
mouseenter/leave:鼠标进入/离开
- 这两个和上面的move一样都是鼠标进入/离开块元素
- 进入子节点不会触发,离开父节点不会触发!::说白了就是有可能会出现
等嵌套,形成多个区域(如正方形里还有一个正方形),子节点就是小的那个::
mouseover/out:鼠标进入/离开
- 进入子节点/离开父节点会再一次触发事件
wheel:滚动鼠标的滚轮时触发
事件类型之键盘事件
++类比于click,键盘事件名字前面也要加on++
注意,键盘事件的前提是要有输入框
keydown:按下按键时触发
keypress:按下有值的键时触发
- 按下Ctrl/Alt/Shift/Meta这样无值键不会触发事件
- 对于有值的键,按下时先触发
keydown
事件,再触发keypress
事件
keyup:松开键盘时触发该事件
- 常与event搭配实时读取输入框数据
Event属性keyCode:代表每个按键的唯一标识
- 唯一标识的意思感觉和ASCII码挺像的,用数字标识键盘按键。需要记忆的是回车键为13
- 这个回车键常用于判断用户是否敲回车了,如果
event.keyCode===13
则提交数据?或者显示怎样的信息?
事件类型之表单事件
%% 表单事件是表单元素以及输入框元素可以监听的事件
input事件:输入触发
btn.oninput=func...
::btn是我们获取到的表单成员::- 作用就是表单的数据发生变化时事件发生,常与
event.target.value
搭配::这样我们在表单输入什么就实时显示什么::实时输入,实时获取
select事件:选中内容时触发
change事件:值变化触发
- 与input最大的不同在于,change不会连续触发,只有当全部修改完成时才会触发::回车或者失去焦点才算全部修改完成::
reset/submit事件:都发生在表单对象****上,不是发生在表单成员上
reset()
- 重置表单/所有表单成员变回默认值
- 注意,该事件常用作方法,与onclick搭配使用。比如我们找到了表单元素myForm,使用方法就是
myForm.reset();
::本质上仍然是事件,只不过该事件可以当方法使用::
submit
:表单数据提交给服务器- 不能当方法使用了!,用的是
onsubmit
- 我们点击表格的按钮之后会触发
onsubmit
,onsubmit会把表单里的数据提交给服务器!! - 注意,提交的是整个表单而非表单元素,所以submit事件的发生对象是
%% 怎么查看是否提交到服务器呢?我们可以看上面的网址,最后如果出现类似username=zyt
这样的,就表明已经提交给服务器了,在HTML的中会有action
属性,内容就是与之连接的服务器地址
- 不能当方法使用了!,用的是
事件类型之滚动事件
%% 页面滚动时触发的事件,速度比较快
window.onscroll = func
监听滚动事件- 可以通过
document.documentElement.scrollTop
获取滚动的距离,二者结合就可以实时获取滚动的高度 - 但是事件执行的次数是非常之多而快的,后续会讲到防抖解决该问题
事件代理(事件委托):父元素系统处理子元素事件
%% 原理就是事件冒泡(事件会在冒泡阶段向上传播到父节点)。子元素数量很多时,明显一个一个设置事件不靠谱,我们就可以把子节点的监听函数定义在父节点上,通过父元素监听每一个子元素的事件
- 获取父元素
- 设置定义在父元素上的事件类型,比如
click
- 用标签名去判断点击的标签类型,用到了
event.target.tagname
与大写的标签名作比较,::返回的是大写的元素标签名,如果想用小写,加上方法toLowerCase()::如果相等那就设置动作,动作常用event.target.innerHTML
返回的是标签中的内容。
list.addEventListener("click",function(event){
if(event.target.tagname.toLowerCase===“li”)
console.log(event.target.innerHTML);
})
定时器(timer)
%% JS提供定时执行代码的功能,叫做定时器,主要由*setTimeout()和setInterval()*两个函数完成,这两个函数向任务队列添加定时任务
setTimeout():延时执行
- 该函数用来指定某个函数或者某段代码在多少毫秒之后执行
- 返回一个整数表示定时器的编号,以后可以用编号取消定时器
setTimeout(func|code,delay);
参1是函数或代码,参2是推迟执行的毫秒数- 取消定时器:
var timer = setT...
然后clearTimeout(timer);
取消定时器
注意:当函数当中有关于对象操作时,setTimeout()中的this指针不指向该对象,而是指向windows全局对象所以要注意对象成员名字起的不能与外界成员名一样。::或者在set函数之外对象函数之内var that=this;这时的this因为不在set函数中所以指向的仍然是该对象::++这声明变量也太简单了…++
setInterval():每间隔一段时间就执行一次
- 用法和setTimeout()一样,Interval是可以无限次执行
- 参数2也是毫秒数,只不过表示的是间隔的时间段
- 可以实现动画效果::每隔多少毫秒透明度就减小0.05之类的::
- 取消定时器
clearInterval(timer);
性能优化
防抖(debounce)
%% 人数点击次数过多容易让浏览器卡死,防抖可以优化这种高频的反馈,以保证浏览器的性能
- 定义:防抖就是让某个时间期限之内事件处理函数只执行一次
- 第一次触发事件,不立即执行函数,而是给出一个期限值如200ms,利用定时器,如果下一个200ms内事件不再触发,就执行函数,如果触发了就重新开始计时。
- 也就是说,我们设置一个期限,这个期限之内最多只能触发一次事件++如果短时间内大量同一事件连续触发,则不执行函数,疯狂重置也就相当于疯狂延时,直到清凉了再去执行++
- 关键在于setTimeout(),可以借助闭包维护全局纯净,具体代码看vs,给你讲的明明白白!
节流(throttle)
%% 和防抖比较像,应用背景也是一样的。防抖有一个不太完善的地方,就是我们滚动吧,如果我们是按着滚动条滚,那就不会返回高度
- 我们可以设计一种类似控制阀门一样定期开放的函数,让函数执行一次后,在某个时间段内短暂消失,过了这段时间之后再重新激活,一定会发生::类似于技能cd::
- 我一开始有个疑问,这个是定期触发,为啥不用setInterval?现在想明白了,节流就是在页面滚动或者发生其他变化的时候定期执行的,而setInterval不管你变不变,自动定期执行,区别就在于此
- 代码详情看vs。个人认为节流是防抖的升级版,多了应对按着滚动键滚动而不返回的情况
命令行工具
%% 常用的两种:CMD命令行工具和PowerShell命令行工具(更方便),ES6中使用只是比较基本,所以这两者没有太大的差异
CMD命令行
- 打开命令行窗口
- 左下角开始,输入cmd,直接弹开
- 快捷键(推荐):win+R,再一个回车
%% 之前系统还不强大时,我们的盘符还不具有可视化::看到C盘然后点击进入::之前系统打开盘符的操作都是通过命令行执行的
- 选择盘符
- 盘符名称+: 如
C:
,再一回车 - 默认是C盘,不区分大小写,我这电脑只有一个C盘所以目前用不到
- 盘符名称+: 如
- 查看盘符以及目录下的文件与文件夹
dir
- 在盘符后+
dir
+回车 - ++基本上所有的操作之前都给我们自动加上盘符了,直接输入操作即可++
- 隐藏的文件也会被展示,注意隐私保护
- 在盘符后+
- 清空命令行信息
- ::用于信息太多太杂乱的情况::
cls
+回车
- 进入文件夹或目录
cd
+ 空格 + 文件名 + 回车::回车之后不写了,都要用::- 进入之后仍旧可以
dir
查看内部文件 - 连续进入:
cd 目录1\目录2\...
- 返回上一级目录
cd
+..
::加不加空格都行,后面也可以加个/::- 一键回退到盘符目录:
cd\
- 快速补全目录或文件夹名称
- 在输入名称时按
tab键
,会自动补全,相当于查找所引了 - 模糊查询是按照文件排列顺序来,可以再按
tab键
内容会随之改变++一直按,直到找到精确的名字++
- 在输入名称时按
- 新建文件夹:
mkdir
+空格+文件名 - 查看历史输入:比如之前输入太麻烦,在新操作时直接按上下按键,历史输入的操作就能查看了
exit
退出命令提示符窗口- 如果我们要经常使用一个文件,重复打开会很麻烦,我们只需要把它的路径记录在电脑的环境变量中即可
PowerShell命令行
- 打开方式
开始
,搜索PowerShell
打开- 在目标文件夹之下按住
shift+右键
打开
- 剩下的保持一直::不过这个是蓝色的,挺好看的::
++以上为ES5.1版本,接下来讲ES6版本!++
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!