【JavaScript】DOM笔记(随缘更新ing)

文章目录

JavaScript DOM笔记

记录一下DOM的笔记,不间断更新,详红宝书第14-16章

1、DOM:文档对象模型

如果把js代码写在上面,那么建议把js代码放在window.onload = function(){}里,确保代码执行时,页面中整个DOM对象已经加载完毕,否则无法获取到DOM对象

但是最好把js代码写在最下面(紧挨着</body>),使页面先加载出来,再执行代码,保证性能

· 文档:整个HTML网页文档
· 对象: 网页中每一个部分
· 模型:使用模型来表示对象之间的关系,方便获取对象
HTML DOM树

1.1、 Node类型

详见红宝书P402

· 节点Node:构成HTML文档最基本的单元
· 四类常用节点
  -文档节点:整个HTML文档,其nodeValue为null -
  -元素节点:HTML文档中的所有标签都是元素节点,使用element表示,其nodeValue为null
  -属性节点:元素的属性,其nodeValue为属性值
  -文本节点:HTML标签中文本的类容,其nodeValue为文本的内容
DOM把以上内容都看作是对象

举个例子

<p class="words">Hello World</p>
//整段代码是元素节点
//class="words" 这一部分是属性节点
//Hello World 是文本节点

JavaScript中所有节点类型都继承Node类型,因此所有节点都共享相同的基本属性和方法,每个节点都有nodeType属性,表示该节点的类型,节点类型由定义在Node类型上的12个数值常量表示。

1.1.1、nodeName与nodeValue

对元素而言,nodeName始终等于元素的标签名,而nodeType始终为null

2、Document类型

详见红宝书P407

事件:用户和浏览器之间的交互行为
HTML事件汇总

2.1、获取元素

获取元素后才能通过JavaScript对元素进行操作-

2.1.1、根据ID名获取

const/let a = document.getElementById('id名');
//id名为区分大小写的字符串
//返回值为一个元素节点对象

2.1.2、根据标签名获取

//两种方法
const/let a = document.getElementsByTagName('标签名');
const/let a = element.getElementsByTagName('标签名');

//返回值一组元素对象的集合(伪数组,数组元素是元素对象)

因为得到的是一个对象的集合,并且索引从0开始,所以要处理里面单个对象就要遍历

2.1.3、H5新增

1、根据类名获取
   const/let a = document.getElementsByClassName('类名');
   //返回值是一个满足条件元素对象的伪数组,使用时需要通过下标获取标签
   const/let a = document.getElementsByClassName('box');

2const/let a = document.querySelector('选择器');
   这里注意选择器必须要加符号,比如类选择器,那么就必须加上“.”,eg.
   const/let a = document.querySelector('.box');
   //返回值:页面中第一个满足的HTML标签

3const/let a = document.querySelectorAll('选择器');
   //返回一组满足条件的元素
   同样,选择器也要加上符号
   const/let a = document.querySelectorAll('#box');
   //返回值:以一个伪数组形式返回一个nodeList(节点列表)

getElementsByClassName 和 querySelectorAll 的区别(先留个坑,后面整理好了再更)

2.1.4、获取特殊元素(body、html)

获取body元素:document.body
获取html元素:document.documentElement

3、改变HTML

修改HTML最简单的方法是使用 innerHTML 属性

3.1、修改HTML元素的内容

语法: document.getElementById(“p1”).innerHTML=“新文本!”;

忽略格式,只是举个例子,下同

<html>
	<p id="p1">Hello World</p>
	<ul id="ul">
		<li>1</li>
	</ul>
</html>

<script>
	document.getElementById('p1').innerHTML = "嗨!";//修改<p>的文本内容
	document.getElementById('ul').innerHTML += "<li>2</li>";//增加一个<li>
</script>

3.2、修改HTML属性

语法:document.getElementById(id).attribute=新属性值

举个例子:

<html>
	<img id="item" src="./图库/素材库/Dante/jackpot.jpg" alt="鬼泣展示图">
</html>

<script>
	document.getElementById('item').innerHTML.src = "./图库/素材库/N vs DV.jpg";
	//通过修改src来替换原来的图片
</script>

3.3、修改HTML样式

语法:document.getElementById(id).style.property=新样式

举个例子:

<html>
	<p id="p1" style="color: red;">Hello World</p>
</html>

<script>
	document.getElementById('p1').style.color="blue";
</script>

4、DOM事件

常用事件后续更新
完整版事件见此

4.1、事件属性

使用事件属性向html元素分配事件,eg.
<button onclick="displayDate()">点击显示日期</button>

4.2、使用DOM分配事件,当事件触发时,执行设置的函数

DOM允许用户使用JavaScript向HTML元素分配事件,语法如下

使用 对象.事件 = 函数 的方式 只能为一个对象绑定一个响应函数,多的会覆盖前面的

<html>
	<button id="btn" onclick="displayDate()">点击显示日期</button>
</html>

<script>
	//写法1:一次性使用时可以用这种写法
	document.getElementById('btn').onclick=function(){
		displayDate();
	};
	//点击id名为btn的button时,执行函数displayDate();

	//写法2:需要多处使用时最好用这种写法
	const/let btn = document.getElementById('btn');
	btn.onclick=function(){
		displayDate();
	};
</script>

5、EventListener事件监听器

通过 addEventListener()方法 为指定对象添加事件句柄,不会覆盖已存在的句柄

语法:element.addEventListener(event, function, useCapture);
//注意在addEvenListener()方法中,不要使用on前缀
//比如应该使用click,而不是onclick
//useCapture为ture时,事件使用捕获传递。为false(默认)时,使用冒泡传递

1、可以通过 addEventListener() 为元素添加一个事件句柄,eg.
element.addEventListener('click',function(){
	console.log('Hello World')
	});
	
2、可以通过 addEventListener() 为他同一元素添加多个相同事件,相互之间为叠加关系,eg.
element.addEventListener('click',function_1);
element.addEventListener('click',function_2);

3、也可以通过 addEventListener() 为同一元素添加多个事件,eg.
element.addEventListener('click',function_1);//点击元素触发函数
element.addEventListener('mouseover',function_2);//鼠标悬停触发函数
element.addEventListener('mouseout',function_3);//鼠标移开触发函数

5.1、事件的冒泡传递与捕获传递

事件传递有两种方式:冒泡和捕获,这两种方式代表元素事件触发的不同顺序

以下面这段代码为例

	<html>
		<div id="div_1">
        	<p id="p_1">点击我</p>
    	</div>
	</html>

    <style>
        #div_1{
            position: relative; 
            width: 100px; 
            height: 50px; 
            background-color: rgb(239, 135, 95); 
            text-align: center;
        }

        #p_1{
            position: absolute; 
            left: 25%; 
            top: 25%; 
            display: block; 
            margin: 0; 
            background-color: rgb(162, 162, 211);
        }
    </style>

效果图:
冒泡与传递

1.useCapture设置为true时,事件为捕获传递,即先触发最外部元素的事件,再由外到内依次触发内部元素的事件即:捕获传递:先外后内

    <script>
        const box_1 = document.getElementById("div_1");
        const text = document.getElementById("p_1");

        box_1.addEventListener('click',function() {
            alert("我是捕获传递,你触发了box_1的点击事件");
        }, true);//这里useCapture设置为true,为捕获传递

        text.addEventListener('click',function() {
            alert('我是捕获传递,你触发了text的点击事件');
        }, true);
    </script>

点击<p>的内容,先触发<div>的点击事件
在这里插入图片描述
点击确定后,会发现才触发<p>的点击事件
在这里插入图片描述
而如果点击<div>内非<p>的区域,那么只触发<div>的点击事件
在这里插入图片描述
按下确定后发现不会触发<p>的点击事件

2、useCapture设置为false时,事件为冒泡传递,即先触发最内部元素的事件,再由内到外依次触发外部元素的事件即:冒泡传递:先内后外

    <script>
        const box_1 = document.getElementById("div_1");
        const text = document.getElementById("p_1");

        box_1.addEventListener('click',function() {
            alert("我是捕获传递,你触发了box_1的点击事件");
        }, false);//这里useCapture设置为true,为捕获传递

        text.addEventListener('click',function() {
            alert('我是捕获传递,你触发了text的点击事件');
        }, false);
    </script>

点击<p>的内容,先触发<p>的点击事件
在这里插入图片描述
点击确定后,会发现才触发<div>的点击事件
在这里插入图片描述
而如果点击<div>内非<p>的区域,那么只触发<div>的事件
在这里插入图片描述

5.2、removeEventListener()

使用removeEventListener() 方法可以移除 addEventListener() 方法添加的事件句柄

语法:element.removeEventListener("event", function);

6、通过DOM向文档中添加、移除或替换HTML元素(节点)

6.1、添加 - appendChild() 与 insertBefore()

createElement():创建HTML元素

const box = document.createElement("div");
const para = document.createElement("p");
//创建了一个</div>元素

createTextNode():创建一个新的文本节点

const textNode = document.createTextNode("新的文本");

appendChild() 与 insertBefore()

1、appendChild() 方法用于将新元素添加到尾部
	para.appendChild(textNode);
	box.appendChild(para);
	//如果html文件中的<div>内有2个<p>,那么用appendChild()新加入的para会放在第二个<p>之后

2、insertBefore() 方法用于将新元素添加到头部
	para.insertBefore(textNode);
	box.insertBefore(para);
	//如果html文件中的<div>内有2个<p>,那么用appendChild()新加入的para会放在第一个<p>之前

6.2、移除 - removeChild()

如果想移除元素a,那么还需要找到它的父元素b

<html>
	<div id="box">
		<a id="link_1"></a>
		<a id="link_2"></a>
	</div>
</html>

使用 removeChild() 方法删除父元素中某个子元素

语法:父元素句柄.removeChild(待删除子元素句柄)

//以删除div内id为“link_2”的子元素为例
<script>
	const parent = document.getElementById("box");
	const child = document.getElementById("link_2");
	parent.removeChild(child);
</script>

6.3、替换 - replaceChild()

语法:父元素句柄.replaceChild(替换元素句柄,被替换子元素的句柄);

7、HTMLCollection (只能包含HTML元素节点)

可以类比数组,通过索引去获取集合中的元素,但集合无法使用数组的方法

使用以下方法获取的是一个集合

1、getElementById();                         //通过ID选取元素
2、getElementsByClassName();                 //通过类名选取元素
3、getElementsByTagName();                   //通过标签选取元素
4、getElementsByName();                      //通过NAME属性选取元素

可以通过在方法后面添加索引号,来获取集合的指定元素,eg.
document.getElementsByClassName('pic1')[0]; 

7.1、集合对象的length属性

length属性获取的是集合中元素的数量

document.getElementsByClassName('pic1').length; 

注意:如果要对获取到的集合中所有元素进行操作,那么应当使用遍历的方法

8、NodeList (可以包含各种类型的节点)

NodeList可以使用 length属性、forEach() 方法遍历,但它不是数组,数组特有的方法它不能使用

通过以下方法可以得到NodeList实例
Node.childNodesdocument.querySelectorAll()

将NodeList转换为数组的方法:
Array.prototype.slice.call(NodeList名)

8.1、NodeList.prototype.item()

item()接受一个整数值作为索引号,返回该索引号位置上的成员,eg.
document.ul.childNodes.items(5);//返回第6个成员

但我们一般使用索引号直接取出成员,eg.
document.ul.childNodes[5];

HTMLCollection 与 NodeList 的区别
1、HTMLCollection 元素可以通过 name,id 或索引来获取。
2、NodeList 只能通过索引来获取。
3、只有 NodeList 对象有包含属性节点和文本节点。

9、DOM操作CSS

9.1、获取元素当前样式与相关属性

· 元素.currentStyle.样式名:只有IE浏览器支持,但IE已成为历史
· getComputedStyle()

getComputedStyle();//返回一个封装了当前元素对应样式的对象
需要传递两个参数,第一个是需要获取样式的元素,第二个是伪元素,一般传null

可以通过返回的对象对元素中的样式进行操作或者读取,eg.
getComputedStyle(div1,null).width;
注意:如果获取到的样式没有用css设置,那么会获取到实际的值而不是元素默认值

getStyle();//传两个参数,第一个是元素类名或者id名等,第二个是样式名的字符串
返回获取样式的值
eg.let c = getStyle(div1, "color");

修改样式的方法

举例:
document.querySelector('.words').style.color = 'red';//注意是字符型

· 获取元素可见宽高的数值
  -包括内边距:clientWidthclientHeight
  -包括内边距和边框:offsetWidthoffsetHeight
· 获取当前元素的定位父元素:offsetParent
  -获取的是距离当前元素最近的设置了定位的祖先元素,若所有都没有设置定位,则返回则返回body

· 获取当前元素相对于其定位元素(offsetParent)的偏移量
  -offsetLeft:水平偏移量
  -offsetTop:垂直偏移量

· 获取滚动条滚动的距离
  -scrollLeft:获取水平滚动的距离
  -scrollTop:获取垂直滚动的距离

滚动到底的判断:
-垂直滚动到底:clientHeight == scrollHeight - scrollTop
-水平滚动到底:clientWidth == scrollLeft - scrollWidth

9.2、disabled 属性

用于设置一个元素是否被禁用,true为禁用,false为不禁用,改属性默认为false

10、event - 事件对象

事件传播的三个阶段:
   1、捕获阶段
      -该阶段从最外层的祖先元素,向目标元素进行事件的捕获,但默认此时不会触发事件
   2、目标阶段
       -事件捕获到目标元素,捕获结束开始在目标元素上触发事件
    3、冒泡阶段
      -事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
· event对象只在事件处理程序执行期间存在,一旦执行完毕,就会被销毁
· 在事件对象event中封装了当期事件相关的一切信息,当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数。
所有浏览器都支持event对象。

使用event对象的一些方式
1、 btn.onclick = function(event){
		console.log(event.type);//ty0pe可以是"click"、"mouseup"……
	}

2、 btn.addEventListener("click" ,(event) => {
		console.log(event.type);
	}, false);

红宝书里还有用HTML实现相同效果的例子:
<input type = "button" value = "点我" onclick = "console.log(event.type)">

10.1、preventDefault() - 取消事件默认行为

preventDefault() 方法可以阻止特定事件的默认行为,比如阻止 <a>标签被点击时默认向href指定的url跳转

let myLink = document.getElementById("link_1");
myLink.onclick = function(event){
	event.preventDefault();
};

任何可以通过 preventDefault() 方法取消默认行为的事件,其event对象的cancelable属性都会设置为true
所以应当先检测再使用该方法

10.2、stopPropagation() - 阻断事件流在DOM的传播

对event使用该方法后,会立即终止事件流在DOM的传播,取消后续事件捕获或者冒泡,不再执行该方法之后event的行为。

10.3、eventPhase属性 -

用于确定事件流所处阶段:
·捕获阶段       —>返回1
·在目标上被调用    —>返回2
·在冒泡阶段被调用   —>返回3

11、事件类型

11.1、用户界面事件 - 涉及与BOM交互的通用浏览器事件

11.1.1、load

加载项加载完成后触发

11.1.2、unload

在window上页面完全卸载后触发,在窗套上当所有窗格都卸载完成后触发、在上当相对应对象卸载完成后触发

11.1.3、absort

在元素上当相应对象加载完成前被用户提前终止下载时触发

11.1.4、error

当window加载JavaScript报错,、、窗套内容有加载失败时触发

11.1.5、选择

在文本框(或文段)上当用户选择了一个或多个字符时触发

11.1.6、调整大小

当窗口或窗格被缩放时触发

11.1.7、滚动

当用户滚动包含滚动条的元素时在元素上触发

11.2、焦点事件

11.2.1、blur(通用版:focusout)

当元素失去焦点时触发,这个事件不冒泡,该事件所有浏览器都支持

DOMFocusOut 在DOM3中被废除

11.2.2、focusin(focus冒泡版)

当元素获得焦点时触发,该事件冒泡

DOMFocusIn 在DOM3 Events中被废除

11.3、鼠标事件

DOM3 Events 规定了9种鼠标事件,对应类型为MouseEvent

事件说明
click鼠标左键单击
dblclick鼠标左键双击
mousedown (DOM3标准化 )按下任意鼠标键
mouseenter (DOM3新增)鼠标光标从元素外移到元素内,该事件不冒泡
mouseleave(DOM3新增)鼠标光标从元素内移到元素外,该事件不冒泡
mousemove鼠标光标在元素上移动时反复触发
mouseout鼠标光标从一个元素移动到另一个元素时触发
mouseover鼠标光标从元素外移动到元素内
mouseup用户释放鼠标按键时触发
对 mousedown 和 mouseup 事件而言,event对象上有一个 button 属性,表示按下或释放的是哪个键
button = 0 ---> 按下或释放鼠标左键
button = 1 ---> 按下或释放鼠标滑轮
button = 2 ---> 按下或释放鼠标右键

客户端坐标获取: event.clientX、event.clientY
页面坐标获取: event.pageX、event.pageY
屏幕坐标获取: event.screenX、event.screenY

鼠标事件的公共属性:bubbles、cancelable、view、clientX、clientY、screenX、screenY、detail、altKey、shiftKey、ctrlKey 、 metaKey。

11.3.1、mousewheel - 鼠标滑轮事件

包括滑轮在垂直方向上的任意滚动,其event对象包含了鼠标事件的所有标准信息,此外还有一个名为 wheelDelta 的属性,其值的正负反应了滑轮滚动方向,数值反应了滚动幅度。

11.4、修饰键 - Shift、Ctrl、Alt、Meta

DOM规定了四个属性表示这四个修饰键的状态:
shiftKey、ctrlKey、altKey、metaKey
被按下时,对应状态布尔值为true、没有被按下时为false

11.5、键盘与输入事件

事件说明
keydown按下某个键时触发,持续按会重复触发
textInput(keypress在DOM3被废弃)按下键盘上某个键并产生字符时触发,持续按会重复触发
keyup用户释放键盘上某个键时触发
event属性说明
keyCode返回按下键的Unicode编码
key返回按下的键名字符

1、textInput是唯一的输入事件,textInput 会在文本被插入到文本框之前触发
2、如果一直按着某个键,那么某个键就会一直触发keydown和keypress(非字符键不触发),直到该键被释放才触发keyup

11.6、HTML5事件

11.6.1、contextmenu事件

Windows上点击鼠标右键 或者 Mac上 Ctrl+单击左键 时出现自定义上下文菜单

通常,自定义的上下文菜单都是通过 oncontextmenu 事件处理程序触发显示,并通过 onclick 事件处理程序触发隐藏。

11.6.2、beforeunload 事件

1、这个事件会在页面即将从浏览器中卸载时触发,如果页面需要继续使用,则可以不被卸载
2、这个事件会向用户显示一个确认框,其中的消息表明浏览器即将卸载页面,并请用户确认是希望关闭页面,还是继续留在页面上

该事件弹出的确认框中的文字由在 event.returnValue 中设置的字符串决定

11.6.3、 DOMContentLoaded 事件

window的load事件是在页面完全加载后触发,会花费较长时间,而DOMContentLoaded事件是在DOM树构建完成后立即触发,而不必等图片、js文件、css文件或其他资源加载完成。从而实现用户与页面更快地进行交互。

11.6.4、 readystatechange 事件

该事件旨在提供文档或元素加载状态的信息,通过readyState属性获取(该属性为支持 readystatechange事件的对象有)

readyState的可能字符串值说明
uninitialized对象存在并尚未初始化
loading对象正在加载数据
loaded对象已经加载完数据
interactive对象可以交互,但尚未加载完成
complete对象加载完成
11.6.5、pageshow 与 pagehide 事件(红宝书P526 - 527)
往返缓存:

该功能由Firefox 和 Opera开发,旨在使用浏览器“前进”和“后退”按钮时加快页面之间的切换。这个缓存不仅存储页面数据,也存储 DOM 和JavaScript 状态,实际上是把整个页面都保存在内存里。
pageshow 与 pagehide事件就是把往返缓存的行为暴露出来

11.6.6、hashchange 事件

用于在url散列值(即url中 # 之后的部分)发生变化时通知开发者
此事件的event对象中有两个属性:oldURL:保存变化前的url。newURL:保存变化后的url

window.addEventListener("hashchange", (event) => { 
 console.log(`Old URL: ${event.oldURL}, New URL: ${event.newURL}`); 
});

使用location对象可以获取当期url散列值
语法:location.hash

11.7、设备事件(红宝书P528 - 531)

11.7.1、orientationchange 事件
11.7.2、deviceorientation 事件
11.7.3、devicemotion 事件

11.8、触摸及手势事件

11.8.1、触摸事件
事件说明
touchstart手指放到屏幕上时触发
touchmove手指在屏幕上滑动时连续触发。在这个事件中调用 preventDefault()可以阻止
滚动
touchend手指从屏幕上移开时触发
touchcancel系统停止跟踪触摸时触发。文档中并未明确什么情况下停止跟踪

每个触摸事件的 event 对象都提供了鼠标事件的公共属性
触点的独特属性:

属性说明
touchesTouch 对象的数组,表示当前屏幕上的每个触点
targetTouchesTouch 对象的数组,表示特定于事件目标的触点
changedTouchesTouch 对象的数组,表示自上次用户动作之后变化的触点

每个Touch对象包含以下属性

属性说明
clientX触点在视口中的 x 坐标
clientY触点在视口中的 y 坐标
identifier触点在视口中的 y 坐标
pageX触点在页面上的 x 坐标
pageY触点在页面上的 y 坐标
screenX触点在屏幕上的 x 坐标
screenY触点在屏幕上的 y 坐标
target触摸事件的事件目标

这些属性可用于追踪屏幕上的触摸轨迹

11.8.2、手势事件
事件说明
gesturestart一个手指已经放在屏幕上,再把另一个手指放到屏幕上时触发
gesturechange任何一个手指在屏幕上的位置发生变化时触发
gestureend其中一个手指离开屏幕时触发

手势事件每个event对象都包含所有鼠标事件的公共属性,此外还包含以下两个属性

属性说明
rotation手指变化旋转的度数,负值逆时针,正值顺时针(从0开始)
scale两指之间距离变化(对捏)的程度。开始时为 1,然后随着距离增大或缩小相应地增大或缩小
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

六时二一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值