Web APIs

一、学习目标:

  • 能够说出Web APIs阶段与JavaScri语法阶段的关联性

  • 能够说出什么是API

  • 能够说出什么是Web API

二、Web APIs与JavaScri的关联性

JS基础学习ECMAScript基础语法为后面做铺垫,WebAPIs是JS的应用,大量使用JS基础语法做交互效果。

    • API

API(应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

简单理解:API是给程序员提供的一种工具,以便能更轻松的实现想要完成的功能。

WebAPI是浏览器提供的一套操作浏览器功能和页面元素的API(BOM和DOM),我们会使用就可以了,不必纠结内部如何实现的。

2.DOM简介

2.1什么是DOM

文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口

W3C 已经定义了一系列的 DOM 接口,通过这些 DOM 接口可以改变网页的内容、结构和样式。

  • 文档:一个页面就是一个文档,DOM中使用doucument来表示

  • 元素:页面中的所有标签都是元素,DOM中使用 element 表示

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

DOM 把以上内容都看做是对象

3.获取元素

3.1如何获取页面元素

DOM在我们实际开发中主要用来操作元素。

我们如何来获取页面中的元素呢?

获取页面中的元素可以使用以下几种方式:

  • 根据 ID 获取

  • 根据标签名获取

  • 通过 HTML5 新增的方法获取

  • 特殊元素获取

3.1.1根据ID获取

使用 getElementByld() 方法可以获取带ID的元素对象

doucument.getElementByld('id名')

使用 console.dir() 可以打印我们获取的元素对象,更好的查看对象里面的属性和方法。

示例

<div id="time">2019-9-9</div>
<script>
    // 1.因为我们文档页面从上往下加载,所以得先有标签,所以script写在标签下面
    // 2.get 获得 element 元素 by 通过 驼峰命名法
    // 3.参数 id是大小写敏感的字符串
    // 4.返回的是一个元素对象
    var timer = document.getElementById('time');
    console.log(timer);
    // 5. console.dir 打印我们的元素对象,更好的查看里面的属性和方法
    console.dir(timer);
</script>

3.1.2根据标签名获取

根据标签名获取,使用 getElementByTagName() 方法可以返回带有指定标签名的对象的集合

doucument.getElementsByTagName('标签名');
  • 因为得到的是一个对象的集合,所以我们想要操作里面的元素就需要遍历

  • 得到元素对象是动态的

  • 返回的是获取过来元素对象的集合,以伪数组的形式存储

  • 如果获取不到元素,则返回为空的伪数组(因为获取不到对象)

<ul>
    <li>知否知否,应是等你好久</li>
    <li>知否知否,应是等你好久</li>
    <li>知否知否,应是等你好久</li>
    <li>知否知否,应是等你好久</li>
    <li>知否知否,应是等你好久</li>
</ul>
<script>
    // 1.返回的是获取过来元素对象的集合 以伪数组的形式存储
    var lis = document.getElementsByTagName('li');
    console.log(lis);
    console.log(lis[0]);
    // 2.依次打印,遍历
    for (var i = 0; i < lis.length; i++) {
        console.log(lis[i]);
    }
    // 3.如果页面中只有 1 个 li,返回的还是伪数组的形式
    // 4.如果页面中没有这个元素,返回的是空伪数组
</script>

还可以根据标签名获取某个元素(父元素)内部所有指定标签名的子元素,获取的时候不包括父元素自己

<script>
    //element.getElementsByTagName('标签名'); 父元素必须是指定的单个元素
    var ol = document.getElementById('ol');
    console.log(ol.getElementsByTagName('li'));
</script>

3.1.3、通过H5新增方法获取

①getElementsByClassName
  • document.getElementsByClassName('类名')

document.getElementsByClassName('类名'); 
②document.querySelector

根据指定选择器返回第一个元素对象

该方法接受一个css选择器作为参数,返回匹配该选择器的元素节点。如果有多个节点满足匹配条件,则返回第一个匹配的节点。

document.querySelector('选择器');
document.querySelector('标签');

// 切记里面的选择器需要加符号 
// 类选择器.box 
// id选择器 #nav
var firstBox = document.querySelector('.box');
③document.querySelectorAll

根据指定选择器返回所有元素对象

该方法与queryselector()用法类似,区别是返回一个NodeList对象,包含所以匹配给定选择器的节点

document.querySelectorAll('选择器');

注意:

querySelectorquerySelectorAll 里面的选择器需要加符号,比如: document.querySelector('#nav');

④例子
<script>
    // 1. getElementsByClassName 根据类名获得某些元素集合
    var boxs = document.getElementsByClassName('box');
    console.log(boxs);
    // 2. querySelector 返回指定选择器的第一个元素对象  切记 里面的选择器需要加符号 .box  #nav
    var firstBox = document.querySelector('.box');
    console.log(firstBox);
    var nav = document.querySelector('#nav');
    console.log(nav);
    var li = document.querySelector('li');
    console.log(li);
    // 3. querySelectorAll()返回指定选择器的所有元素对象集合
    var allBox = document.querySelectorAll('.box');
    console.log(allBox);
    var lis = document.querySelectorAll('li');
    console.log(lis);
</script>

3.2、获取特殊元素

①获取body元素

返回body元素对象

document.body;

②获取html元素

返回html元素对象

document.documentElement;

4、事件基础

4.1、事件概述

JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为。

简单理解: 触发— 响应机制。

网页中的每个元素都可以产生某些可以触发 JavaScript 的事件,例如,我们可以在用户点击某按钮时产生一个事件,然后去执行某些操作。

4.2、事件三要素

  1. 事件源(谁:事件被触发的对象)

  1. 事件类型(什么事件:鼠标点击、鼠标经过、键盘按下)

  1. 事件处理程序(做啥:通过一个函数赋值的方式完成)

<script>
    // 点击一个按钮,弹出对话框
    // 1. 事件是有三部分组成  事件源  事件类型  事件处理程序   我们也称为事件三要素
    //(1) 事件源 事件被触发的对象   谁  按钮
    var btn = document.getElementById('btn');
    //(2) 事件类型  如何触发 什么事件 比如鼠标点击(onclick) 还是鼠标经过 还是键盘按下
    //(3) 事件处理程序  通过一个函数赋值的方式 完成
    btn.onclick = function() {
        alert('点秋香');
    }
</script>

4.3、执行事件的步骤

  1. 获取事件源

  1. 注册事件(绑定事件)

  1. 添加事件处理程序(采取函数赋值形式)

<script>
    // 执行事件步骤
    // 点击div 控制台输出 我被选中了
    // 1. 获取事件源
    var div = document.querySelector('div');
    // 2.绑定事件 注册事件
    // div.onclick 
    // 3.添加事件处理程序 
    div.onclick = function() {
        console.log('我被选中了');
    }
</script>

4.4鼠标事件

5、操作元素

JavaScript 的 DOM 操作可以改变网页内容、结构和样式,我们可以利用 DOM 操作元素来改变元素里面的内容 、属性等。注意以下都是属性

5.1改变元素内容

  • element.innerText

  • element.innerHTML

从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉。

element.innerText

起始位置到终止位置的全部内容,包括HTML标签,同时保留空格和换行

element.innerHTML
//当我们点击按钮,div里面的文字会发生变化
//1、获取元素
var btn=document.querySelector('button')
var div=document.querySelector('div')
//2注册事件
btn.onclick=function(){
div.innnerText='2023年的1月18号'
}
//我们元素可以不用添加事件
var p=document.querySelector('p')
p.innerText=getDate();

innerText和innerHTML的区别:

<body>
    <div></div>
    <p>
        我是文字
        <span>123</span>
    </p>

    <script>
        // innerText 和 innerHTML的区别 
        // 1. innerText 不识别html标签,去除空格和换行
        var div = document.querySelector('div');
        div.innerText = '<strong>今天是:</strong> 2019';
        // 2. innerHTML 识别html标签 保留空格和换行的
        div.innerHTML = '<strong>今天是:</strong> 2019';
        // 这两个属性是可读写的  可以获取元素里面的内容
        var p = document.querySelector('p');
        console.log(p.innerText);//输出内容会去掉空格和换行,内容在一行上
        console.log(p.innerHTML);//保留空格和换行
    </script>
</body>

5.2、改变元素属性

  • innerText、innerHTML改变元素内容

  • src、href

  • id、alt、title

// img.属性
img.src = "xxx";
img.title='xxx'
input.value = "xxx";
input.type = "xxx";
input.checked = "xxx";
input.selected = true / false;
input.disabled = true / false;
//点击更换图片
zxy.onclick=function(){
    img.src='images/zxy.jpg'
}

5.3、表单元素的属性操作

利用DOM可以操作如下表单元素的属性:

type、value、checked、selected、disabled

案例:仿京东显示密码的案例

点击按钮(眼睛)将密码框切换为文本框,并可以查看密码明文

①核心思路:点击眼睛按钮,把密码框类型改为文本框就可以看见里面的密码

②一个按钮有两个状态,点击一次,切换为文本框,继续点击一次切换为密码框

③算法:利用一个flag变量,来判断flag的值,如果是1就切换为文本框,flag设置为0,如果是0就切换为密码框,flag设置为1

5.4样式属性操作

我们可以通过JS修改元素的大小、颜色、位置等样式。

  1. element.style 行内样式操作

  1. element.className 类名样式操作

  • 行内样式操作

// element.style
div.style.backgroundColor = 'pink';
div.style.width = '250px';
  • 类名样式操作

// element.className

☆注意:

1.JS里面的样式采取驼峰命名法比如 fontSize ,backgroundColor

2.JS 修改 style 样式操作 ,产生的是行内样式,CSS权重比较高

3.如果样式修改较多,可以采取操作类名方式更改元素样式

4.class 因为是个保留字,因此使用className来操作元素类名属性

  1. className 会直接更改元素的类名,会覆盖原先的类名

5.4.1element.style

案例:点击显示图片/点击隐藏

①核心思路:利用样式的显示和隐藏,display:none隐藏元素display:block显示元素

②点击按钮,就让这个二维码盒子隐藏起来即可

案例:循环精灵图背景
  1. 首先精灵图图片排列有规律的

  1. 核心思路:利用for循环,修改精灵图片的背景位置background-position

  1. 剩下的就是考验你的数学功底了

  1. 让循环里面的i索引号*44就是每个图片的y坐标

案例:显示隐藏文本框内容
  1. 首先表单需要2个新事件,获得焦点onfocus 失去焦点onblur

  1. 如果获得焦点,判断表单里面内容是否为默认文字,如果是默认文字,就清空表单内容

3.如果失去焦点,判断表单内容是否为空,如果为空,则表单内容改为默认文字

5.4.2.element.className

1使用element.style获得修改元素样式,如果样式比较少或者功能简单的情况下使用

.change{
    background-color;red;
    color;red;
    font-size;25px
}
test.onclick=function(){
//让我们当前元素的类名改为change
this.className= 'change'
}

2.我们可以通过修改元素的className更改元素的样式,适合于样式较多或者功能复杂的情况

3.class是个保留字,因此使用className来操作元素类名属性

4.className会直接更改元素的类名,会覆盖原来的类名

如果想要保留原先的类名,我们可以这么做:多类名选择器

this.className='first change';

案例:密码提示错误信息
  1. 首先判断的事件是表单失去焦点onblur

  1. 如果输入正确则提示正确的信息为绿色小图标变化

  1. 如果输入不是6-16位,则提示错误信息颜色为红色小图标变化

  1. 因为里面变化样式较多,我们采取classNam修改样式

5.5总结

5.6排他思想

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

  1. 所有元素全部清除样式(干掉其他人)

  1. 给当前元素设置样式 (留下我自己)

  1. 注意顺序不能颠倒,首先干掉其他人,再设置自己

<body>
    <button>按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>
    <script>
        // 1. 获取所有按钮元素
        var btns = document.getElementsByTagName('button');
        // btns得到的是伪数组  里面的每一个元素 btns[i]
        for (var i = 0; i < btns.length; i++) {
            btns[i].onclick = function() {
                // (1) 我们先把所有的按钮背景颜色去掉  干掉所有人
                for (var i = 0; i < btns.length; i++) {
                    btns[i].style.backgroundColor = '';
                }
                // (2) 然后才让当前的元素背景颜色为pink 留下我自己
                this.style.backgroundColor = 'pink';

            }
        }
        //2. 首先先排除其他人,然后才设置自己的样式 这种排除其他人的思想我们成为排他思想
    </script>
</body>

5.6.1案例:多个按钮换背景

  1. 这个案例练习的是给一组元素注册事件

  1. 给4个小图片利用循环注册点击事件

  1. 当我们点击了这个图片,让我们页面背景改为当前图片

  1. 核心算法:把当前的src路径取过来,给body作为背景即可

5.6.2案例:表格隔行变色

1.用到新的鼠标事件 鼠标经过onmouseover 鼠标离开onmouseout

2.核心思路:鼠标经过tr行,当前的行变背景颜色,鼠标离开去掉当前的背景颜色

3.注意:第一行(thead里面的行)不需要变换颜色,因此我们获取的是tbody里面的行

5.6.2案例:表单全选取消全选案例

案例分析:

  1. 全选和取消全选的做法:让下面所有复选框的checked属性(选中状态)跟随全选按钮即可

  1. 下面复选框需要全部选中,上面全选才能选中做法:给下面所有复选框绑定点击事件,每次点击都要循环查看下面的复选框是否有没选中的,如果有一个没选中,上面全选就不选中。

  1. 可以设置一个变量,来控制全选是否选中

5.7、自定义属性

5.7.1获取属性值

  • 获取内置属性值(元素本身自带的属性)

element.属性;
  • 获取自定义的属性

get得到获取的意思;attribute属性的意思

element.getAttribute('属性');

区别:element.属性:获取内置属性值(元素本身自带属性)

element.getAttribute(‘属性’):主要获得自定义的属性(标准)我们程序员自定义的属性

5.7.2设置属性值

(1)element.属性=‘值’ 设置内置属性值

element.属性 = '值';

(2)element.setAttribute('属性',‘值’)

element.setAttribute('属性','值');

区别:element.属性:获取内置属性值(元素本身自带属性)

element.getAttribute(‘属性’):主要获得自定义的属性(标准)我们程序员自定义的属性

5.7.3、移除属性

移除属性:element.removeAttribute('属性');

element.removeAttribute('属性');
<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>

案例:tab栏切换(重点案例)

当鼠标点击上面相应的选项卡(tab),下面内容跟随变化

案例分析:

①Tab栏切换有2个大的模块

②上的模块选项卡,点击某一个。当前这一个底色会是红色,其余不变(排他思想)修改类名的方式

③下面的模块内容,会跟随上面的选项卡变化。所以下面模块变化写到点击事件里面。

④规律:下面的模块显示内容和上面的选项卡一一对应,相匹配。

⑤核心思路:给上面的tab_list里面的所以小li添加自定义属性,属性值从0开始编号

⑥当我们点击tab_list里面的某个小li,让tab_con里面的对应序号的内容显示,其余隐藏(排他思想)

5.8 H5自定义属性

自定义属性目的:

  • 保存并保存数据,有些数据可以保存到页面中而不用保存到数据库中

  • 有些自定义属性很容易引起歧义,不容易判断到底是内置属性还是自定义的,所以H5有了规定

5.8.1设置H5自定义属性

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

比如:

<div data-index="1"></div>

或者使用JS设置

element.setAttribute('data-index',2)

<div data-index = "1"></>
// 或者使用JavaScript设置
div.setAttribute('data-index',20);

5.8.2 获取H5自定义属性

  • 兼容性获取 :element.getAttribute('data-index')

  • H5新增的:element.dataset.indexelement.dataset['index'] IE11才开始支持

<body>
    <div getTime="20" data-index="2" data-list-name="andy"></div>
    <script>
        var div = document.querySelector('div');
        console.log(div.getAttribute('getTime'));
        div.setAttribute('data-time', 20);
        console.log(div.getAttribute('data-index'));
        console.log(div.getAttribute('data-list-name'));
        // h5新增的获取自定义属性的方法 它只能获取data-开头的
        // dataset 是一个集合里面存放了所有以data开头的自定义属性
        console.log(div.dataset);
        console.log(div.dataset.index);
        console.log(div.dataset['index']);
        // 如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法
        console.log(div.dataset.listName);
        console.log(div.dataset['listName']);
    </script>
</body>

①dataset 是一个集合里面存放了所有以data开头的自定义属性

②获取用:div.dataset.indexdiv.dataset['index']

☆尽量使用element.getAttribute('data-index')

③如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法

data-list-name:div.dataset.listNamediv.dataset['listName']IE11才开始支持

5.9、节点操作

5.9.1为什么学节点操作

获取元素通常使用两种方式:

  1. 利用DOM提供的方法获取元素

  • document.getElementById( )

  • document.getElementByTagName()

  • document.querySelector等

  1. 利用节点的层次关系获取元素

  • 利用父子兄节点关系获取元素

  • 逻辑性强,但是兼容性差

5.9.2节点概述

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

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

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

  • 元素节点:nodeType 为1

  • 属性节点:nodeType 为2

  • 文本节点:nodeType 为3(文本节点包括文字、空格、换行等)

我们在实际开发中,节点操作主要操作的是元素节点

5.9.3节点层次

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

1.父级节点
node.parentNode
  • parentNode属性可以返回某节点的父结点,注意是最近的一个父结点

  • 如果指定的节点没有父结点则返回null

<body>
    <!-- 节点的优点 -->
    <div>我是div</div>
    <span>我是span</span>
    <ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ul>
    <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>
</body>
2.子节点
parentNode.childNodes(标准)
  • parentNode.childNodes 返回包含指定节点的子节点的集合,该集合为即时更新的集合

  • 返回值包含了所有的子结点,包括元素节点,文本节点等

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

parentNode.children(非标准)
  • parentNode.children 是一个只读属性,返回所有的子元素节点

  • 它只返回子元素节点,其余节点不返回 (这个是我们重点掌握的

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

<body>
    <ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ul>
    <ol>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ol>
    <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>
</body>
3.第一个子结点
parentNode.firstChild
  • firstChild 返回第一个子节点,找不到则返回null

  • 同样,也是包含所有的节点

firstElementChild

firstElementChild:返回第一个子元素节点,找不到则返回null(兼容性)

4.最后一个子结点
parentNode.lastChild
  • lastChild 返回最后一个子节点,找不到则返回null

  • 同样,也是包含所有的节点

lastElementChild

lastElementChild:返回第最后一个子元素节点,找不到则返回null(兼容性

<body>
    <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>
</body>

注意:firstElementChild、lastElementChild有兼容性问题,IE9以上才支持

3.1和4.1兼容性解决方案

实际开发中,firstChild 和 lastChild 包含其他节点,操作不方便,而 firstElementChild 和 lastElementChild 又有兼容性问题,那么我们如何获取第一个子元素节点或最后一个子元素节点呢?

  • 如果想要第一个子元素节点,可以使用 parentNode.chilren[0]

  • 如果想要最后一个子元素节点,可以使用

//输出第一个元素
parentNode.chilren[0]
//输出最后一个元素
// 数组元素个数减1 就是最后一个元素的索引号
parentNode.chilren[parentNode.chilren.length - 1]

例子:

<body>
    <ol>
        <li>我是li1</li>
        <li>我是li2</li>
        <li>我是li3</li>
        <li>我是li4</li>
    </ol>
    <script>
        var ol = document.querySelector('ol');
        // 1.firstChild 获取第一个子结点的,包含文本结点和元素结点
        console.log(ol.firstChild);
        // 返回的是文本结点 #text(第一个换行结点)
        
        console.log(ol.lastChild);
        // 返回的是文本结点 #text(最后一个换行结点)
        // 2. firstElementChild 返回第一个子元素结点
        console.log(ol.firstElementChild);
        // <li>我是li1</li>
        
        // 第2个方法有兼容性问题,需要IE9以上才支持
        // 3.实际开发中,既没有兼容性问题,又返回第一个子元素
        console.log(ol.children[0]);
        // <li>我是li1</li>
        console.log(ol.children[3]);
        // <li>我是li4</li>
        // 当里面li个数不唯一时候,需要取到最后一个结点时这么写
        console.log(ol.children[ol.children.length - 1]);
    </script>
</body>
案例:下拉菜单

①导航栏里面的li都要有鼠标经过效果,所以需要循环注册鼠标事件

②核心原理:当鼠标经过li里面的第二个孩子ui显示,当鼠标离开,则ul隐藏

5.9.4、兄弟节点

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

  • 同样,也是包含所有的节点

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

  • 同样,也是包含所有的节点

5.3、下一个兄弟节点(兼容性)
node.nextElementSibling
  • nextElementSibling 返回当前元素下一个兄弟元素节点,找不到则返回null

  • 有兼容性问题,IE9才支持

5.4、上一个兄弟节点(兼容性)
node.previousElementSibling
  • previousElementSibling 返回当前元素上一个兄弟元素节点,找不到则返回null

  • 有兼容性问题,IE9才支持

总结:

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

问:如何解决兼容性问题?

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

5.9.5创建/添加节点

1.创建节点
document.createElement('tagName');
  • document.createElement() 方法创建由 tagName 指定的HTML 元素

  • 因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点

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

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

示例:

<body>
    <ul>
        <li>123</li>
    </ul>
    <script>
        // 1. 创建节点元素节点
        var li = document.createElement('li');
        // 2. 添加节点 node.appendChild(child)  node 父级  child 是子级 后面追加元素  类似于数组中的push
        // 先获取父亲ul
        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>
</body>
案例:简单版发布留言案例

案例分析:

①核心思路:点击按钮之后,就动态创建一个li,添加到ul里面。

②创建li的同时,把文本域里面的值通过li.innerHTML赋值给li

③如果想要新的留言后面显示就用appendChild如果想要前面显示就用.insertBefore()

3.删除节点
node.removeChild(child)
  • node.removeChild()方法从 DOM 中删除一个子节点,返回删除的节点

案例:删除子节点
案例:删除留言案例
  1. 当我们把文本里面的值赋值给li的时候,多添加一个删除的链接

  1. 需要我们把所有的链接获取过来,当我们点击当前的连接的时候,删除当前连接所在的li

  1. 阻止链接跳转需要添加javascript:void(0);或者javascript:;<a href="javascript:;">

4.复制节点(克隆节点)
node.cloneNode()
  • node.cloneNode()方法返回调用该方法的节点的一个副本。 也称为克隆节点/拷贝节点

  • 如果括号参数为空或者为 false ,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点

  • 如果括号参数为 true ,则是深度拷贝,会复制节点本身以及里面所有的子节点

示例:

<body>
    <ul>
        <li>1111</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        // 1. node.cloneNode(); 括号为空或者里面是false 浅拷贝 只复制标签不复制里面的内容
        // 2. node.cloneNode(true); 括号为true 深拷贝 复制标签复制里面的内容
        var lili = ul.children[0].cloneNode(true);
        ul.appendChild(lili);
    </script>
</body>

6、面试题

一、案例:动态生成表格

①因为里面的学生数据都是动态的,我们需要js动态生成。这里我们模拟数据,自己定义好数据。数据我们采取对象形式存储。

②所有数据都是放在tbody里面的行里面

③因为行很多,我们需要循环创建多个行(对应多少人)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        table {
            width: 500px;
            margin: 100px auto;
            border-collapse: collapse;
            text-align: center;
        }
        
        td,
        th {
            border: 1px solid #333;
        }
        
        thead tr {
            height: 40px;
            background-color: #ccc;
        }
    </style>
</head>


<body>
    <table cellspacing="0">
        <thead>
            <tr>
                <th>姓名</th>
                <th>科目</th>
                <th>成绩</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
    <script>
        //1先去准备好学生的数据
        var datas = [{
                name: '张三',
                subject: 'java',
                score: 60
            }, {
                name: '李四',
                subject: '语文',
                score: 100
            }, {
                name: '王二',
                subject: '数学',
                score: 99
            }, {
                name: '刘五',
                subject: 'English',
                score: 54
            }]
            //2往tbody里面创建行:有几个人(通过我们数组的长度得到)我们就创建几行
        var tbody = document.querySelector('tbody');
        for (var i = 0; i < datas.length; i++) {
            //创建tr行
            var tr = document.createElement('tr')
            tbody.appendChild(tr)
                //行里面创建单元格 td 单元格的数量取决于每个对象里面的属性个数
                //for循环遍历对象  datas[i]
            for (var k in datas[i]) { //data[i]代表是第几个对象
                //创建单元格
                var td = document.createElement('td')
                    //把对象里面的属性值datas[i][k]给td
                    //consloe.log(datas[i][k])
                td.innerHTML = datas[i][k]
                tr.appendChild(td)
            }
            //3创建有删除2个字的单元格
            var td = document.createElement('td');
            td.innerHTML = '<a href="javascript:;">删除</a>'
            tr.appendChild(td);
        }
        // for(var k in obj){
        //     k得到的是属性名
        //     obj[k]得到是属性值
        // }
        var aa = document.querySelectorAll("a")
        for (var i = 0; i < aa.length; i++) {
            aa[i].onclick = function() {
                //点击a删除当前a所在的行(链接的爸爸的爸爸)node.removeChild(child)
                tbody.removeChild(this.parentNode.parentNode)
            }
        }
    </script>
</body>

</html>

二、三种动态创建元素的区别

  • doucument.write()

  • element.innerHTML

  • document.createElement()

区别:

  • document.write() 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘

  • innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘

  • innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂

<body>
    <div class="innner"></div>
    <div class="create"></div>
    <script>
        // 2. innerHTML 创建元素
        var inner = document.querySelector('.inner');
        // 2.1 innerHTML 用拼接字符串方法
        for (var i = 0; i <= 100; i++) {
            inner.innerHTML += '<a href="#">百度</a>';
        }
        // 2.2 innerHTML 用数组形式拼接
        var arr = [];
        for (var i = 0; i <= 100; i++) {
            arr.push('<a href="#">百度</a>');
        }
        inner.innerHTML = arr.join('');

        // 3.document.createElement() 创建元素
        var create = document.querySelector('.create');
        var a = document.createElement('a');
        create.appendChild(a);
    </script>
</body>

7.DOM重点核心

文档对象模型(简称DOM)。是w3c组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口。

W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容,结构和样式。

1对于javascript,为了能够是javascript操作HTML,javascript就有了一套自己的DOM编程接口

2.对于HTML,dom使得html形成一颗dom树,包含文档、元素、节点

对于DOM操作,我们主要针对子元素的操作,主要有

  • 创建

  • 属性操作

  • 时间操作

7.1创建

  1. document.write

  1. innerHTML

  1. createElement

7.2、增

  1. appendChild

  1. insertBefore

7.3、删

  1. removeChild

7.4、改

  • 主要修改dom的元素属性,dom元素的内容、属性、表单的值等

  1. 修改元素属性:src、href、title 等

  1. 修改普通元素内容:innerHTML、innerText

  1. 修改表单元素:value、type、disabled

  1. 修改元素样式:style、className

7.5、查

  • 主要获取查询dom的元素

1.DOM提供的API方法:getElementById、getElementsByTagName (古老用法,不推荐)

2.H5提供的新方法:querySelector、querySelectorAll (提倡)

3.利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling) 提倡

7.6、属性操作

  • 主要针对于自定义属性

  1. setAttribute:设置dom的属性值

  1. getAttribute:得到dom的属性值

  1. removeAttribute:移除属性

7.7事件操作

给元素注册事件,采取 事件源.事件类型=事件处理程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

再学习一点

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

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

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

打赏作者

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

抵扣说明:

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

余额充值