一、DOM
DOM:文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可拓展标记语言的标准编程接口。通过DOM提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等)。
文档:一个页面就是一个文档,在DOM中用document表示
元素:页面中的所有标签都是元素,在DOM中用element表示
节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示
1.操作元素
1)改变元素内容
语法:
element.innerText
// 从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉
element.innerHTML
// 起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<div id="div1"></div>
<div id="div2"></div>
<p>
段落
<span>123</span>
</p>
<script>
var div1 = document.getElementById('div1');
var div2 = document.getElementById('div2');
div1.innerText = '<strong>你好</strong>,明天';
// innerText 不识别html标签,去除空格和换行
div2.innerHTML = '<strong>你好</strong>,明天';
// innerHTML 识别html标签,保留空格和换行
var p = document.querySelector('p');
console.log(p.innerText);
console.log(p.innerHTML);
// 这个两个属性可以获取元素里面的内容
</script>
</body>
</html>
效果图:
2)常用元素的属性操作
- innerText、innerHTML改变元素内容
- src、herf
- id、alt、title
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<div><img src="#"></div>
<script>
var img = document.querySelector('img')
img.onmouseover = function() {
img.src = 'https://uploadstatic.mihoyo.com/contentweb/20211103/2021110322064026502.png'
}
</script>
</body>
</html>
效果图:
3)表单元素的属性操作
利用DOM可以操作的表单元素属性:type、value、checked、selected、disabled
4)样式属性操作
语法:
1. element.style
// 行内样式操作
// js修改style样式操作,产生的是行内样式,css权重比较高
2. element.className
// 类名样式操作
// className会直接更改元素的类名,会覆盖原先的类名
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<style>
.one {
width: 400px;
height: 400px;
background-color: aqua;
}
.two {
width: 20px;
height: 50px;
background-color: blueviolet;
}
</style>
</head>
<body>
<div class="one"></div>
<script>
var div = document.querySelector('div')
div.onmouseover = function() {
div.className = 'two'
}
</script>
</body>
</html>
效果图:
鼠标放上去后
5)自定义属性的操作
5.1 获取属性值
语法:
element.属性
// 获取内置属性值(元素本身自带的属性)
element.getAttribute(‘属性’);
// 主要获得自定义的属性(程序员自定义的属性)
5.2 设置属性值
语法:
element.属性 = ‘值’
// 设置内置属性值
element. getAttribute(‘属性’, ‘值’);
// 设置自定义的属性
6)H5自定义属性
自定义属性的目的:是为了保存并使用数据,有些数据可以保存到页面中而不用保存到数据库中。
H5规定自定义属性date-开头作为属性名并且赋值。
例:
< div data-index = “1” >< / div >
element.setAttribute( ‘data-index’ , 1 );
获取H5自定义属性
语法:
1. element.setAttribute( ‘data-index’);
//兼容性获取
2. element.dataset.index 或者 element.dataset[ ‘index’ ]
//H5新增,ie11才开始支持
2.节点操作
节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示
1)节点概述
获取元素通常使用两种方式:利用DOM提供的方法获取元素;利用节点层级关系获取元素
但是用DOM提供的方法获取元素,逻辑性不强且繁琐
利用系欸但那层级关系获取元素,可以通过父子兄节点关系获取元素,逻辑性强,但是兼容性稍差节点至少拥有三个基本属性:nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)
- 元素节点 nodeType 为1
- 属性节点 nodeType 为2
- 文本节点 nodeType 为3(文本系欸但包含文字、空格、换行等)
// 在实际开发中,节点操作主要操作的是元素节点
2)节点层级
父级节点
语法:node.parentNode
parentNode属性可返回某节点的父节点,注意是最近的一个父节点
如果指定的系欸但没有父节点则返回null
子节点
语法:
1. parentNode.childNodes(标准)
// 返回值里面包含了所有的子节点,如:元素节点,文本节点等
// 如果只想要获得里面的元素节点,需要专门处理
2. parentNode.children(非标准)
// parentNode.children是一个只读属性。它只返回子元素节点,其余节点不返回
3. parentNode.firstChild
// 返回第一个子节点,找不到则返回null,包含所有的节点
4. parentNode.lastChild
// 返回最后一个子节点,找不到则返回null,包含所有的节点
5. parentNode.firstElementChild
// 返回第一个子节点,找不到则返回null
6. parentNode.lastElementChild
// 返回最后一个子节点,找不到则返回null
// 5.6都有兼容性问题,ie9以上支持
兼容性解决:
1. parentNode.chilren[0]
2. parentNode.chilren[parentNode.chilren.length - 1]
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ol>
<script>
var ol = document.querySelector('ol')
console.log(ol.childNodes)
console.log(ol.children)
for(var i = 0; i < ol.childNodes.length; i++) {
if(ol.childNodes[i].nodeType == 1) {
console.log(ol.childNodes[i])
}
}
console.log(ol.firstChild)
console.log(ol.lastElementChild)
console.log(ol.children[0])
console.log(ol.children[ol.children.length - 1])
</script>
</body>
</html>
效果图:
兄弟节点
语法:
1. node.nextSibling
// 返回当前元素的下一个兄弟节点,找不到则返回null,包含所有节点
2. node.previousSibling
// 返回当前元素的上一个兄弟节点,找不到则返回null,包含所有节点
3. node.nextElementSibling
// 返回当前元素下一个兄弟节点,找不到则返回null
4. node.previousElementSibling
// 返回当前元素的上一个兄弟节点,找不到则返回null
// 3.4都有兼容性问题,ie9以上支持
兼容性解决(封装一个兼容性的函数)
<script>
function getNextElementSibling(element) {
var el =element
while(el =el.nextSibling) {
if(el.nodeType == 1) {
return el;
}
}
return null;
}
</script>
3)创建节点
语法:document.createElement( ‘tagName’ )
// 由tagName指定html元素,这些元素本不存在,根据需求动态生成的,所有称为动态创建元素节点
三种动态创建元素的区别
- document.write()
- element.innerHTML
- document.createElement()
区别:
- document.write是直接将内容写入页面的内容流,但是文本流执行完毕,则会导致页面全部覆盖
- innerHTML是将内容写入某个DOM节点,不会导致页面全部重绘
- innerHTML创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
- createElement()创建多个元素效率稍微低一点点,但是结构更清晰
4)增加节点
语法:
1.node.appendChild(child)
// 将一个节点添加到指定父节点的子节点列表末尾。类似css中的after伪元素
2.node.insertBefore(child, 指定元素)
// 将一个节点添加到指定父节点的子节点前面。类似css中的before伪元素
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<ul></ul>
<script>
var ul = document.querySelector('ul')
var li = document.createElement('li')
ul.appendChild(li)
</script>
</body>
</html>
效果图:
5)删除节点
语法:node.removeChild(child)
// 从DOM中删除一个子节点,返回删除的节点
6)复制节点
语法:node.cloneNode()
// 调用该方法的节点的一个副本 //
如果括号参数为空或者为false,则是浅拷贝,即只复制节点本身,不复制里面的子节点 //
如果括号参数为true,则是深度拷贝,会复制节点本身以及里面所有的子节点
7)DOM操作总结
DOM针对元素的操作,主要由创建、增、删、改、查、属性操作、事件操作。
7.1 创建
- document.write
- innerHTML
- createElement
7.2 增
- appendChild
- insertBefore
7.3 删
- removeChild
7.4 改
- 修改元素属性:scr、herf、title
- 修改普通元素内容:innerHTML、innerText
- 修改表单元素:value、type、disabled
- 修改元素样式:style、className
7.5 查
- DOM提供的API方法:getElementById、getElementsByTagName
- H5提供的新方法:querySelector、querySelectorAll
- 利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling)
7.6 属性操作
主要针对自定义属性
- setAttribute:设置dom的属性值
- getAttribute:得到dom的属性值
- removeAttribute移除属性
7.7 事件操作
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获得鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |
二、事件高级
1.注册事件
给元素添加事件称为注册事件或者绑定事件。
注册事件由两种方式:传统方式和方法监听注册方式
传统注册方式
- 利用on开头的事件
- < button onclick = “alert(‘hi’)” >< / botton >
- btn.onclick = function() {}
- 特点:注册事件的唯一性
- 同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数
方法监听注册方式
- W3C推荐
- addEventListener()它是一个方法
- IE9之前的IE不支持此方法,可使用attachEvent() 代替
- 特点:同一个元素同一个事件可以注册多个监听器
2.事件监听方式
1)addEventListener
语法:eventTarget.addEventListener( type, listener[ , useCapture ] )
该方法接受三个参数:
- type:事件类型字符串,比如:click,mouseover,注意不要带on
- listener:事件处理函数,事件发生时,会调用该监听函数
- useCapture:可选参数,是一个布尔值,默认是false
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<button>1</button>
<button>2</button>
<script>
var buts = document.querySelectorAll('button')
buts[0].onclick = function() {
alert('hi')
}
buts[0].onclick = function() {
alert('nihao')
}
// 只会显示你好
buts[1].addEventListener('click', function() {
alert(22)
})
buts[1].addEventListener('click', function() {
alert(33)
})
// 显示22然后显示33
</script>
</body>
</html>
效果图:
2)attachEvent
语法:eventTarget.attachEvent( eventNameWithOn, callback )
该方法接受两个参数:
- evenNameWithOn:事件类型字符串,比如 onclick、onmouseover、这里要带on
- callback:事件处理函数,当目标触发事件时回调函数被调用
3)兼容性
<script>
function addEventListener(element,eventName,fn) {
//判断当前浏览器是否支持addEventListener方法
if(element.addEventListener) {
element.addEventListener(eventName,fn);//第三个参数,默认是false
} else if (element.attachEvent) {
element.attachEvent('on' + eventName, fn );
} else {
//相当于element.onclick = fn;
element['on' + eventName] = fn;
}
}
</script>
3.删除事件方式
- 传统注册方式删除
eventTarget.onclick = null;- 方法监听注册方式删除
1)eventTarget.removeEventListener( type, listener[ , useCapture] );
2)eventTarget.detachEvent(eventNameWithOn, callback);
删除事件兼容性解决
<script>
function removeEventListener(element,eventName,fn) {
//判断当前浏览器是否支持addEventListener方法
if(element.removeEventListener) {
element.removeEventListener(eventName,fn);//第三个参数,默认是false
} else if (element.detachEvent) {
element.detachEvent('on' + eventName, fn );
} else {
element['on' + eventName] = null;
}
}
</script>
4.事件流
事件流描述的是从页面中接受事件的顺序。
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流
DOM事件流分为3个阶段:1.捕获阶段;2.当前目标阶段;3.冒泡阶段
注意:
- js代码中只能执行捕获或者冒泡其中的一个阶段
- onclick和attachEvent只能得到冒泡阶段
- addEventListener( type, listener[ , useCapture ] )第三个参数如果是ture,表示在事件捕获阶段调用事件处理程序;如果是false(不写默认就是false),表示在事件冒泡阶段调用事件处理程序
- 实际开发中我们很少使用事件捕获,我们更关注事件冒泡
- 有些事件是没有冒泡的,比如onblur、onfocus、onmouseenter、onmouseleave
5.事件对象
1)事件对象
语法:
eventTarget.onclick = function( event ) { }
eventTarget.addEventListener( ‘click’ , function (event) { } )
// 这个event是事件对象,还可以写成e或者evt
// 事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象event里面
2)兼容性方案
事件对象本身的获取存在兼容问题:
1.标准浏览器中是浏览器给方法传递的参数,只需要定义形参e就可以获取到
2.在IE6~8中,浏览器不会给方法传递参数,如果需要的话,需要到window.event中获取查找
兼容性解决: e = e || window.event;
3)事件对象常见属性和方法
事件对象属性方法 | 说明 |
---|---|
e.target | 返回触发事件的对象(标准) |
e.srcElement | 返回触发事件的对象(非标准id6~8使用) |
e.type | 返回事件的类型,比如:click(不带on) |
e.cancelBubble | 该属性阻止冒泡(非标准id6~8使用) |
e.returnValue | 该属性阻止默认事件(默认行为)非标准ie6~8使用,比如不让连接跳转 |
e.prebentDefault() | 该方法阻止默认事件(默认行为)标准,比如不让链接跳转 |
e.stopPropagation() | 阻止冒泡,标准 |
6.e.target和this的区别
e.target返回的是触发事件的对象(元素)
this返回的是绑定事件的对象(元素)
7.阻止默认行为
阻止默认行为就是让连接不能跳转,或者提交按钮不能提交
语法:
e.prebentDefault() // 普通浏览器
e.returnValue() // 低版本浏览器
return false // 也能阻止默认行为,但是return后面的代码就不会执行了
8.阻止事件冒泡
- 标准写法:e.stopPropagation()
- 非标准写法:IE6-8利用事件对象cancelBubble属性
9.事件委托
事件委托也称为事件代理,在JQuery里面称为事件委派
事件委托的原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
事件委托的作用:只操作了一次DOM,提高了程序的性能
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
var ul = document.querySelector('ul')
ul.addEventListener('click',function(e) {
alert("弹出")
// 不论是点击哪个li都会出现弹框
})
</script>
</body>
</html>
10.常用鼠标事件
1)禁止鼠标右键菜单
<script>
document.addEventListener('contextmenu',function(e) {
//contextmenu主要控制应该合适显示上下文菜单,主要用于程序员取消默认的上下文菜单
e.preventDefault();
})
</script>
2)禁止鼠标选中
<script>
document.addEventListener('selectstart',function(e) {
//selectstart开始选中
e.preventDefault();
})
</script>
3)鼠标事件对象
鼠标事件对象 | 说明 |
---|---|
e.clientX | 返回鼠标相对于浏览器窗口可视区的X坐标 |
e.clientY | 返回鼠标相对于浏览器窗口可视区的Y坐标 |
e.pageX | 返回鼠标相对于文档页面的X坐标,IE9+支持 |
e.pageY | 返回鼠标相对于文档页面的Y坐标,IE9+支持 |
e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
11.常用键盘事件
键盘事件 | 触发条件 |
---|---|
onkeyup | 某个键盘按键被松开时触发 |
onkeydown | 某个键盘按键被按下时触发 |
onkeypress | 某个键盘按键被按下时触发(但它不识别功能键,比如:ctrl shift 箭头等) |
注意:
- 使用addEventListener不需要加on
- 三个事件的执行顺序是:keydown,keypress,keyup
键盘事件对象属性keyCode,返回该键的ASCII值
其中onkeyup和onkeydown不区分字母大小写,onkeypress区分字母大小写
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<script>
document.addEventListener('keyup',function() {
console.log(1);
})
document.addEventListener('keydown',function() {
console.log(2);
})
document.addEventListener('keypress',function() {
console.log(3);
})
</script>
</body>
</html>
三、BOM
BOM:浏览器对象模型(Browser Object Model,简称BOM),它提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。通过BOM可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等。
DOM:文档对象模型,把[文档]当作一个[对象]来看待,DOM的顶级对象是document,主要学习的是操作页面元素,是W3C标准规范
BOM:浏览器对象模型,把[浏览器]当作一个[对象]来看待,BOM的顶级对象是window,主要学习的是浏览器窗口交互的一些对象,BOM是浏览器厂商在各自浏览器上定义的,兼容性较差
1.window对象的常见事件
window对象是浏览器的顶级对象
- 它是js访问浏览器窗口的一个接口
- 它是一个全部对象。定义在全局作用域中的变量、函数都会变成window对象的属性和方法。在调用的时候可以省略window,前面学习的对话框都属于window对象方法,如alert()、prompt()等
- window下的一个特殊属性window.name
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<script>
var num = 10
console.log(num);
console.log(window.num);
function fn() {
console.log(11);
}
fn()
window.fn()
</script>
</body>
</html>
效果图:
1)窗口加载事件
语法:
window.onload = function () {} ;
// 窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS文件等),就调用处理函数,这样就可以把js放在页面元素的上方了
// window.onload 只能写一次,如果有多个,会以最后一个window。onload为准
window.addEventListener( “load”, function() {} ) ;
// 使用没有限制
document.addEventListener(‘DOMContentLoaded’, function() {} )
// 事件触发时,仅当DOM加载完成,不包括样式表,图片,flash等(ie9以上支持)
如果页面的图片很多的话,从用户访问到onload触发可能需要较长的事件,交互效果就不能实现,必然影响用户的体验,此时用DOMContentLoaded事件比较合适
2)调整窗口大小事件
语法:
window.onresize = function() { }
// 调整窗口大小加载事件,当触发时就调用的处理函数
window.addEventListener( “resize” , function() { } )
注意:
- 只要窗口大小发生像素变化,就会触发这个事件
- 我们经常利用这个事件完成响应式布局。window.inner.Width当前屏幕的宽度
2.定时器
setTimeout() 定时器
语法:window.setTimeout( 调用函数,[延迟的毫秒数] );
注意:
- window可以省略
- 延迟的毫秒数省略默认是0,如果写,必须是毫秒
- 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符
- setTimeout() 这个调用函数我们也称为回调函数 callback(上一个事情做完,再回头调用这个函数,如click)
clearTimeout() 清除定时器
语法:window.clearTimeout( timeoutID )
// 取消先前通过调用setTimeout()建立的定时器
// 里面的参数就是定时器的标识符
setInterval() 计时器
语法:window.setInterval( 回调函数, [间隔的毫秒数] );
// 重复调用一个函数,每隔这个时间,就去调用一次回调函数
注意:
- window可以省略
- 延迟的毫秒数省略默认是0,如果写,必须是毫秒
- 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符
claerInterval() 停止计时器
语法:window.clearInterval( intervalID )
// 取消先前通过调用setInterval()建立的定时器
// 里面的参数就是定时器的标识符
this
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<script>
// 全局作用域或者普通函数中的this指向全局对象window
console.log(this);
function fn() {
console.log(this);
}
window.fn();
// 方法调用中的this指向被调用的对象
var a = {
one: function() {
console.log(this);
}
}
a.one()
// 构造函数中的this指向构造函数的实例
function fun() {
console.log(this)
}
var b = new fun()
// 定时器里面的this指向window
window.setTimeout(function() {
console.log(this)
},1000)
</script>
</body>
</html>
效果图:
3.JS执行机制
js有一个特点就是单线程,同一时间只能做一件事,于是就出现了同步和异步。
- 同步:前一个任务结束后执行下一个人物,程序的执行顺序与任务的排列顺序是一致的。
- 异步:在做一件花费时间很长的任务同时去做其他的任务。(通过回调函数实现,如:click,resize,load,error,定时器)异步任务会添加到任务队列(消息队列)中,先执行执行栈中的同步任务,然后再按次序读取、执行任务队列中的异步任务
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<script>
window.setTimeout(function() {
console.log(this)
},1000)
// 无论把定时器放在哪里,都是最后执行的
console.log(this);
function fn() {
console.log(this);
}
window.fn();
var a = {
one: function() {
console.log(this);
}
}
a.one()
function fun() {
console.log(this)
}
var b = new fun()
</script>
</body>
</html>
4.location对象
location属性用于获取或则会之窗体的url,并且可以用于解析url。
location对象属性 | 返回值 |
---|---|
location.href | 获取或者设置整个url |
location.host | 返回主机(域名) |
location.port | 返回端口号,如果未写返回空字符串 |
location.pathname | 返回路径 |
location.search | 返回参数 |
location.hash | 返回片段,#后面内容,常见于连接,锚点 |
location对象方法 | 返回值 |
---|---|
location.assign() | 跟herf一样,可以跳转页面(也称为重定向页面) |
location.replace() | 替换当前页面,因为不记录历史,所以不能后退页面 |
location.reload() | 重新加载页面,相当于刷新按钮或者f5,如果参数为true强制刷新ctrl+f5 |
5.navigator对象
navigator对象包含浏览器的信息,它有很多属性,我们最常用的是userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值
<script>
//判断用户使用哪个终端打开,实现转跳
if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|Webos|Symbian|Windows Phone)/i))) {
window.location.href = ""; //手机
} else {
window.location.href = ""; //电脑
}
</script>
6.history对象
history对象与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的url
history对象方法 | 作用 |
---|---|
back() | 可以后退功能 |
forward() | 前进功能 |
go(参数) | 前进后退功能,参数如果是1,则前进一个页面;如果是-1,后退一个页面 |