DOM基本

一、DOM及节点

1.DOM简述

JavaScript分为三个部分,ECMAScript,DOM(页面文档对象模型)和BOM(浏览器对象模型)。
DOM是JS操作网页的接口,全称为“文档对象模型”(Document Object Model。通过 HTML DOM,JavaScript 能够访问和改变 HTML 文档的所有元素。

2.节点

网页中的所有内容都是节点(例如注释、标签、文本等),是DOM的最小组成单位。任何 HTML 或 XML 文档都可以用 DOM 表示为一个由节点构成的层级结构。节点分很多类型,每种类型对应着文档中不同的信息或标记,也都有自己不同的特性、数据和方法,而且与其他类型有某种关系。

2.1节点类型

1.文档节点(document)
整个HTML文档document对象作为window对象的属性存在的,我们不用获取可以直接使用。
2.元素节点(Element)
HTML文档中的HTML标签就是元素节点。
3.属性节点(Attribute)
元素的属性表示的是标签中的一个一个的属性,这里要注意的是属性节点并非是元素节点的子节点,而是元素节点的一部分。
4.文本节点(Text)
HTML标签中的文本内容。
5.DocumentType(doctype标签)
6.Comment(注释)
7.DocumentFragment(文档片段)*

2.2节点层级

<html>
<head>
  <title>Example1</title>
</head>
<body>
  <p>Hello world!</p>
  <a href="www.nenu.edu.cn">东北师范大学</a>
</body>
</html>

document 节点表示每个文档的根节点,根节点的唯一子节点是html元素(也是根元素),我们称之为文档元素(documentElement)。HTML 中的每段标记都可以表示为这个树形结构中的一个节点。元素节点表示 HTML 元素,例如head元素,body元素,属性节点表示属性,例如上元素面a后面的href,文档类型节点表示文档类型,注释节点表示注释。DOM 中总共有12种节点类型,这些类型都继承一种基本类型。

2.3节点树

一个文档的所有节点,按照所在的层级,可以抽象成一种树状结构。这种树状结构就是DOM。
在这里插入图片描述

最顶层的节点就是document节点,它代表了整个文档。一般根节点只有一个子节点html元素,该html元素成为根节点,其他html标签都是它的下级。
节点之间存在三种关系:
父节点关系(parentNode)直接的那个上级节点。
子节点关系(childNode)直接的下级节点。
同级节点关系(sibling)拥有同一父节点的节点

二、DOM应用

1.Document类型

1.1查找html元素

项目描述
document.getElementById(id)通过元素 id 来查找元素
document.getElementsByTagName(name)通过标签名来查找元素
document.getElementsByClassName(name)通过类名来查找元素
document.querySelector()返回文档中匹配指定的CSS选择器的第一元素
document.querySelectorAll()返回文档中匹配的CSS选择器的所有元素节点列表

1.getElementById() 返回匹配指定 id 的一个元素

<div id="one">我是一个div标签</div>
<script>
  var div = document.getElementById('one');  // 查找id为one的标签
  console.log(div);
</script>

2.getElementsByTagName()
返回一个HTMLCollection(伪数组),包含匹配指定标签名的所有元素。

<p>我是第一个p标签</p>
<p>我是第二个p标签</p>
<p>我是第三个p标签</p>
<script>
  var p = document.getElementsByTagName('p');  // 查找所有p标签
  console.log(p);  //
</script>

3.getElementsByClassName()
返回一个HTML集合HTMLCollection(伪数组),包含匹配指定类名的所有元素。

<div class="one">我是div标签</div>
<div class="one">我是div标签</div>
<div class="one">我是div标签</div>
<script>
  var div = document.getElementsByClassName('one');  // 查找class为one的标签
  console.log(div);
</script>

4.document.querySelector()
返回文档中匹配指定的CSS选择器的第一元素

<div id="div1">111</div>
<div id="div1">222</div>
<script>
  document.querySelector("#div1").innerHTML = "Hello World";
  //将第一个id="div1"的区域内容改为Hello world
</script>

5.document.querySelectorAll()
查找匹配指定 CSS 选择器(id、类名、类型、属性、属性值等等)的所有 HTML 元素

<p>段落1</p>
<p class="one">段落22</p>
<p class="one">段落33</p>
<p id="demo"></p>
<script>
var x = document.querySelectorAll("p.one");
document.getElementById("demo").innerHTML = x[1].innerHTML; 
//返回了class="one"的第二个索引,id="demo"的段落内容变为 段落33
</script>

1.2操作html元素

改变html元素:

项目描述
element.innerHTML = new html content改变元素的 inner HTML
element.attribute = new value改变 HTML 元素的属性值
element.setAttribute(attribute, value)改变HTML 元素的属性值
element.style.property = new style改变 HTML 元素的样式
<p id="p1">段落1</p>
<p id="p2">段落2</p>
<script>
document.getElementById("p2").innerHTML = "段落已被改变";//段落内容已改为段落已被改变
document.getElementById("p2").style.color = "blue";//第二个段落的样式已被修改,颜色变为蓝色
var x = document.querySelector('#p2');
x.id='p3';  //将x的id属性改为p3
//或者也可以写成x.setAttribute('id', 'p3')
document.getElementById("p3").innerHTML ="段落再次被改变"
</script>

2.Node类型

DOM Level 1 描述了名为 Node 的接口,这个接口是所有 DOM 节点类型都必须实现的。Node 接口在 JavaScript中被实现为 Node 类型,在除 IE之外的所有浏览器中都可以直接访问这个类型。在 JavaScript中,所有节点类型都继承 Node 类型,因此所有类型都共享相同的基本属性和方法。

2.1属性

1.nodeType
nodeType属性返回一个整数值,表示节点的类型。

节点类型对应常量
文档节点(document)9Node.DOCUMENT_NODE
元素节点(element)1Node.ELEMENT_NODE
属性节点(attr)2Node.ATTRIBUTE_NODE
文本节点(text)3Node.TEXT_NODE
文档类型节点(DocumentType)10Node.DOCUMENT_TYPE_NODE
注释节点(Comment)8Node.COMMENT_NODE
文档片断节点(DocumentFragment)11Node.DOCUMENT_FRAGMENT_NODE
<script>
  console.log(element.nodeType); //输出1
</script>

2.nodeName
nodeName属性返回节点的名称(大写的元素名)。

<p id="one">123456</p>
<script>
  var abc = document.getElementById('one');
  console.log(abc.nodeName); //输出P
</script>

3.nodeValue
nodeValue属性返回一个字符串,表示当前节点本身的文本值。nodeValue只能获得文本节点的值,不能获得元素节点的值

<div id="d1">hello world</div>
<script>
  var div = document.getElementById('d1');
  console.log(div.nodeValue); // null,因为div是一个元素节点
  console.log(div.firstChild.nodeValue); //hello world,div的第一个子节点才是文本节点
</script>

4.textContent
textContent属性返回当前节点和它的所有后代节点的文本内容

<div id="one">Hello World!
	<P>Hello DOM!</P>
</div>
<script>
  var x = document.getElementById('one');
  console.log(x.textContent); //Hello World!    Hello DOM!
</script>

5.nextSibling
nextSibling属性返回紧跟在当前节点后面的第一个同级节点。如果当前节点后面没有同级节点,则返回null
注意可能会识别到“空格”或“回车”这样的文本节点

<div id="d1">hello</div><div id="d2">world</div> //两个div之间不能换行
<script>
  var div1 = document.getElementById('d1');
  var div2 = document.getElementById('d2');
  console.log(div1.nextSibling); //输出<div id="d2">world</div>
</script>

6.previousSibling
previousSibling属性返回当前节点前面的、距离最近的一个同级节点。如果当前节点前面没有同级节点,则返回null(同上,也可能会识别空格或回车)。

<div id="d1">111</div><div id="d2">222</div>
<script>
  var div1 = document.getElementById('d1');
  var div2 = document.getElementById('d2');
  console.log(div2.previousSibling);   //<div id="d1">hello</div>
</script>

7.parentNode
parentNode属性返回当前节点的父节点。对于一个节点来说,它的父节点只可能是三种类型:元素节点(element)、文档节点(document)和文档片段节点(documentfragment)

<div id="d1"><div id="d2"></div></div>
<script>
  var div1 = document.getElementById('d1');
  var div2 = document.getElementById('d2');
  console.log(div1.parentNode); // body
  console.log(div2.parentNode); // <div id="d1"></div>
</script>

8.parentElement
parentElement属性返回当前节点的父元素节点。如果当前节点没有父节点,或者父节点类型不是元素节点,则返回null
与parentNode的区别:
在获取根部document节点时,parentElement找的是元素,因此返回null,而parentNode获取的是节点,返回的是#document。

<div id="d1"></div>
<script>
  var div1 = document.getElementById('d1');
  console.log(div1.parentElement); // body
  console.log(div1.parentElement.parentElement);  //html
  console.log(div1.parentElement.parentElement.parentElement);  //null
  console.log(div1.parentNode.parentNode.parentNode);  //#document
</script>

.9.firstChild和lastChild
firstChild属性返回当前节点的第一个子节点,如果当前节点没有子节点,则返回null,last则返回最后一个子节点。

  <div id="d1">我是父节点<div>我是子节点</div></div>
  <div id="d2"></div>
  <script>
    var div1 = document.getElementById('d1');
    console.log(div1.firstChild); //输出"我是父节点",因为文本内容属于文本节点
    console.log(div1.lastChild); // <div>我是子节点</div>
    var div2 = document.getElementById('d2');
    console.log(div2.firstChild); // null
  </script>

10.childNodes
childNodes属性返回一个类似数组的对象(NodeList集合),成员包括当前节点的所有子节点

  <div id="d1">Hello DOM<div>我是子节点</div><p>我也是子节点</p></div>
  <script>
    var div1 = document.getElementById('d1');
    console.log(div1.childNodes);
  </script>

输出结果为:
在这里插入图片描述

2.2方法

1.appendChild
appendChild方法接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点。该方法的返回值就是插入文档的子节点。

<div id="d1"><p>段落1</p><p>段落2</p></div>
<button onclick="myFunction()">点我</button>
<script>
  function myFunction(){
    var node=document.createElement("p");
    node.innerHTML = '段落3';
    document.getElementById("d1").appendChild(node);
  }//按下按钮后,div最后多出一个段落3
</script>

2.insertBefore()
insertBefore方法用于将某个节点插入父节点内部的指定位置。
parentNode.insertBefore(newNode, referenceNode),该方法接受两个参数,第一个参数是所要插入的节点newNode,第二个参数是父节点parentNode内部的一个子节点referenceNode。newNode将插在referenceNode这个子节点的前面。返回值是插入的新节点newNode。

<ul>
    <li>ECMAScript</li>
    <li>DOM</li>
    <li>BOM</li>
</ul>
<script>
    var x = document.querySelector('ul');
    var y = document.createElement("li");
    y.innerHTML = 'JS';
    x.insertBefore(y,x.children[0]);//将js插入到第一个子节点前面,使得js成为第一个子节点
</script>

3.removeChild()
removeChild方法接受一个子节点作为参数,用于从当前节点移除该子节点。返回值是移除的子节点。

<ul>
    <li>ECMAScript</li>
    <li>DOM</li>
    <li>BOM</li>
</ul>
<script>
    var x = document.querySelector('ul');
    x.removeChild(x.children[2]); //ul的第三个li被删除
</script>

4.replaceChild()
replaceChild方法用于将一个新的节点,替换当前节点的某一个子节点。
parentNode.replaceChild(newChild, oldChild),replaceChild方法接受两个参数,第一个参数newChild是用来替换的新节点,第二个参数oldChild是将要替换走的子节点。返回值是替换走的那个节点oldChild。

<ul>
    <li>ECMAScript</li>
    <li>DOM</li>
    <li>BOM</li>
</ul>
<script>
    var x = document.querySelector('ul');
    var y = document.createElement("p");
    y.innerHTML = 'JS';
    x.replaceChild(y,x.children[2]);//ul里第三个li的内容变成了"JS"
</script>

5.node.cloneNode()
返回调用该方法的节点的一个副本,如果括号参数为空或false,则只克隆复制节点本身,不克隆里面的内容;如果括号参数为true,则克隆复制节点本身及里面内容。

<ul>
    <li>ECMAScript</li>
    <li>DOM</li>
    <li>BOM</li>
</ul>
<script>
    var x = document.querySelector('ul');
    var y =x.children[0].cloneNode(true);
    x.appendChild(y);
    //x的第一个子元素被复制,并插入到x的最后,成为x的第四个元素
</script>

3.事件

3.1概述

JavaScript使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为。
网页中的每个元素都可以产生某些可以触发 JavaScript 的事件,例如,我们可以在用户点击某按钮时产生一个事件,然后去执行某些操作。

事件三要素:

  • 事件源:触发事件的元素
  • 事件类型: 例如 click 点击事件
  • 事件处理程序:事件触发后要执行的代码(函数形式),事件处理函数
<button id="but1">按我</button>
<script>
    var btn = document.getElementById('btn');  //btn为事件源
    btn.onclick = function(){  //onclick为事件类型
        alert('按钮已被按下');  //alert为事件处理程序
    }
</script>

3.2常见事件

常见的鼠标事件:

  • 1.onclick 鼠标点击左键触发
  • 2.onmouseover 鼠标经过触发
  • 3.onmouseout 鼠标离开触发
  • 4.onfocus 获取鼠标焦点触发
  • 5.onblur 失去鼠标焦点触发
  • 6.onmousemove 鼠标移动触发
  • 7.onmouseup 鼠标弹起触发
  • 8.onmousedown 鼠标按下触发

常用的键盘事件:

  • 1.onkeyup 某个键盘按键被松开时触发
  • 2.onkeydown 某个键盘按键被按下时触发
  • 3.onkeypress 某个键盘按键被按下时触发,但是它不识别功能键,比如ctrl、shift箭头等。

3.3注册事件

给元素添加事件,称为注册事件/绑定事件。注册事件有两种方式:传统方式和方法监听注册方式。

3.3.1传统注册方式

利用 on 开头的事件
DOM 0级事件绑定方式—— 因为 W3C 在确定 DOM 版本时,在之前已经有了事实上存在的一些事件,比如 onclick 这种直接绑定给元素的属性的事件,DOM1 中用的还是之前的事件,所以是 DOM 0级事件,而不是1级事件

<button oncilck = "alert(1)"></button>
btn.onclick = function () {
}

特点:注册事件的唯一性(同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数)

3.3.2 方法监听注册方式

方法:addEventListener()
特点:同一个元素可以多次绑定事件监听,同一个事件类型可以注册多个事件函数
语法:element.addEventListener(event, function, useCapture)
第一个参数是事件的类型(比如 “click” 或 “mousedown”)。第二个参数是当事件发生时我们需要调用的函数。第三个参数是布尔值,指定使用事件冒泡还是事件捕获。此参数是可选的。
注意:请勿对事件使用 “on” 前缀;请使用 “click” 代替 “onclick”。

下面的程序中,按下按钮将会弹出"Hello world"

<button id="myBtn">按我</button>
<script>
document.getElementById("myBtn").addEventListener("click", function() {
  alert("Hello World!");
});
</script>

向相同元素添加多个事件处理程序:addEventListener()方法允许向相同元素添加多个事件,同时不覆盖已有事件:

<button id="myBtn">点击</button>
<script>
var x = document.getElementById("myBtn");
x.addEventListener("click", myFunction);
x.addEventListener("click", OtherFunction);
function myFunction() {
  alert ("此函数被执行了!");
}
function OtherFunction() {
  alert ("此函数也被执行了!");
}
</script>

也能够向相同元素添加不同类型的事件:

<button id="myBtn">点击</button>
<p id="demo"></p>
<script>
var x = document.getElementById("myBtn");
x.addEventListener("mouseover", myFunction);
x.addEventListener("click", mySecondFunction);
x.addEventListener("mouseout", myThirdFunction);
function myFunction() {
  document.getElementById("demo").innerHTML += "Moused over!<br>";
}
function mySecondFunction() {
  document.getElementById("demo").innerHTML += "Clicked!<br>";
}
function myThirdFunction() {
  document.getElementById("demo").innerHTML += "Moused out!<br>";
}
</script>

3.4删除(解绑)事件

3.4.1传统注册方式

eventTarget.onclick = null

var btn = document.getElementById("btn");
btn.onclick = function () {
  alert(1);
};
btn.onclick = null;// 解除绑定方法
3.4.2方法监听注册方式

element.removeEventListener() 方法,含有两个参数,第一个参数是事件类型的字符串(直接书写” click” ,不需要加 on),第二个参数为事件函数名字。

var btn = document.getElementById("btn");
btn.addEventListener("click", fun);
function fun() {
	alert(1);
	btn.removeEventListener("click", fun);
}// 点击按钮,只弹出一次1,点第二次不再弹出

三、总结

上节课我们学习了JavaScript的基础,包括JavaScript基础语法,变量类型,运算符,函数等,尤其是函数的异步,没有做好预习,经过补救后基础地掌握了异步的本质,可以得出一些简单程序的结果。在文章的末尾,衷心感谢学长学姐们的教导。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值