Web APIs-02基础

    科技2025-04-05  14

    Web APIs-02:排他操作,自定义属性 ,节点操作

    1.1. 排他操作

    1.1.1 排他思想

    如果有同一组元素,我们想要某一个元素实现某种样式, 需要用到循环的排他思想算法:

    所有元素全部清除样式(干掉其他人)给当前元素设置样式 (留下我自己)注意顺序不能颠倒,首先干掉其他人,再设置自己 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <button>按钮1</button> <button>按钮2</button> <button>按钮3</button> <button>按钮4</button> <button>按钮5</button> <script> // 思路: // 1.获取所有元素 // 2.变历所有元素、为所以元素设置 点击事件处理程序 // 3.排他思想(核心): // 如果有同一组元素,我们想要某一个元素实现某种样式,需要用到循环的排他思想算法: // 1.所以元素全部清除样式(干掉所以人,包括自己)2.给自己设置样式(复活自己) // 注意:顺序不能颠倒 // 1. 获取所有按钮元素 var btns = document.getElementsByTagName('button'); console.log(btns); // [button, button, button, button, button] // btns得到的是伪数组 里面的每一个元素 btns[i] for (var i = 0; i < btns.length; i++) { btns[i].onclick = function() { // (1) 我们先把所有的按钮背景颜色去掉 干掉所有人 for (var j = 0; j < btns.length; j++) { btns[j].style.backgroundColor = ''; } // (2) 然后才让当前的元素背景颜色为pink 留下我自己 this.style.backgroundColor = 'pink'; } } //2. 首先先排除其他人,然后才设置自己的样式 这种排除其他人的思想我们成为排他思想 </script> </body> </html>

    1.2 案例:百度换肤

    案例分析:

    这个案例练习的是给一组元素注册事件给4个小图片利用循环注册点击事件当我们点击了这个图片,让我们页面背景改为当前的图片核心算法:把当前图片的src路径取过来,给body做为背景即可 <!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> * { margin: 0; padding: 0; background-repeat: no-repeat; } body{ transition: all 1s; } .header { padding: 10px; background: rgba(0, 0, 0, 0.5); overflow: hidden; padding-left: 150px; } .header img { float: left; width: 250px; margin-right: 10px; cursor: pointer; transition: all .5s; } .active{ border-radius: 10px; transform: scale(1.1); } </style> </head> <body> <div class="header"> <img src="./images/bg1.jfif" alt=""> <img src="./images/bg2.jfif" alt=""> <img src="./images/bg3.jfif" alt=""> <img src="./images/bg4.jfif" alt=""> </div> <img src="" alt=""> <script> document.body.style.backgroundImage = `url(./images/bg1.jfif)` var imgs = document.querySelectorAll('.header img') for (var i = 0; i < imgs.length; i++) { // console.log(imgs[i]); imgs[i].onclick = function () { document.body.style.backgroundImage = `url(${this.src})` reset() this.className='active' } } function reset() { for (var i = 0; i < imgs.length; i++) { imgs[i].className='' } } </script> </body> </html>

    1.3 案例:表格隔行变色

    案例分析:

    用到新的鼠标事件:鼠标经过onmouseover、鼠标离开 onmouseout核心思路:鼠标经过tr行,当前的行变背景颜色,鼠标离开去掉当前的背景颜色注意:第一行(thead里面的行)不需要变换颜色,因此我们获取的是tbody里面的行 <!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> *{ margin: 0; padding: 0; } table{ width: 80%; margin:50px auto; text-align: center; border: 1px solid #aaaa; border-collapse: collapse; } th,td{ border: 1px solid #aaaa; padding: 15px; } .odd{ background-color: cyan; } .even{ background-color: rgb(250, 160, 235); } thead{ background-color: rgb(98, 127, 224); } </style> </head> <body> <table> <thead> <tr> <th>编号</th> <th>姓名</th> <th>出生年月</th> <th>性别</th> </tr> </thead> <tbody> <tr> <td>001</td> <td>詹姆斯</td> <td>199988</td> <td></td> </tr> <tr> <td>002</td> <td>詹姆斯</td> <td>199988</td> <td></td> </tr> <tr> <td>003</td> <td>詹姆斯</td> <td>199988</td> <td></td> </tr> <tr> <td>004</td> <td>詹姆斯</td> <td>199988</td> <td></td> </tr> <tr> <td>005</td> <td>詹姆斯</td> <td>199988</td> <td></td> </tr> <tr> <td>006</td> <td>詹姆斯</td> <td>199988</td> <td></td> </tr> <tr> <td>007</td> <td>詹姆斯</td> <td>199988</td> <td></td> </tr> <tr> <td>008</td> <td>詹姆斯</td> <td>199988</td> <td></td> </tr> </tbody> </table> <script> var trs=document.querySelectorAll('tbody tr') for(var i=0;i<trs.length;i++){ // console.log(trs[i]) if(i%2==0){ // trs[i].style.backgroundColor='#458' trs[i].className='odd' }else{ // trs[i].style.backgroundColor='#ccc' trs[i].className='even' } } </script> </body> </html>

    1.4 自定义属性操作

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="demo" index="1" class="nav"></div> <script> var div = document.querySelector('div'); // 1. 获取元素的属性值 // (1) element.属性 console.log(div.id); //(2) element.getAttribute('属性') get得到获取 attribute 属性的意思 我们程序员自己添加的属性我们称为自定义属性 index console.log(div.getAttribute('id')); console.log(div.getAttribute('index')); // 2. 设置元素属性值 // (1) element.属性= '值' div.id = 'test'; div.className = 'navs'; // (2) element.setAttribute('属性', '值'); 主要针对于自定义属性 div.setAttribute('index', 2); div.setAttribute('class', 'footer'); // class 特殊 这里面写的就是class 不是className // 3 移除属性 removeAttribute(属性) div.removeAttribute('index'); </script> </body> </html>

    1.4.1 获取属性值

    element.属性 获取属性值element.getAttribute('属性')

    区别:

    element.属性 获取内置属性值 (元素本身自带的属性)element.getAttribute('属性'); 主要获取自定义的属性 (标准) 我们程序员自定义的属性 <div id="demo" index="1" class="nav"></div> <script> var div = document.querySelector('div'); // 1. 获取元素的属性值 // (1) element.属性 console.log(div.id); //(2) element.getAttribute('属性') get得到获取 attribute 属性的意思 我们程序员自己添加的属性我们称为自定义属性 index console.log(div.getAttribute('id')); console.log(div.getAttribute('index')); </script> 12345678910

    1.4.2设置属性值

    设置属性值

    element.属性 = '值' 设置内置属性值element.setAttribute('属性','值')

    区别:

    element.属性 设置内置属性值element.setAttribute('属性'); 主要设置自定义的属性 (标准) // 2. 设置元素属性值 // (1) element.属性= '值' div.id = 'test'; div.className = 'navs'; // (2) element.setAttribute('属性', '值'); 主要针对于自定义属性 div.setAttribute('index', 2); div.setAttribute('class', 'footer'); // class 特殊 这里面写的就是 1234567

    1.4.3 移出属性

    element.removeAttribute('属性') // class 不是className // 3 移除属性 removeAttribute(属性) div.removeAttribute('index'); 123

    1.4.4 案例:tab栏

    案例分析:

    Tab栏切换有2个大的模块上的模块选项卡,点击某一个。当前这一个底色会是红色,其余不变(排他思想)修改类名的方式下面的模块内容,会跟随上面的选项卡变化。所以下面模块变化写到点击事件里面。规律:下面的模块显示和上面的选项卡一一对应,相匹配。核心思路:给上面的tab_list里面的所有小li添加自定义属性,属性值从0开始编号。当我们点击tab_list里面的某个小li,让tab_con里面对应序号的内容显示,其余隐藏(排他思想) <!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> * { margin: 0; padding: 0; } body { background-color: #eee; } .box ul { list-style-type: none; height: 34px; line-height: 34px; border-bottom: 1px solid #e4393c; background-color: #f7f7f7; } .box { width: 1000px; background-color: #fff; margin: 50px 0 0 50px; } .box li { float: left; /* border: 1px solid rosybrown; */ padding: 0 15px; color: #333; cursor: pointer; } li:hover { color: #e1251b; } .content { width: 100%; height: 200px; border: 1px solid #000; display: none; } .active { background-color: #e4393c; color: #fff !important; } </style> </head> <body> <div class="box"> <ul> <li index="commodity">商品介绍</li> <li index="specs">规格与包装</li> <li index="aftersale">售后保障</li> <li index="evaluate">商品评价(2.2+)</li> <li index="community">手机社区</li> </ul> <div style="display: block;" id="commodity" class="content">商品介绍</div> <div id="specs" class="content">规格与包装</div> <div id="aftersale" class="content">售后保障</div> <div id="evaluate" class="content">商品评价</div> <div id="community" class="content">手机社区</div> </div> <script> var lis = document.querySelectorAll('li') var cs = document.querySelectorAll('.content') for (var i = 0; i < lis.length; i++) { lis[i].onclick = function () { res() this.className = 'active' f1() var index = this.getAttribute('index') document.querySelector(`#${index}`).style.display = 'block' } } function res() { for (var i = 0; i < lis.length; i++) { lis[i].className = '' } } function f1() { for (var i = 0; i < cs.length; i++) { cs[i].style.display = 'none' } } </script> </body> </html>

    1.5.5. H5自定义属性

    自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。

    自定义属性获取是通过getAttribute(‘属性’) 获取。

    但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。

    H5给我们新增了自定义属性:

    1. 设置H5自定义属性

    H5规定自定义属性data-开头做为属性名并且赋值

    比如:<div data-index="1"></div>或者使用 element.setAttribute('data-index',2)

    2. 获取H5自定义属性

    兼容性获取:element.getAttribute('data-index')H5新增:element.dataset.index 或者 element.dataset['index'] ie11 才开始支持 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div getTime="20" data-index="2" data-list-name="andy"></div> <script> var div = document.querySelector('div'); // console.log(div.getTime); console.log(div.getAttribute('getTime')); // 20 div.setAttribute('data-time', 20); console.log(div.getAttribute('data-index')); // 2 console.log(div.getAttribute('data-list-name')); // andy // h5新增的获取自定义属性的方法 它只能获取data-开头的 // dataset 是一个集合里面存放了所有以data开头的自定义属性 console.log(div.dataset); // {index: "2", listName: "andy", time: "20"} console.log(div.dataset.index); // 2 console.log(div.dataset['index']); // 2 // 如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法 console.log(div.dataset.listName); // andy console.log(div.dataset['listName']); // andy </script> </body> </html>

    1.6. 节点操作

    1.6.1. 节点概述

    网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。

    HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。

    一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。

    元素节点:nodeType 为 1属性节点:nodeType 为 2文本节点:nodeType 为 3 (文本节点包含文字、空格、换行等) 我们在实际开发中,节点操作主要操作的是元素节点

    1.6.2. 节点层级

    利用 DOM 树可以把节点划分为不同的层级关系,常见的是父子兄层级关系。

    1.6.3. 父级节点

    node.parentNode

    parentNode 属性可返回某节点的父节点,注意是:最近的一个父节点如果指定的节点没有父节点则返回 null <div class="demo"> <div class="box"> <span class="erweima">×</span> </div> </div> <script> // 1. 父节点 parentNode var erweima = document.querySelector('.erweima'); // var box = document.querySelector('.box'); // 得到的是离元素最近的父级节点(亲爸爸) 如果找不到父节点就返回为 null console.log(erweima.parentNode); </script>

    1.6.4. 子节点

    所有子节点

    parentNode.childNodes (标准)

    parentNode.childNodes 返回包含指定节点的子节点的集合,该集合为即时更新的集合。

    注意:返回值里面包含了所有的子节点,包括:元素节点、文本节点等。

    如果只想要获得里面的元素节点,则需要专门处理。所以我们一般不提倡使用childNodes

    子元素节点

    parentNode.children (非标准)

    parentNode.children 只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回(重点)

    虽然children是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用

    <ul> <li>我是li标签</li> <li>我是li标签</li> <li>我是li标签</li> <li>我是li标签</li> </ul> <script> // DOM 提供的方法(API)获取 var ul = document.querySelector('ul'); var lis = ul.querySelectorAll('li'); // 1. 子节点 childNodes 所有的子节点 包含 元素节点 文本节点等等 console.log(ul.childNodes); console.log(ul.childNodes[0].nodeType); console.log(ul.childNodes[1].nodeType); // 2. children 获取所有的子元素节点 也是我们实际开发常用的 console.log(ul.children); </script>

    第1个子节点

    parentNode.firstChild

    firstChild返回第一个子节点,找不到则返回null。同样,也是包含所有的节点。

    最后1个子节点

    parentNode.lastChild

    lastChild 返回最后一个子节点,找不到则返回null。同样,也是包含所有的节点。

    第1个子元素节点

    parentNode.firstElementChild

    firstElementChild 返回第一个子元素节点,找不到则返回null。

    最后1个子元素节点

    parentNode.lastElementChild

    lastElementChild 返回最后一个子元素节点,找不到则返回null。

    注意:这两个方法有兼容性问题, IE9 以上才支持。

    实际开发中,firstChild和lastChild 包含其他节点,操作不方便,而firstElementChild 和 lastElementChild又有兼容性问题

    解决方案:

    如果想要第一个子元素节点,可以使用:parentNode.children[0]如果想要最后一个子元素节点,可以使用:parentNode.children[parentNode.children.length-1] <ol> <li>我是li1</li> <li>我是li2</li> <li>我是li3</li> <li>我是li4</li> <li>我是li5</li> </ol> <script> var ol = document.querySelector('ol'); // 1. firstChild 第一个子节点 不管是文本节点还是元素节点 console.log(ol.firstChild); console.log(ol.lastChild); // 2. firstElementChild 返回第一个子元素节点 ie9才支持 console.log(ol.firstElementChild); console.log(ol.lastElementChild); // 3. 实际开发的写法 既没有兼容性问题又返回第一个子元素 console.log(ol.children[0]); console.log(ol.children[ol.children.length - 1]); </script>

    1.6.6. 兄弟节点

    下一个兄弟节点

    node.nextSibling

    nextSibling 返回当前元素的下一个兄弟节点,找不到则返回null

    上一个兄弟节点

    node.previousSibling

    previousSibling 返回当前元素上一个兄弟节点,找不到则返回null

    <div>我是div</div> <span>我是span</span> <script> var div = document.querySelector('div'); // 1.nextSibling 下一个兄弟节点 包含元素节点或者 文本节点等等 console.log(div.nextSibling); console.log(div.previousSibling); // 2. nextElementSibling 得到下一个兄弟元素节点 console.log(div.nextElementSibling); console.log(div.previousElementSibling); </script>

    下一个兄弟元素节点(有兼容性问题)

    node.nextElementSibling

    nextElementSibling 返回当前元素下一个兄弟元素节点,找不到则返回null

    上一个兄弟元素节点(有兼容性问题)

    node.previousElementSibling

    previousElementSibling 返回当前元素上一个兄弟节点,找不到则返回null

    注意:nextElementSibling 和 previousElementSibling 有兼容性问题, IE9 以上才支持

    如何解决兼容性问题: 自己封装一个兼容性的函数

    function getNextElementSibling(element) { var el = element; while (el = el.nextSibling) { if (el.nodeType === 1) { return el; } } return null; }

    1.6.7. 创建节点

    document.createElement('tagName') document.createElement()` 方法创建由 tagName 指定的 HTML 元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为`动态创建元素节点

    1.6.8. 添加节点

    node.appendChild(child)

    node.appendChild() 方法将一个节点添加到指定父节点的子节点列表末尾。类似于 CSS 里面的 after 伪元素

    node.insertBefore(child,指定元素)

    node.insertBefore() 方法将一个节点添加到父节点的指定子节点前面。类似于 CSS 里面的 before 伪元素

    <ul> <li>123</li> </ul> <script> // 1. 创建节点元素节点 var li = document.createElement('li'); // 2. 添加节点 node.appendChild(child) node 父级 child 是子级 后面追加元素 var ul = document.querySelector('ul'); ul.appendChild(li); // 3. 添加节点 node.insertBefore(child, 指定元素); var lili = document.createElement('li'); ul.insertBefore(lili, ul.children[0]); // 4. 我们想要页面添加一个新的元素 : 1. 创建元素 2. 添加元素 </script>
    Processed: 0.010, SQL: 8