Python测开28期-偕行-JavaScript的BOM与DOM

一、BOM

1、 什么是BOM ?

BOM(Browser Object Model)即浏览器对象模型使 JavaScript 有能力与浏览器“对话”。

BOM提供了访问浏览器各种功能部件的途径,例如浏览器窗口本身、浏览历史等;

DOM提供了访问浏览器中网页文档各元素的途径,包括页面中的超链接、表单等各种HTML元素及其内容。

BOMDOM是独立于程序语言和平台的标准,W3C定义了一组标准接口,而这些接口在浏览器中以对象的形式实现。BOMDOM均由一组对象组成,对象定义了属性和方法。

2、 BOM结构图

image
结构图说明:

  1. 反映了BOM中各对象之间的层次关系。
  2. BOM中,window对象是顶层对象,其它对象均是其子对象
  3. history浏览器的浏览历史
  4. location对象代表当前显示的文档的地址
  5. navigator对象提供有关浏览器的各种信息
  6. screen对象提供显示器屏幕相关的一些信息
  7. frames[]window对象的数组型属性,每一个数组元素对应框架集(frameset)中的一个框架(frame)所对应的窗口
  8. document对象是对DOM的引用,代表了当前浏览器窗口中的网页文档

二、 Window 对象

1、 什么是 Window 对象 ?

Window对象是BOM顶层对象,表示浏览器窗口或者网页中的框架。

Window 对象是脚本中的全局对象,可以在任何地方调用,脚本中任何对象的使用最终都要追溯到对window对象的访问,所以在使用window对象的各种属性和方法时,window前缀可以省略。

访问window对象或子对象属性和方法,要按照层次关系,使用“.”运算符将它们连接起来。

window.alert(); 简写方式 alert();

window.document.write(); 简写方式 document.write();

所有 JavaScript 全局对象、函数以及变量均自动成为 window 对象的成员。

    1. 全局变量是Window的对象属性。
<!-- 变量a就是全局变量,也是Window对象上的属性 -->
var a = 19;
<!-- 调用 -->
console.log(window.a);// 19
    1. 全局函数是Window的对象方法。
<!-- 定义全局函数 -->
function inner() {
   console.log('全局方法');
}
<!-- 调用 -->
window.inner();// 全局方法
    1. 甚至HTML DOMdocument 也是window对象的属性之一。

2、 window 对象的属性和方法

  1. alert (); 显示带有一段消息和一个确认按钮的警告框

  2. confirm();显示带有一段消息以及确认按钮和取消按钮的对话框

  3. setInterval();按照指定的周期(以毫秒计)来调用函数或计算表达式。

  4. setTimeout();指定的毫秒数后调用函数或计算表达式。

  5. clearInterval();取消由setInterval()设置的timeID

  6. clearTimeout();取消由setTimeout()方法设置的timeID

  7. scrollTo();览器滚动到指定的位置

(1)定时器函数

image

(2)重复定时器函数setInterval()

  • window.setInterval(); 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。

  • setInterval() 方法会不停地调用函数,直到 window.clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作clearInterval()方法的参数。

setIntervar(code,millisec);
  • window.setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。
setTimeout(code,millisec);

(3)消除计时器clearInterval(timeId)

定时器一般用于制作动画效果,比如每隔一段时间就移动某个元素的位置。

  • clearInterval(timeId) => 取消由 setInterval() 设置的 timeId

  • clearTimeout(timeId) => 取消由 setTimeout() 方法设置的 timeId

三、 BOM 其他对象

1、 screen 对象

  1. screen.availWidth:显示器屏幕可用宽度,除任务栏外。

  2. screen.availHeight:显示器屏幕可用高度,除任务栏外。

  3. screen.width:显示器屏幕实际宽。

  4. screen.height:显示器屏幕实际高。

<script>
    console.log("screen 对象:",screen)
    console.log("显示器屏幕可用宽度,除任务栏外:",screen.availWidth)
    console.log("显示器屏幕可用高度,除任务栏外:",screen.availHeight)
    console.log("显示器屏幕实际宽:",screen.width)
    console.log("显示器屏幕实际高:",screen.height)
</script>

2、 history 对象

该对象记录了浏览器的浏览历史,并提供一组方法访问曾经访问过的历史页面。

  1. length整数值,表示浏览器历史列表中的URL的个数。

  2. back();返回到浏览器列表中当前页面之前的页面,与浏览器的“返回”功能相同。

  3. forward();前进到浏览器中当前页面之后的页面,与浏览器的“前进”按钮功能相同。

  4. go();访问浏览器列表中指定的页面,该方法接受一个参数。参数可正可负。

<script>
    console.log("history 对象:",history)
    console.log("浏览器历史列表中的URL的个数:",history.length)
</script>

image

3、 location 对象

该对象存储了当前显示的文档的地址,包括完整的URL地址以及组成URL地址的各个部分。其中各个属性被重新赋值后,浏览器将自动刷新,载入新的URL地址。

  • hash表示URL地址中的锚点部分,包括前导符“#”。可读可写。
  • host表示URL中的主机名和端口,即IP地址或者域名端口,可读可写。
  • hostname表示URL中的主机名部分。可读可写
  • href表示当前页面完整的URL地址,可读可写。
  • pathname表示URL的页面路径部分,包含页面文件名称,可读可写。
  • port表示URL地址中的端口部分,可读可写
  • protocol表示URL中的协议部分,包括尾部的":"符号,可读可写
  • search表示URL中的参数部分,可读可写。
<script>
    console.log("location  对象:",location)
    console.log("hash表示URL地址中的锚点部分:",location.hash)
    console.log("hostname:",location.hostname)
    console.log("host表示URL中的主机名和端口:",location.host)
    console.log("hostname表示URL中的主机名部分:",location.hostname)
    console.log("href表示当前页面完整的URL地址:",location.href)
    console.log("pathname表示URL的页面路径部分:",location.pathname)
    console.log("port表示URL地址中的端口部分:",location.port)
    console.log("protocol表示URL中的协议部分:",location.protocol)
    console.log("search表示URL中的参数部分:",location.search)
</script>

4、 navigator 对象

该对象提供有关浏览器的各种信息,所有浏览器都支持该对象

  1. userAgent返回由客户机发送服务器的user-agent头部的值
  2. cookieEnabled返回指明浏览器中是否启用cookie的布尔值
<script>
    console.log("navigator   对象:",navigator )
</script>

四、DOM

1、什么是DOM

DOM 是Document Object Model首字母缩写词,代表文档对象模型。文档对象模型 (DOM) 是 HTML 和 XML 文档的编程接口。它将文档的结构表示为对象树,每个对象表示文档的一部分,例如元素、属性或文本节点。

JavaScript 可用于与 DOM 交互,允许开发人员创建可以更新和响应用户输入的动态网页。JavaScript DOM 允许您操作和访问 HTML 或 XML 文档的元素、属性和内容,无需重新加载网页即可更改网页的结构、布局和内容。

(1) 文档:DOM中的"D"

D代表document-文档,如果没有document,DOM也就无从谈起。当创建一个网页并把它加载到web浏览器中时,DOM就在幕后悄然而生。它将根据你编写的网页文档创建一个文档对象。

(2) 对象:DOM中的”O“

O代表object-对象,对象是一种独立的数据集合。与某个特定对象相关联的变量被称为这个对象的属性;可以通过某个特定对象去调用的函数被称为这个对象的方法。

Javascript语言中的对象可以分为三种类型:

  1. 用户定义对象(user-defined object):由程序员自行创建的对象。
  2. 内建对象(native object):内建的Javascript语言中的对象,如Array、Math和Date等。
  3. 宿主对象(host object):由浏览器提供的对象,比如window对象

(3) 模型:DOM中的“M”

​ DOM中的“M”代表着“Model”(模型),但说它代表着“Map(地图)”也是可以的。模型也好,地图也罢,它们的含义都是某种事物的表现形式。就像一个模型火车代表着一列真正的火车、一张城市街道图代表着一个世纪存在的城市那样,DOM代表着被加载到浏览器窗口里的当前网页:浏览器由我们提供了当前的地图(或者说模型),而我们可以通过JavaScript去读取这张地图。

2、DOM树

DOM把一份文档表示为一颗树(这里所说的“树“是数学意义上的概念),这是我们理解和运用这一模型的关键。更具体的说,DOM把文档表示一颗家谱树。

​ 家谱数本身又是一种模型。家谱树的典型用法是表示一个人类家族的谱系关系并使用parent(父)、child(子)、sibling(兄弟)等记号来表明家族成员之间的关系。家谱树可以把一些相当复杂的关系简明表示出来:一位特定的成员既是某些成员的父辈,又是另一位成员的子辈,同时还是另一位成员的兄弟。
image

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>class list</title>
</head>
<body>
	<h2>你要买什么课程?</h2>
	<p title='请您选择购买的课程'>本课程是web全栈课程,期待你的购买!</p>
	<ul id='classList'>
		<li class='item'>JavaScript</li>
		<li class='item'>css</li>
		<li>DOM</li>
	</ul>
</body>
</html>


由此图可以看出来该家谱数以html为根元素的。毫无疑问,html元素完全可以代表整个文档。

​ 我们会发现<head><body>两个分枝。他们存在于同一个层次且互不包含,所以他们是兄弟关系。他们有着共同的父元素<html>,但又各有各的子元素,所以它们本身又是其它一些元素的父元素。

<head>元素由两个子元素:<meta><title>(这两个元素是兄弟关系)。<body>元素由三个子元素:<h1><p><ul>(这三个元素是兄弟关系)。如果继续深入下去,我们将发现<ul>也是一个父元素。他有三个子元素,他们都是<li>元素。

​ 利用这种简单的家谱关系记号,我们可以把各元素之间的关系简明清晰地表达出来。

​ 如果把各种文档元素都想象成一颗家谱树的各个节点的话,我们就可以用同样的记号来描述DOM。不过,与使用”家谱树“这个术语相比,把一份文档称为一颗“节点树”更准确。

3、节点

在 JS 操作 DOM 的时候,我们有时候会操作 Node 节点,有时候也会操作 Element;

  • Node:

在 DOM 树中,所有的节点都是 Node,包括 Element,也就是说 Node 包含了 HTML 元素标签、text、以及注释等等内容,它是所有 DOM 的基类。

  • Element:

在 DOM 树中,Element 是所有 HTML 元素的基类,也就是说,Element 只包含 HTML 元素标签。

  • Node 和 Element 两者是包含关系,Node 包含 Element。从而衍生出了两个集合:

    • NodeList 是 Node 的集合;
    • HTMLCollection 是 Element 的集合。
  • childNodes:Node.childNodes 返回包含指定节点的子节点的集合,该集合为即时更新的NodeList 集合。

    • childNodes会返回所有节点,包括HTML、Text、注释等等内容;
    • childNodes包含children;
      image
  • children理解:Element.children 是一个只读属性,返回 一个Node的子elements ,是一个动态更新的 HTMLCollection 集合。

    • children只返回元素节点。
      image
<body>
    <div id="parent">
        <div id="firstchild">i am a first child</div>
        <p id="secondchild">i am the second child</p>
        <h4>i am alive</h4>
        <h1>hello world</h1>
        <p>i am the last child</p>
    </div>

    <script>
        // 获取元素/节点
        const parent = document.getElementById('parent')
        console.log("parent:",parent) //<div id="parent">...</div>
        
        // parent.children
        console.log("parent.children:",parent.children) // [div#firstchild, p#secondchild, h4, h1, p, firstchild: div#firstchild, secondchild: p#secondchild]
        
        // parent.childNodes
        console.log("parent.childNodes:",parent.childNodes) //  [text, div#firstchild, text, p#secondchild, text, h4, text, h1, text, p, text]
    </script>
</body>

(1) 元素节点

在刚才上述的“课程列表”的文档时,像<body><p><ul>之类的元素这些我们都称为叫元素节点(element node)。如果把web上的文档比作一座楼,元素就是建造这座楼的砖块,这些元素在文档中的布局形成了文档的结构。

各种标签提供了元素的名字。文本段落元素的名字是"p",无序列表元素的名字是“ul”,列表项元素的名字是“li”。

(2)文本节点

<p title='请您选择购买的课程'>本课程是web全栈课程,期待你的购买!</p>

<p> 元素包含着文本"本课程是web全栈课程,期待你的购买!" 。它是一个文本节点(text node)。

(3)属性节点

标签元素或多或少都有一些属性,属性的作用是对元素做出更具体的描述。

在DOM中,title='请您选择购买的课程' 是一个属性节点(attribute node)。如图所示。属性总是被放在起始标签里,所以属性节点总是被包含在元素节点当中。并非所有的元素都包含着属性,但所有的属性都会被包含在元素里。
image

(4)节点属性

在文档对象模型(DOM)中,每一个节点都是一个对象。DOM节点有三个重要的属性:

  • nodeName属性:节点的名称,是只读

      1. 元素节点的nodeName与标签名相同
      1. 属性节点的nodeName与属性的名称相同
      1. 文本节点的nodeName永远是#text
      1. 文档节点的nodeName永远是#document
  • nodeValue属性:节点的值

      1. 元素节点的 nodeValue 是 undefined 或 null
      1. 文本节点的 nodeValue 是文本自身
      1. 属性节点的 nodeValue 是属性的值
  • nodeType 属性: 节点的类型,是只读的。
    image

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="parent">
        <div id="firstchild">i am a first child</div>
        <p id="secondchild">i am the second child</p>
        <h4>i am alive</h4>
        <h1>hello world</h1>
        <p>i am the last child</p>
    </div>

    <script>
        // 获取元素/节点
        const parent = document.getElementById('parent')
        console.log("parent:",parent) //<div id="parent">...</div>
        // 获取节点名称、属性值、类型
        console.log("parent.nodeName:",parent.nodeName)
        console.log("parent.nodeValue:",parent.nodeValue)
        console.log("parent.nodeType:",parent.nodeType)
    </script>
</body>
</html>

image

(5)子、父、兄弟、祖先–元素/节点

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>class list</title>
</head>
<body>
    <div id="parent">
        <div id="firstchild">i am a first child</div>
        <p id="secondchild">i am the second child</p>
        <h4>i am alive</h4>
        <h1>hello world</h1>
        <p>i am the last child</p>
    </div>
    <script>
        // 获取父级元素
        const parent = document.getElementById('parent')
        // parent
        console.log("parent:",parent) //<div id="parent">...</div>
        console.log("parent.firstElementChild:",parent.firstElementChild) // <div id="firstchild">i am a first child</div>
        console.log("parent.secondElementChild:",parent.secondElementChild) //undefined
        console.log("parent.lastElementChild",parent.lastElementChild) // <p>i am the last child</p>
        console.log("parent.firstChild",parent.firstChild) // #text
        console.log("parent.lastChild",parent.lastChild)  // #text
        
        // 获取节点名称、属性值、类型
        console.log("parent.nodeName:",parent.nodeName)
        console.log("parent.nodeValue:",parent.nodeValue)
        console.log("parent.nodeType:",parent.nodeType)
        // parent.children
        console.log("parent.children:",parent.children) // [div#firstchild, p#secondchild, h4, h1, p, firstchild: div#firstchild, secondchild: p#secondchild]
        console.log("parent.children.firstchild:",parent.children.firstchild) // <div id="firstchild">i am a first child</div>
        console.log("parent.children.secondhild:",parent.children.secondhild) // undefined
        console.log("parent.children.lastchild",parent.children.lastchild) // undefined
        console.log("parent.children.firstElementChild",parent.children.firstElementChild) // undefined
        console.log("parent.children.lastElementChild",parent.children.lastElementChild) // undefined
        
        // parent.childNodes
        console.log("parent.childNodes:",parent.childNodes) //  [text, div#firstchild, text, p#secondchild, text, h4, text, h1, text, p, text]
        console.log("parent.childNodes.firstchild:",parent.childNodes.firstchild) // undefined
        console.log("parent.childNodes.lastchild:",parent.childNodes.lastchild) // undefined
        console.log("parent.childNodes.firstElementChild:",parent.childNodes.firstElementChild) // undefined
        console.log("parent.childNodes.lastElementChild:",parent.childNodes.lastElementChild) // undefined

        // 获取子元素
        const secondchild = document.getElementById('secondchild')
        console.log("secondchild:",secondchild) //<p id="secondchild">i am the second child</p>

        // 子元素的父级元素
        console.log("secondchild.parentNode:",secondchild.parentNode) //<div id="parent">...</div>
        console.log("secondchild.parentElement:",secondchild.parentElement) //<div id="parent">...</div>
        // 子元素的下一个元素
        console.log("secondchild.nextElementSibling:",secondchild.nextElementSibling) //<h4>i am alive</h4>
        console.log("secondchild.nextElement:",secondchild.nextElement) //undefined
        // 子元素的上一个元素
        console.log("secondchild.previousElementSibling:",secondchild.previousElementSibling) //<div id="firstchild">i am a first child</div>
        // 子元素的儿子元素
        console.log("secondchild.children:",secondchild.children) // []
        // 子元素的儿子节点
        console.log("secondchild.childNodes:",secondchild.childNodes) // [text]
    </script>
</body>
</html>

A、子节点/子元素

  • 节点
    • Element.firstChild :第一个子节点;
    • Element.lastChild :最后一个子节点;
    • Element.childNodes[索引值]:获取指定位置(索引)的子节点;
        // 获取父级元素
        const parent = document.getElementById('parent')

        console.log("parent.firstChild",parent.firstChild) // #text
        console.log("parent.lastChild",parent.lastChild)  // #text

        console.log("parent.childNodes:",parent.childNodes) //  [text, div#firstchild, text, p#secondchild, text, h4, text, h1, text, p, text]
        console.log("parent.childNodes[1]:",parent.childNodes[1]) //  <div id="firstchild">i am a first child</div>
  • 元素
    • Element.firstElementChild:获取第一个子元素;
    • Element.lastElementChild:获取最后一个子元素;
    • Element.children.firstchild:获取第一个子元素;
    • Element.children.firstchild[索引]:获取指定位置(索引)的元素;
// 获取父级元素
        const parent = document.getElementById('parent')
        // parent
        console.log("parent:",parent) //<div id="parent">...</div>
        console.log("parent.firstElementChild:",parent.firstElementChild) // <div id="firstchild">i am a first child</div>
        console.log("parent.lastElementChild",parent.lastElementChild) // <p>i am the last child</p>

// parent.children
        console.log("parent.children:",parent.children) // [div#firstchild, p#secondchild, h4, h1, p, firstchild: div#firstchild, secondchild: p#secondchild]
        console.log("parent.children.firstchild:",parent.children.firstchild) // <div id="firstchild">i am a first child</div>

B、父节点/父元素

  • 父节点:Element.parentNode
  • 父元素:Element.parentElement
        const secondchild = document.getElementById('secondchild')
        console.log("secondchild:",secondchild) //<p id="secondchild">i am the second child</p>

        // 子元素的父级元素
        console.log("secondchild.parentNode:",secondchild.parentNode) //<div id="parent">...</div>
        console.log("secondchild.parentElement:",secondchild.parentElement) //<div id="parent">...</div>
  • 祖先节点:Element.parentNode.parentNode...
  • 祖先元素:Element.parentElement.parentElement...

C、访问兄弟节点

  • 某个节点之后紧跟的节点:Element.nextElementSibling,如果无此节点,则该属性返回null;

  • 某个节点之前紧跟的节点:Element.previousElementSibling,如果无此节点,则该属性返回null;

4、获取元素/节点的方法

文档中的每一个元素都对应着一个对象。 利用DOM提供的方法,我们可以把与这些元素怒相对应的任何一个对象筛选出来。

(1)通过id获取元素document.getElementById(" id ")方法

  • 元素的 id 是页面中的唯一标识符;

  • 该方法将返回一个与那个给定id属性值的元素节点相对应的对象;

  • 只有一个参数:你想获得的那个元素的id属性值,这个id值必须是字符串类型。

  • 注意:ID 会考虑大小写。例如,ids"master""Master" 是完全不同的。

<body>
	<p id="controller">i'm a javascript lover</p>

    <script>
        const controllerEl = document.getElementById('controller')
        console.log(controllerEl) //<p id="controller">i'm a javascript lover</p> 
        console.log(typeof controllerEl) // object
    </script>
</body>

(2)通过标签名获取元素document.getElementsByTagName("标签名")方法

  • 这个方法将返回一个元素对象集合
  • 参数:标签名,并按照给定标记名称的每个元素在文档中出现的顺序返回它们。
<body>
	<p>GitHub</p>
    <p>Firebase</p>
    <p>HTML</p>
    <button id="btn">click me</button>
    <script>
        // 通过id获取到button对象
        const btn = document.getElementById("btn");
        // 给button添加监听事件
        btn.addEventListener("click", function master() {
            // 通过标签名p获取到所有的p标签对象
            let pElement = document.getElementsByTagName("p");
            console.log(pElement)
            console.log(typeof pElement)
            // 给第二个p标签元素设置文本
            let masterEl = (pElement[1].innerHTML = "我是新来的文本");
            console.log(masterEl); // 我是新来的文本
        });
    </script>
</body>

(3)通过类名获取元素document.getElementsByClassName("类名")

  • 返回:类名相同的所有元素的集合

  • 参数:类名,并按照给定类名的每个元素在文档中出现的顺序返回它们;

  • 注意:类名区分大小写;

<body>
    <p class="master2">i'm a javascript lover</p>
    <p class="Master2">i love react too well</p>
    <h1 class="master2">i want a remote job</h1>
    <button id="btn">click me</button>

    <script>
        const btn = document.getElementById('btn')

        btn.addEventListener('click', function master(){
            var masterEl = document.getElementsByClassName("master2");
            console.log(masterEl)
            masterEl[1].innerHTML = '我是新来的文本';
        })
    </script>
</body>

(4) 如何使用 CSS 选择器选择 DOM 元素

A、document.querySelector("css选择器")

  • 返回与指定选择器匹配的第一个值
<body>
    <p class="master2">i'm a javascript lover</p>
    <p class="Master2">i love react too well</p>
    <h1 class="master2">i want a remote job</h1>
    <button id="btn">click me</button>

    <script>
        const classEl = document.querySelector('.master2')
        // 只返回匹配的第一个值
        console.log(classEl) // <p class="master2">i'm a javascript lover</p>
        
        const pEl = document.querySelector('p')
        console.log(pEl) // <p class="master2">i'm a javascript lover</p>
    </script>
</body>

B、document.querySelectorAll("css选择器")

  • 返回所有匹配的节点列表集合
<body>
    <p class="master2">i'm a javascript lover</p>
    <p class="Master2">i love react too well</p>
    <h1 class="master2">i want a remote job</h1>
    <button id="btn">click me</button>

    <script>
        const classEl = document.querySelectorAll('.master2')
        console.log("classEl=",classEl) 
        
        const pEl = document.querySelectorAll('p')
        console.log("pEl=",pEl) 
    </script>
</body>
</html>

image

5、操作元素属性

通过上述方法找到对应的元素后, 可以利用getAttribute() 方法和setAttribute() 方法对元素的属性值进行操作。

(1)获取元素属性: Element.getAttrbute(attributeName: DOMString)方法

  • getAttribute()方法只接收一个参数——你打算查询的属性的名字字符串。

    • 如果查询不到结果,则该调用则返回null,null是JavaScript语言中的空值,其含义是你说的这个东西不存在
<body>
    <p title='请您选择购买的课程' class="score" id="web">本课程是web全栈课程,期待你的购买!</p>

    <script>
        var pEl = document.getElementById('web');
        // 获取title属性
        var titleAttr = pEl.getAttribute('title')
        console.log("titleAttr:",titleAttr)
        // 获取class属性
        var classAttr = pEl.getAttribute('class')
        console.log("classAttr:",classAttr)
        // 获取id属性
        var idAttr = pEl.getAttribute('id')
        console.log("idAttr:",idAttr)
        // 获取value属性
        var valueAttr = pEl.getAttribute('value')
        console.log("valueAttr:",valueAttr)
    </script>
</body>

image

(2)设置元素属性:Element.setAttribute(属性名, 属性值)方法

  • setAttrbute() 方法它允许我们对属性节点的值做出修改。此方法传递两个参数:
    • 第一个参数为属性名
    • 第二个参数为属性值
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 定义公共样式 -->
    <style>
        .highlight {
            color: red;
            background-color: rgb(141, 84, 84);
            padding: 10px;
            width: 250px;
            text-align: center;
        }
    </style>
</head>
<body>
    <h2>你要买什么课程?</h2>
	<p title='请您选择购买的课程'>本课程是web全栈课程,期待你的购买!</p>
	<ul id='classList'>
		<li class='item'>JavaScript</li>
		<li class='item'>css</li>
		<li>DOM</li>
	</ul>

    <script>
        var ulEl = document.getElementById('classList');
        // 给元素设置属性值
        ulEl.setAttribute('title','js代码设置的属性值')
        // 给元素设置css样式
        ulEl.setAttribute('class','highlight')
    </script>
</body>
</html>

6、 如何操作 DOM 中的元素

(1)创建元素/节点 document.createElement("tagName")

var newNode = document.createElement(tagName);
  • createElement() 方法可创建元素节点。此方法可返回一个Element对象;
  • 参数:tagName,标签名字符串,用来指明创建元素的类型;
<body>
    <script>
         const createEl = document.createElement('p')
        console.log(createEl) //<p></p>
        console.log(createEl.tagName);//P
    </script>
</body>

仅仅是创建了一个新的p元素节点,如何来设置该标签的文本内容呢?

注意:此文本内容,p标签既可以是纯文本,也可以在p标签中包含一些其它标签的文本。

innerText属性 :仅仅对元素来获取或者设置文本

<body>
    <script>
        // 创建标签元素
        const createEl = document.createElement('p')
        console.log(createEl) //<p>我是添加的文本</p>
        console.log(createEl.tagName);//P
        // 给元素设置文本内容
        createEl.innerText = '我是添加的文本'
        console.log(createEl) //<p>我是添加的文本</p>
    </script>
</body>

如果想在p标签插入一段<a>mjj</a> ,会发现<a>mjj</a> 它也会充当文本的来进行设置。

// 创建标签元素
        const createEl = document.createElement('p')
        // 给元素设置文本内容
        createEl.innerText = '<a>mjj</a>'
        console.log(createEl) //<p><a>mjj</a></p>

image

innerHTML属性:既可以设置文本又可以设置标签

// 创建标签元素
        const createEl = document.createElement('p')
        // 给元素设置文本内容
        createEl.innerHTML = '<a>mjj</a>'
        console.log(createEl) 

image

注意:如果想获取节点对象的文本内容,可以直接调用innerText或者innerHTML属性来获取

(2) 插入节点

  • 在指定的节点的最后一个子节点之后添加一个新的子节点:parentEl.appendChild(newPEl)

    • parentEl:父元素,也就是让父元素调方法,向儿子元素中插入一个元素;
    • newPEl:被插入的元素,必须保证这个元素存在,要么是新创建的,要么是从什么地方偷的,反正得有。
  • 在指定的儿子节点添加一个新子节点:parentEl.insertBefore(newSonEl,oldSonEl)

    • parentEl:父元素,也就是让父元素调方法,向儿子元素中插入一个元素;
    • newSonEl:被插入的元素;
    • oldSonEl:可以理解为位置,也就是在oldSonEl前插入;
<body>
    <div id="parent">
        <div id="firstchild">i am a first child</div>
        <p id="secondchild">i am the second child</p>
        <h4>i am alive</h4>
        <h1>hello world</h1>
        <p>i am the last child</p>
    </div>

    <script>
        // 获取元素
        var parentEl = document.getElementById('parent')
        // 创建一个新节点,并添加文本
        var newPEl = document.createElement('p')
        newPEl.innerHTML='在parent的最后一个子节点插入一个新节点'
        // 在parent的最后一个子节点插入一个新节点
        parentEl.appendChild(newPEl)
        // 获取元素
        var secondEl = document.getElementById('secondchild')
        // 创建一个新节点,并添加文本
        var newPEl2 = document.createElement('p')
        newPEl2.innerHTML='在secondEl节点前插入一个新的子节点'
        // 节点前插入一个新的子节点
        parentEl.insertBefore(newPEl2,secondEl)
    </script>
</body>

(3)删除节点

  • parentEl.removeChild(secondEl) 方法从子节点列表中删除某个节点。如果删除成功,此方法可返回被删除的节点,如失败,则返回NULL。
    • parentEl:父元素,也就是要删除这个父元素中的某个子元素;
    • secondEl:需要删除的子元素;
<body>
    <div id="parent">
        <div id="firstchild">i am a first child</div>
        <p id="secondchild">i am the second child</p>
        <h4>i am alive</h4>
        <h1>hello world</h1>
        <p>i am the last child</p>
    </div>

    <script>
        // 获取元素
        var parentEl = document.getElementById('parent')
        var secondEl = document.getElementById('secondchild')
        // 删除儿子节点secondEl
        var result = parentEl.removeChild(secondEl)
        console.log(result) // <p id="secondchild">i am the second child</p>
    </script>
</body>
  • 说明:成功删除后,secondEl这个子节点不在DOM树中,但是还存在内存中,可通过 result =null来删除对象。

(4)替换元素节点

  • parentEl.replaceChild(newEl,oldEl)实现子节点(对象)的替换。返回被替换对象的引用。
    • parentEl:父元素,它里面的儿子元素需要替换;
    • newEl:替换进去的新元素;
    • oldEl:被替换的老元素;
<body>
    <div id="parent">
        <div id="firstchild">i am a first child</div>
        <p id="secondchild">i am the second child</p>
        <h4>i am alive</h4>
        <h1>hello world</h1>
        <p>i am the last child</p>
    </div>

    <script>
        // 获取元素
        var parentEl = document.getElementById('parent')
        var oldEl = document.getElementById('firstchild')
        // 创建一个元素
        var newEl = document.createElement('p')
        newEl.innerHTML = "我是被替换进来的"
        // 用新元素替换老元素
        var result = parentEl.replaceChild(newEl,oldEl)
        console.log(result) // <div id="firstchild">i am a first child</div>
    </script>
</body>

image

(5) 创建文本节点

  • document.createTextNode("str"):创建新的文本节点,返回新创建的Text节点;
<body>
    <div id="parent">
        <div id="firstchild">i am a first child</div>
        <p id="secondchild">i am the second child</p>
        <h4>i am alive</h4>
        <h1>hello world</h1>
        <p>i am the last child</p>
    </div>

    <script>
        // 创建一个新节点
        var newNode = document.createElement('div');
        // 创建一个文本节点
        var textNode  = document.createTextNode('我是js创建的一条文本信息');
        console.log(textNode) // "我是js创建的一条文本信息"
        // 把文本节点添加到新节点中
        newNode.appendChild(textNode);
        // 把新节点添加到body中
        document.body.appendChild(newNode);
    </script>
</body>

image

7、如何操作css样式

通过JavaScript以不同的方式来操作CSS样式,我们可以通过该节点对象的style属性来实现。

(1) 动态设置样式

直接在想要动态设置样式的元素内部添加内联样式。这是用HTMLElement.style属性来实现。这个属性包含了文档中每个元素的内联样式信息。你可以设置这个对象的属性直接修改元素样式。

<body>
    <div id="parent">
        <div id="firstchild">i am a first child</div>
        <p id="secondchild">i am the second child</p>
        <h4>i am alive</h4>
        <h1>hello world</h1>
        <p>i am the last child</p>
    </div>

    <script>
        var secondEl = document.getElementById('secondchild');
        // 通过style属性来设置css
        secondEl.style.color = 'red';
        secondEl.style.backgroundColor = 'black';
        secondEl.style.padding = '10px';
		secondEl.style.width = '250px';
		secondEl.style.textAlign = 'center';
    </script>
</body>

(2) 操作属性的类来控制样式

  • 使用HTML操作的常用方法 -Element.setAttribute(属性,值)来控制样式;
    • 属性:比如class、id等等;
    • 值:对应的css选择器;
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 定义公共样式 -->
    <style>
        .highlight {
            color: red;
            background-color: black;
            padding: 10px;
            width: 250px;
            text-align: center;
        }
    </style>
</head>
<body>
    <div id="parent">
        <div id="firstchild">i am a first child</div>
        <p id="secondchild">i am the second child</p>
        <h4>i am alive</h4>
        <h1>hello world</h1>
        <p>i am the last child</p>
    </div>

    <script>
        var parentEl = document.getElementById('parent');
        // 通过操作属性的类来控制样式
        parentEl.setAttribute('class','highlight')
    </script>
</body>
</html>

(3)使用CSS类来控制样式

A、 如何添加 CSS 类Element.classList.add(css类)

案例:单击按钮时自动应用“按钮”类的 CSS 样式,需要为按钮添加一个事件侦听器。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 定义样式 -->
    <style>
        .button {
            background-color: blueviolet;
            width: 200px;
            border: none;
            font-size: 2rem;
            padding: 0.5rem;
            border-radius: 5px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <button id="click">Click me</button>

    <script>
        const buttonEl = document.getElementById('click')
        // 给按钮添加监听事件
        buttonEl.addEventListener('click', addFunction)
        // 定义事件响应的内容方法
        function addFunction(){
            // 给按钮添加css样式类
            buttonEl.classList.add('button')
        }
    </script>
</body>
</html>

image

B、 如何删除CSS类Element.classList.remove(css类)

案例:给按钮设置一个样式,点击之后按钮样式显示默认样式,也就是之前设置的样式被删除;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 定义样式 -->
    <style>
        .button {
            background-color: blueviolet;
            width: 200px;
            border: none;
            font-size: 2rem;
            padding: 0.5rem;
            border-radius: 5px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <button id="click">Click me</button>

    <script>
        const buttonEl = document.getElementById('click')
        // 先给按钮设置一个样式
        buttonEl.setAttribute('class','button')
        // 给按钮添加监听事件
        buttonEl.addEventListener('click', addFunction)
        // 定义事件响应的内容方法
        function addFunction(){
            // 点击的时候干掉设置的样式,也就是按钮样式恢复到默认
            buttonEl.classList.remove('button')
        }
    </script>
</body>
</html>

image

C、 如何切换CSS类Element.classList.toggle(css类)

大多数社交媒体网络,包括 Twitter,通常使用 classList.toggle() 函数。让用户可以在相同的按钮点击切换喜欢和不喜欢帖子。

案例:不删除样式,而是在样式之间来回切换,比如反复点击按钮在自定义样式和默认样式之间切换;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 定义样式 -->
    <style>
        .button {
            background-color: blueviolet;
            width: 200px;
            border: none;
            font-size: 2rem;
            padding: 0.5rem;
            border-radius: 5px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <button id="click">Click me</button>

    <script>
        const buttonEl = document.getElementById('click')
        // 先给按钮设置一个样式
        buttonEl.setAttribute('class','button')
        // 给按钮添加监听事件
        buttonEl.addEventListener('click', addFunction)
        // 定义事件响应的内容方法
        function addFunction(){
            // 反复点击按钮在自定义样式和默认样式之间切换
            buttonEl.classList.toggle('button')
        }
    </script>
</body>
</html>

image

D、如何替换CSS类:Element.classList.toggle(oldcss类,newcss类)

使用newcss类样式替换掉oldcss类样式;

案例:按钮之前未紫色,点击之后为绿色;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 定义样式 -->
    <style>
        .button {
            background-color: blueviolet;
            width: 200px;
            border: none;
            font-size: 2rem;
            padding: 0.5rem;
            border-radius: 5px;
            cursor: pointer;
        }
        .button1 {
            background-color: rgb(43, 226, 195);
            width: 200px;
            border: none;
            font-size: 2rem;
            padding: 0.5rem;
            border-radius: 5px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <button id="click">Click me</button>

    <script>
        const buttonEl = document.getElementById('click')
        // 先给按钮设置一个样式
        buttonEl.setAttribute('class','button')
        // 给按钮添加监听事件
        buttonEl.addEventListener('click', addFunction)
        // 定义事件响应的内容方法
        function addFunction(){
            // 点击之后用另一个样式进行替换
            buttonEl.classList.replace('button','button1')
        }
    </script>
</body>
</html>

image

8、补充:事件监听

  • Element.addEventListener(eventType,事件处理逻辑(函数),事件捕获还是事件冒泡)
    • 参数一eventType:事件的类别,比如“点击”等;–必填
    • 参数二:事件处理逻辑(函数);–必填
    • 参数三:布尔值,表示是使用事件捕获还是事件冒泡;–非必填;

更多JavaScript事件请点击这里