webAPI系列之_7分钟玩转DOM上篇

严格自律=绝对自由

玩转DOM上篇

知识导航:

  1. 何为DOM
  2. 事件基础
  3. 获取元素
  4. 操作元素
  5. 节点操作

1. 何为DOM

文档对象模型(Document Object Model,简称DOM),是 W3C 组织推荐的处理可扩展标记语言(html或者xhtml)的标准编程接口
W3C 已经定义了一系列的 DOM 接口,通过这些 DOM 接口可以改变网页的内容、结构和样式。

DOM树

webAPI系列之_7分钟玩转DOM上篇_第1张图片
DOM树 又称为文档树模型,把文档映射成树形结构通过节点对象对进行其处理。

  • 文档:一个页面就是一个文档,DOM中使用document表示
  • 节点:网页中的所有内容,在文档树中都是节点(标签、属性、文本、注释等),使用node表示
  • 标签节点:网页中的所有标签,通常称为元素节点,又简称为“元素”,使用element表示(本篇主要介绍

2. 获取元素

我们为啥子要获取元素呢?
当我们想通过js改变一个元素的形状,位置时。我们最起码得先拿到这个元素吧
下面来看获取方式

2.1 根据元素的ID属性

基本语法:

document.getElementById(元素Id);
返回值为获取的元素对象

栗子:
console.dir()能返回元素的结构

    <div id="demo01"></div>
    <script>
        var demo01 = document.getElementById("demo01");
        console.dir(demo01);
    </script>

结果:webAPI系列之_7分钟玩转DOM上篇_第2张图片

2.2 根据元素的标签名

基本语法:

//为啥是Elements呢,因为元素标签不唯一啊
document.getElementsByTagName('标签名') 
//或者 
element.getElementsByTagName('标签名') 

返回值:多个元素对象的伪数组。获取单个元素利用for循环遍历即可(数组遍历)

栗子:

    <div id="demo01"></div>
    <div class="demo01"></div>
    <div class="demo01"></div>
    <script>
        var demo02 = document.getElementsByTagName('div');
        console.dir(demo02);
    </script>

结果:
webAPI系列之_7分钟玩转DOM上篇_第3张图片

2.3 h5新增方式

  1. document.getElementsByClassName(元素类名); 参数为字符串下同
  2. document.querySelector(选择器名);
  3. document.querySelectorAll(选择器名);
    栗子:
    <ul>
        <li class="demo1"></li>
        <li class="demo1"></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
    <script>
        var demo01 = document.getElementsByClassName('demo1');
        var demo02 = document.querySelector('li');
        var demo03 = document.querySelector('.demo1');//这里的类名选择器别忘了加前面的.
        var demo04 = document.querySelectorAll('li');
        console.dir(demo01);
        console.dir(demo02);
        console.dir(demo03);
        console.dir(demo04);
    </script>

结果:
webAPI系列之_7分钟玩转DOM上篇_第4张图片

值得注意:

  1. getElementsByClassName 根据类名获得某些元素集合(伪数组方式存储)
  2. querySelector 返回指定选择器的第一个元素对象 切记 里面的选择器需要加符号 .box #nav
  3. querySelectorAll()返回指定选择器的所有元素对象集合(伪数组)

2.4 获取特殊元素

  1. document.body 获取body元素
  2. document.documentElement 获取html元素
    栗子
        var demo01 = document.body;
        var demo02 = document.documentElement;
        console.dir(demo01);
        console.dir(demo02);

结果
webAPI系列之_7分钟玩转DOM上篇_第5张图片

3. 事件基础(获取了元素总要干点事吧)

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

3.1 事件三要素

  • 事件源(谁要触发):触发事件的元素
  • 事件类型(何种事件触发): 例如 click 点击事件
  • 事件处理程序(触发之后干了些啥):事件触发后要执行的代码(函数形式),事件处理函数

栗子

<button>按钮</button>
 	<script>
 var btn = document.querySelector('button');
        btn.onclick = function() {
            alert("你点击了");
        }
    </script>

结果
webAPI系列之_7分钟玩转DOM上篇_第6张图片

3.2 执行步骤

  1. 获取事件源(上面的button)
  2. 给事件源绑定事件(上面的onclick)
  3. 添加事件处理程序(上面的弹框)

3.3 常见鼠标事件一览(先看下就行,7有详写)

webAPI系列之_7分钟玩转DOM上篇_第7张图片

4. 操作元素(重头戏来了)

4.1 改变元素内容

有两种方式(可读写。即直接赋值便改变内容,不赋值即返回原有内容):

  1. element.innerText:它会去除html标签、空格换行
  2. element.innerHTML:保留上所去除的
    栗子:
    <button>按钮</button>
    <div>我是谁</div>


    <script>
        // 获取元素
        var btn = document.querySelector("button");
        var div = document.querySelector("div");
        // 事件源  事件   处理函数
        btn.onclick = function() {
        	//亲自己切换吧
        	//div.innerText = "宫小白";
            div.innerHTML = "宫小白";
        }
    </script>

innerText结果
webAPI系列之_7分钟玩转DOM上篇_第8张图片
innerHTML结果
webAPI系列之_7分钟玩转DOM上篇_第9张图片

4.2 操作元素的属性(如src,alt,tittle属性等)

仍是可读写
借一下操作图片的栗子演示一哈:

<body>
    <button>宋茜</button>
    <button>佟丽娅</button>
    <div><img src="img/song.jpg" title="宋茜"></div>
</body>

<script>
    var btn = document.querySelectorAll("button");
    var img = document.querySelector("img");
    btn[0].onclick = function() {
        img.src = "img/song.jpg";
        img.title = "宋茜";
    }
    btn[1].onclick = function() {
        img.src = "img/tong.jpg";
        img.title = "佟丽娅";
    }
</script>

结果展示:

4.3 操作表单元素的属性

表单中的input属性如type,value,checked,selected,disabled(忘了的话看这喔链接宫小白])
请看栗子:

 <div class="box">
        <button id="btn01">是秘文变明文</button>
        <button id="btn02">改变内容</button>
        <button id="btn03">禁用下面按钮</button>
        <button id="btn04">选成女</button>

    </div>
    <div>
        <input type="password" name="" id="" class="input01">
        <input type="text" name="" id="" class="input02">
        <input type="button" value="按钮">
        <input type="radio" name="sex" value="男" checked="checked" class="input04" /><input type="radio" name="sex" value="女" class="input05" /></div>
</body>
<script>
	//来练习一下id和标签获取吧
    var btn01 = document.getElementById("btn01");
    var btn02 = document.getElementById("btn02");
    var btn03 = document.getElementById("btn03");
    var btn04 = document.getElementById("btn04");

    var input = document.getElementsByTagName("input");


    btn01.onclick = function() {
        input[0].type = "text";
    }
    btn02.onclick = function() {
        input[1].value = "宫小白";
    }
    btn03.onclick = function() {
        input[2].disabled = "disabled";
    }
    btn04.onclick = function() {
        input[3].checked = "";
        input[4].checked = "checked";
    }
</script>

结果:

值得注意

input中改变元素内容是利用它的value属性而不是用innerHTML等方式了。

上面的改为秘文还有一个问题,我们还要再做一个功能。即再次点击按钮又变成秘文(这里还有点小技巧呢)
看代码:

    var flag = true;
    btn01.onclick = function() {
        if (flag) {
            input[0].type = "text";
            flag = false;
        } else {
            input[0].type = "password";
            flag = true;
        }
    }

这里我们我们需要设置一个标志位的变量,以控制俩次点击实现不同的效果。既然只有两种情况那么boolean型便可完美胜任
看效果:
webAPI系列之_7分钟玩转DOM上篇_第10张图片
拓展:有三种情况呢。比如第一次点击变明文,再一次点击变秘文,再一次点击变成按钮了
主要看代码思路:(看标志位的用法)

    var flag = 0;
    btn01.onclick = function() {
        if (flag == 0) {
            input[0].type = "text";
            flag += 1;
        } else if (flag == 1) {
            input[0].type = "password";
            flag += 1;
        } else {
            input[0].type = "button";
            flag = 0;
        }
    }

结果:
webAPI系列之_7分钟玩转DOM上篇_第11张图片

4.4 操作元素的样式属性(css属性)

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

4.4.1 通过操作style属性

看栗子吧:(注意js不认-,所以background-color要安装驼峰命名法写成backgroundColor )

	//原样式
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: aqua;
        }
    </style>
    <button></button>
    <div>这是一个div</div>
<script>
    var btn = document.querySelector("button");
    var div = document.querySelector("div");
    btn.onclick = function() {
        div.style.width = "300px";
        div.style.height = "300px";
        div.style.backgroundColor = "red";
        div.style.marginLeft = "20px";
        div.style.color = "yellow";
        div.style.fontSize = "30px";

    }
</script>

效果:
webAPI系列之_7分钟玩转DOM上篇_第12张图片
值得注意:
通过style修改的样式产生的是行内式,权重较高。

4.4.2 通过操作className属性

不知道你发现没,上面js代码代码div.style写了一堆。把我自己都写烦了。
那有些好的方法呢?
我们何尝不实现写好要改变的样式,通过改变元素的className属性。间接的修改呢
把上面的栗子做一下修改:

       .tag {
            margin-left: 20px;
            width: 300px;
            height: 300px;
            background-color: red;
            color: yellow;
            font-size: 30px;
        }
<script>
    var btn = document.querySelector("button");
    var div = document.querySelector("div");
    btn.onclick = function() {
        div.className = "tag";

    }
</script>

岂不是更加简单。
值得注意:
通过className修改元素的类名,原有类名也会被覆盖。若想保留你需这样写
div.className = "原类名 新加类名"类名之间空格隔开

4.4 自定义属性操作

也许你会有一些疑问。属性的获取,我们可以通过上面的element.属性来获取啊
为什么还要再学一个呢
嗯,多一个肯定会有多一个的好处。上面的element.属性它是只能获取我们元素内那些自带的属性。很多情况元素自带的属性可是不够用的,我们会给元素自定义一些。比如

它里面的date-index属性用上面的方法可是拿不到的。接下来看下面的了

4.5.1 获取属性值

基本语法:

element.getgetAttribute("属性名");

栗子:

    <div class="demo" date="1"></div>
    <script>
        var div = document.querySelector("div");
        //顺便验证一下div.date是获取不到的
        console.log(div.date);
        console.log(div.getAttribute("date"));
    </script>

结果:
webAPI系列之_7分钟玩转DOM上篇_第13张图片

4.5.2 设置属性

基本语法:

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

栗子:

    <div class="demo" date="1"></div>
    <script>
        var div = document.querySelector("div");
        div.setAttribute("date-index", 2);
    </script>

结果:
webAPI系列之_7分钟玩转DOM上篇_第14张图片

4.5.3 移出属性

基本语法:

element.removeAttribute("属性值");

栗子:

    <div class="demo" date="1"></div>
    <script>
        var div = document.querySelector("div");
        div.removeAttribute("date");
    </script>

结果:
webAPI系列之_7分钟玩转DOM上篇_第15张图片

4.5.4 h5自定义属性

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

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

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

故H5给我们新增了自定义属性:
H5规定自定义属性名以data-起头。同时提供一种拿值的新方法(不过得是ie11以上的浏览器才支持喔)
使用:

element.dataset.名字
或者
element.dataset['名字']

栗子:

    <div class="demo" data-index="1"></div>
    <script>
        var div = document.querySelector("div");
        console.log(div.dataset.index);
        console.log(div.dataset["index"]);
    </script>

结果:
webAPI系列之_7分钟玩转DOM上篇_第16张图片

5 节点操作

一个网页文档中所有东西都可以看成一个节点,大到一个个标签。小到一个空格
我们都可以通过节点操作将它们获取到,并进行操作
既然文本和元素都可以看做一个节点,那我们怎么区分它们呢?
答:一个节点通常有三个最基本的属性。即nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性
其中

  • 元素节点的nodeType为1;
  • 属性节点的nodeType为2
  • 文本节点的nodeType为3;
    栗子:
    webAPI系列之_7分钟玩转DOM上篇_第17张图片
    结果:
    webAPI系列之_7分钟玩转DOM上篇_第18张图片

5.1 常见的节点层级

父子关系,兄弟关系

5.1.1 获取元素节点的父节点

基本语法:注意返回的是离自己最近的父级,即亲爸爸

node.parentNode;

栗子:

    <ul>
        <li></li>
        <li></li>
        <li></li>
    </ul>
    <script>
        var li = document.querySelector("li");
        console.log(li.parentNode);
    </script>

结果:
webAPI系列之_7分钟玩转DOM上篇_第19张图片

5.1.2 获取元素节点的子节点

方法一:node.childNode(w3c标准,但是他能获取所有的子节点包括换行文本这样的节点)
方法一:node.children(获取当前节点的所有子元素节点)
其他

  • 获取第一个子节点
    • node.firstchild(包含所有)
    • node.firstElementChild(子元素节点)
  • 获取最后一个子节点
    • node.lastchild(包含所有)
    • node.lastElementChild(子元素节点)

栗子:

    <div>
        <ul>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </div>
    <script>
        var ul = document.querySelector("ul");
        console.log(ul.childNodes);
        console.log(ul.children);
        console.log(ul.firstChild);
        console.log(ul.firstElementChild);
        console.log(ul.lastChild);
        console.log(ul.lastElementChild);
    </script>

结果:
webAPI系列之_7分钟玩转DOM上篇_第20张图片

5.1.3 获取元素节点的兄弟节点

  • 获取上一个兄弟节点node.previousSibling
  • 获取下一个兄弟节点node.nextSibing
  • 获取上一个兄弟元素节点node.previousElementSibling(ie9)
  • 获取下一个兄弟元素节点node.nextElementSibing(ie9)
    兼容ie写法:
   function getNextElementSibling(element) {
      var el = element;
      //兄弟节点一本不可能在第一个找到,第一个一般都是个换行所以要循环往下找
      while (el = el.nextSibling) {
      //利用nodeType取出元素节点并返回
        if (el.nodeType === 1) {
            return el;
        }
      }
      return null;
    }

5.2 节点的增删

5.2.1. 节点创建

创建元素节点:
document.createElement("名字")

5.2.2 节点添加

创建了之后需要我们给它指定位置,有两种

  • node.appendChlid(“新节点”);直接放到node节点的最后一个孩子后面
  • node.insertBefore(“新节点”,指定元素)放到node节点的一个你指定的子元素节点的前面
    栗子:
    <div>
        <ul>
            <li></li>
            <li class="li"></li>
            <li></li>
        </ul>
    </div>
    <script>
        var newli01 = document.createElement("li");
        var newli02 = document.createElement("li");
        newli01.innerHTML = "我是新来的1号";
        newli02.innerHTML = "我是新来的2号";
        var ul = document.querySelector("ul");
        ul.appendChild(newli01);
        ul.insertBefore(newli02, ul.children[1]);
    </script>

webAPI系列之_7分钟玩转DOM上篇_第21张图片

5.2.3 节点删除

node.removeChild(要删除的);返回值是删除的那个节点。
栗子:
ul.removeChild(ul.children[0]);删除ul的第一个元素节点

5.2.3 克隆节点

node.cloneNode(),再克隆一个node节点。
它有两个参数

  • true 克隆这个节点包含节点里面的内容
  • false或空 只克隆本节点
    栗子:
    <div>
        <ul>
            <li></li>
            <li>aaa
                <div>

                </div>
            </li>
            <li></li>
        </ul>
    </div>
    <script>
        var ul = document.querySelector("ul");
        var li = ul.children[1];
        var new01 = li.cloneNode(true);
        var new02 = li.cloneNode();
        ul.appendChild(new01);
        ul.appendChild(new02);
    </script>

webAPI系列之_7分钟玩转DOM上篇_第22张图片

点击请看DOM下篇

你可能感兴趣的:(前端知识总结,#,WebAPI系列)