欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

web前端学习笔记--Dom

程序员文章站 2024-03-20 10:29:16
...

web前端学习笔记——DOM

一、概念

DOM:document object model,文档对象模型(将文档抽象为对象),是一种与平台和语言无关的应用程序接口(API),它可以动态地访问程序和脚本,更新其内容、结构和 www 文档的风格,是一种基于树 的API文档,在处理过程中整个文档都表示在存储器中

DOM又称为文档树模型

文档:一个网页

节点:网页中所有的内容都是节点(标签、属性、文本、注释等)

元素:网页中的标签

属性:标签的属性

二、常用操作

  • 获取元素

    1. 根据id获取元素

      方法:通过document对象的getElementById方法

      参数:id的属性值

      返回值:对应的id名的元素对象(没有值)

         <script>
              var para = document.getElementById("text1");
              console.log(para);
          </script>
          <p id="text1">这是一段文字</p>
          <p id="text2">这是一段文字</p>
          <p id="text3">这是一段文字</p>
      

      效果:

      发现得到的是null,主要是因为在js中获取元素必须保证元素已经在浏览器中渲染成功,故需要把获取元素部分在在代码后面

       <p id="text1">这是一段文字</p>
       <p id="text2">这是一段文字</p>
       <p id="text3">这是一段文字</p>
       <script>
              var para = document.getElementById("text1");
              console.log(para);
        </script>
      

      效果:

      扩:在后台查看具体的对象可以用console.dir();

      可以设置其属性

       para.style.background = "pink";
      
    2. 根据标签名获取元素

      方法:document对象的getElementByTagName方法

      参数:标签名

      返回值:由同名的元素对象组成的数组(按照顺序排列)

      <p>text1</p>
      <p>text2</p>
      <p>text3</p>
      <script>
           para = document.getElementsByTagName("p");
           console.log(para);
      </script>
      

      效果:

      其中的HTMLCollection:html元素组成的集合 伪数组

      在操作数据时,需要按照数组的方法进行

      获取的元素是动态增加的(push加入),故可以写在html之前(渲染之前)

      for (var i = 0; i <= para.length - 1; i++) {
                  console.log(para[i]);		//显示每一项
      }
      para[0].style.background = "pink";		//设置属性
      

      效果:

      扩:元素对象内部获取标签元素(缩小选择元素的范围)

      <div id="box1">
              <p>text1 of box1</p>
              <p>text2 of box1</p>
              <p>text3 of box1</p>
              <p>text4 of box1</p>
      </div>
      <script>
              var box1 = document.getElementById("box1");
              console.log(box1);
              var ps1 = box1.getElementsByTagName("p");
              console.log(ps1);
      </script>
      

      可以简写,类似后代选择器

      var box1 = document.getElementById("box1").getElement
      sByTagName("p");
      
    3. 根据name获取元素

      方法:调用 document 对象的 getElementsByName 方法。

      参数:字符串类型的 name 属性值。

      返回值:name 属性值相同的元素对象组成的数组。

      不建议使用:在 IE 和 Opera 中有兼容问题,会多选中 id 属性值相同的元素。

       <form>
              <input type="radio" name="age">0~10<br>
              <input type="radio" name="age">11~20<br>
              <input type="radio" name="age">20~30<br>
      </form>
      <div id="age">年龄</div>
      <script>
              var ages = document.getElementsByName("age");
              console.log(ages);
      </script>
      

      效果:

      注:只能使用document去调用getElementsByName

      Nodelist是返回节点的集合,元素节点,HTMLcollection是HTML的集合,是一个元素,是节点的一种,故可以理解为HTMLcollection是Nodelist的一种

    4. 根据类名获取元素

      方法:调用 document 对象的 getElementsByClassName 方法。

      参数:字符串类型的 class 属性值。

      返回值:class 属性值相同的元素对象组成的数组。 (动态添加)

      浏览器兼容问题:不支持 IE8 及以下的浏览器

      <div id="box1">
              <p class="para">text1 of box1</p>
              <p class="para">text2 of box1</p>
              <p>text3 of box1</p>
              <p>text4 of box1</p>
      </div>
      <script>
              var paras = document.getElementsByClassName("para");
              console.log(paras);
      </script>
      

      效果:

      元素对象内部也可以调用getElementsClassName

      var box1 = document.getElementById("box1");
      var paras = box1.getElementsByClassName("para");
      console.log(paras);
      

      效果:

    5. 根据选择器获取元素

      方法1:调用 document 对象的 querySelector 方法,通过 css 中的选择器去选取第一个

      符合条件的标签元素。

      参数:字符串类型的 css 中的选择器。

      返回值:对象元素

      <div>
              <p>text1 of box1</p>
              <p>text2 of box1</p>
              <p>text3 of box1</p>
              <p>text4 of box1</p>
          </div>
          <script>
              var para = document.querySelector("p");
              console.log(para);
          </script>
      
      

      效果:

      方法2:调用 document 对象的 querySelectorAll 方法,通过 css 中的选择器去选取所

      有符合条件的标签元素。

      参数:字符串类型的 css 中的选择器。

      返回值:数组

      <div>
              <p>text1 of box1</p>
              <p>text2 of box1</p>
              <p>text3 of box1</p>
              <p>text4 of box1</p>
          </div>
          <script>
              var para = document.querySelectorAll("p");
              console.log(para);
          </script>
      

      效果:

      浏览器兼容问题:不支持 IE8 以下的浏览器

  • 对元素进行操作

  • 动态创建元素

  • 事件(什么时机做相应的操作)

    ​ 事件:在什么时候做什么事

    ​ 执行机制:触发–响应机制

    ​ 绑定事件(注册事件)三要素:

    ​ 1、事件源:给谁绑定事件

    ​ 2、事件类型:绑定什么类型的事件 click 单击

    ​ 3、事件函数:事件发生后执行什么内容,写在函数内部

    ​ 事件监听:JavaScript 解析器会给有绑定事件的元素添加一个监听,解析器会一直监测这个元素,只要

    触发对应的绑定事件,会立刻执行事件函数。

    ​ 绑定方法(监听):

    ​ 方法一:绑定HTML元素属性

     <input type="button" value="点击有惊喜" onclick="alert('点击我做什么?')">
    

    ​ 方法二:绑定DOM对象属性

    1.获取元素

    2.绑定事件

    <input type="button" value="点击有惊喜" id="btn">
    <script>
            var btn = document.getElementById("btn");	//获取元素
            btn.onclick = function() {					//绑定
                alert("点击我做什么");
            };
    </script>
    

    常用鼠标事件类型

    • onclick 鼠标左键单击触发

    • ondbclick 鼠标左键双击触发

    • onmousedown 鼠标按键按下触发

    • onmouseup 鼠标按键放开时触发

    • onmousemove 鼠标在元素上移动触发

    • onmouseover 鼠标移动到元素上触发

    • onmouseout 鼠标移出元素边界触发

属性操作:

非表单元素属性(href、title、id、src等)

调用方式:元素对象打点调用属性名,例如 obj.href。

注意:部分的属性名跟关键字和保留字冲突,会更换写法。

class → className

for → htmlFor

rowspan → rowSpan

属性赋值:给元素属性赋值,等号右侧的赋值都是字符串格式

<a href="http://www.baidu.com" title="跳转到百度" id="link">跳转</a>
    <img src="images/a.jpg" alt="图片" id="pic" width="100px">
    <script>
        var link = document.getElementById("link");
        var pic = document.getElementById("pic");
        // 调用
        console.log(link.title);
        console.log(link.href);
        console.log(link.id);
        console.log(pic.src);
        console.log(pic.id);
    </script>

案列:

点击按钮切换图片

<input type="button" value="点击" id="btn"><br>
    <img src="images/a.jpg" alt="图片a" id="pic" width="200px">
    <script>
        //  获取元素
        var btn = document.getElementById("btn");
        var pic = document.getElementById("pic");
        // 添加事件
        // btn.onclick = function() {
        //     if (pic.src === "images/a.jpg") {
        //         pic.src = "images/b.jpg";
        //     } else {
        //         pic.scr = "images/a.jpg";
        //     }
        // }
        //失败原因是因为pic.src的值是绝对路径,可以添加一个值作为判断条件
        var num = 1;    //当num为1的时候,就是a照片,2的时候,为b照片
        btn.onclick = function() {
            if (num == 1) {
                pic.src = "images/b.jpg";
                num = 2; //可以循环切换
            } else {
                pic.src = "images/a.jpg";
                num = 1; //可以循环切换
            }
        }
    </script>

点击按钮,显示隐藏

<style>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
        }
        
        .show {
            display: block;
        }
        
        .hide {
            display: none;
        }
</style>
<body>
    <input type="button" value="隐藏" id="btn"><br>
    <div id="box"></div>
    <script>
        //    获取元素
        var btn = document.getElementById("btn");
        var box = document.getElementById("box");
        // 事件
        btn.onclick = function() {
            if (btn.value == "隐藏") {
                box.className = "hide";
                btn.value = "显示"
            } else {
                box.className = "show";
                btn.value = "隐藏";
            }
        }
    </script>
</body>

this

在事件函数内部 有一个 this ,指向事件源

区分一下不同函数内部 this 的指向

普通函数 -> window 对象

构造函数 -> 指向的是生成的实例对象

对象的方法 -> 指向的是对象本身

事件函数 -> 指向的是事件源

美女相册

 <h2>美女画廊</h2>
    <div id="imagegallery">
        <a href="images/1.jpg" title="美女A">
            <img src="images/1-small.jpg" alt="美女1" width="100px">
        </a>

        <a href="images/2.jpg" title="美女B">
            <img src="images/2-small.jpg" alt="美女2" width="100px">
        </a>
        <a href="images/3.jpg" title="美女C">
            <img src="images/3-small.jpg" alt="美女3" width="100px">
        </a>
        <a href="images/4.jpg" title="美女A">
            <img src="images/4-small.jpg" alt="美女4" width="100px">
        </a>
    </div>
    <div style="clear:both"></div>
    <img src="images/placeholder.png" alt="" width="450px" id="image">
    <p id="des">选择一个图片</p>
<script>
        // 获取元素
        var imagegallery = document.getElementById("imagegallery");
        var link = imagegallery.getElementsByTagName("a");
        var image = document.getElementById("image");
        var des = document.getElementById("des");
        // 添加点击事件
       for (var i = 0; i <= link.length - 1; i++) {
            link[i].onclick = function() {
                // alert("aaaa");
                // image.src = link[i].href;
                image.src = this.href;
                return false;		//取消a标签默认的返回效果
            }
        }
</script>

为什么不能使用**image.src = link[i].href;**是因为在for 循环内部添加的绑定事件,在触发时,所有的批量添加的事件已经成功,触发事件时都是在循环结束之后,当批量绑定的事件的事件函数内部有 变量 i,i的值是循环结束后的值,(循环内部定义的变量是一个全局变量)故在循环后执行的 i 变量的值是 i 跳出循环时的值此时的i的值是4,已超出link的长度。

获取标签内部内容的属性

1.innerHTML

是标签内部的所有内容,包括包含的标签、空白、换行等

设置属性值:可以给双标签内部更改内容,可以有标签(按照HTML语法中的标签加载)

使用场景:在设置有内部子标签结构时使用

2.innerText

只包含文本内容,会去掉标签、空白、缩进等

设置属性值:可以给双标签内部更改内容,可以有标签(按照普通的字符加载)

使用场景:在设置纯字符串的时候使用

<div id="box">
        这是一个div标签
        <p id="ps">这是一段文字</p>
</div>
<script>
        var box = document.getElementById("box");
        var ps = document.getElementById("ps");
        var box1 = box.innerHTML;
        console.log(box1);
        console.log(box.innerText);
</script>

表单元素属性

• value 用于大部分表单元素的内容获取(option除外,option用innerHTML)

• type 可以获取input标签的类型(输入框或复选框等)

• disabled 禁用属性

• checked 复选框选中属性

• selected 下拉菜单选中属性

• 注意:在 DOM 中元素对象的属性值只有一个时,会被转成布尔值显示。

例如:txt.disabled = true;

案列:

检测用户名是否是3-6位,密码是否是6-8位,如果不满足要求高亮显示文本框

登录:
<input type="text" value="" placeholder="请输入用户名" id="loginName"> <br>密码:
<input type="password" placeholder="请输入密码" id="loginPassword"><br>
<input type="button" value="点击" id="btn">
<script>
        var btn = document.getElementById("btn");

        //判断
        btn.onclick = function() {
            var name = document.getElementById("loginName");
            var pw = document.getElementById("loginPassword");
            if (name.value.length < 3 || name.value.length > 6) {
                name.className = "bg";
                return;
            } else {
                name.className = "";
            }
            if (pw.value.length < 6 || pw.value.length > 8) {
                pw.className = "bg";
                return;
            } else {
                pw.className = "";
            }
        }
</script>

设置下拉框中的选中项 (随机选择)

 <input type="button" value="点击" id="btn">
    <select name="food" id="list">
        <option value="">小龙虾</option>
        <option value="">火锅</option>
        <option value="">麻辣烫</option>
        <option value="">鸡公煲</option>
        <option value="">酸辣粉</option>
    </select>
    <!--  -->
    <script>
        var btn = document.getElementById("btn");
        var list = document.getElementById("list");
        var opts = list.getElementsByTagName("option");
        btn.onclick = function() {
            var num = Math.floor((Math.random()) * opts.length);
            opts[num].selected = true;
        };
    </script>

搜索文本框 (获取焦点、失去焦点)

<input type="text" class="grey" value="请输入搜索内容" id="search">
    <input type="button" value="搜索" id="btn">
    <script>
        var search = document.getElementById("search");
        var btn = document.getElementById("btn");
        // 设置高亮
        search.onfocus = function() {
            if (search.value === "请输入搜索内容") {
                this.className = "black";
                this.value = "";
            }
        };
        search.onblur = function() {
            if (search.value == "" || search.value == "请输入搜索内容") {
                this.value = "请输入搜索内容";
                this.className = "grey";
            }
        };
    </script>

全选反选

<div class="wrap">
        <table>
            <thead>
                <tr>
                    <td><input type="checkbox" id="all"></td>
                    <td>商品</td>
                    <td>价钱</td>
                </tr>
            </thead>
            <tbody id="tb">
                <tr>
                    <td><input type="checkbox"></td>
                    <td>iphone8</td>
                    <td>8000</td>
                </tr>
                <tr>
                    <td><input type="checkbox"></td>
                    <td>ipad Pro</td>
                    <td>5000</td>
                </tr>
                <tr>
                    <td><input type="checkbox"></td>
                    <td>ipad Air</td>
                    <td>4000</td>
                </tr>
                <tr>
                    <td><input type="checkbox"></td>
                    <td>Apple Watch</td>
                    <td>2000</td>
                </tr>
            </tbody>
        </table>
        <input type="button" value="反选" id="btn">
    </div>
    <script>
        // 获取元素
        var all = document.getElementById("all");
        var tb = document.getElementById("tb");
        var tb_input = tb.getElementsByTagName("input");
        var btn = document.getElementById("btn");
        // 全选
        all.onclick = function() {
            for (var i = 0; i < tb_input.length; i++) {
                tb_input[i].checked = all.checked;
            }
        };
        // 单选去全选
        for (var i = 0; i < tb_input.length; i++) {
            tb_input[i].onclick = function() {
                // 判断所有子选项是否都是选中的状态
                allChecked();
            };
        }
        // 反选  与之前的状态相反
        btn.onclick = function() {
            for (var i = 0; i < tb_input.length; i++) {
                tb_input[i].checked = !tb_input[i].checked;
            }
            allChecked();
        };
        //  定义isAllChecked函数
        function allChecked() {
            var isAllChecked = true;
            for (var i = 0; i < tb_input.length; i++) {
                if (tb_input[i].checked === false) {
                    isAllChecked = false;
                    break;
                }
            }
            all.checked = isAllChecked;
        }
    </script>

自定义属性操作

 <div id="box" age="18" sex="男">小明</div>

对于标签的自身属性可以通过打点的方式获取

console.log(box.id);

对于自定义的属性获取可以调用元素对象getAttribute

console.log(box.getAttribute("age"));
console.log(box.getAttribute("sex"));

也可以调用自有的属性

console.log(box.getAttribute("id"));

设置属性,添加新的自定义属性或者自有属性,修改属性setAttribute

box.setAttribute("name", "小明");
box.setAttribute("age", "20");

移出属性 removeAttribute

box.removeAttribute("age");

style样式属性操作

console.log(box.style);
box.style.width = "200px";

1.使用style属性方式设置的样式会显示在标签行内

2.element.style属性的值,是所有行内样式组成的一个样式对象

3.可以通过点语法去调用或者更改行内样式

4.复合属性即多个单词组成,要修改为驼峰命名方式

5.在设置宽高、位置等的属性时,需要加上px等单位

className类名属性操作

修改元素的 className 属性相当于直接修改标签的类名。

如果需要修改多条 css 样式,可以提前将修改后的样式设置到一个类选择器中,后续通过修改类名的方式,批量修改 css 样式

.cls{
	width:100px;
	height:100px;
	background-color:pink;
}
 box.className = "cls";

案例

开关灯

 <input type="button" value="关灯" id="btn">
    <script>
        var btn = document.getElementById("btn");
        // var isOpen = true;
        // btn.onclick = function() {
        //     if (isOpen) {
        //         document.body.style.backgroundColor = "black";
        //         this.value = "开灯";
        //         isOpen = false;
        //     } else {
        //         document.body.style.backgroundColor = "white";
        //         this.value = "关灯";
        //         isOpen = true;
        //     }
        // }
        btn.onclick = function() {
            if (this.value === "关灯") {
                document.body.style.backgroundColor = "black";
                this.value = "开灯";
            } else {
                document.body.style.backgroundColor = "white";
                this.value = "关灯";
            }
        }
    </script>

body是封装在document对象中,可以直接调用

图片切换二维码案例

 <div class="box" id="box">
        <div class="erweima hide" id="er">
            <img src="images/456.png" alt="">
        </div>
    </div>
    <script>
        var box = document.getElementById("box");
        var er = document.getElementById("er");
        box.onmouseover = function() {
             er.className = "erweima show";
        }
        box.onmouseout = function() {
            er.className = "hide";
        }
    </script>

当前输入的文本框高亮显示

<input type="text"><br>
    <input type="text"><br>
    <input type="text"><br>
    <input type="text"><br>
    <input type="text"><br>
    <input type="text"><br>
    <input type="text"><br>
    <button id="btn">提交</button>
    <script>
        var txts = document.getElementsByTagName("input");
        for (var i = 0; i < txts.length; i++) {
            txts[i].onfocus = function() {
                for (var j = 0; j < txts.length; j++) {
                    txts[j].style.backgroundColor = "";
                }
                this.style.backgroundColor = "yellow";
            };
        }
    </script>

点击按钮改变div的大小和位置

 <style>
        div {
            width: 100px;
            height: 100px;
            background-color: pink;
        }
        
        .new {
            width: 200px;
            height: 200px;
            position: absolute;
            left: 50px;
            top: 50px;
        }
    </style>
    <input type="button" value="按钮" id="btn">
    <div id="box"></div>
    <script>
        var btn = document.getElementById("btn");
        var box = document.getElementById("box");
        btn.onclick = function() {
            //修改类名
            // box.className = "new";
            //更改或者添加属性
            box.style.width = "200px";
            box.style.height = "200px";
            box.style.position = "absolute";
            box.style.top = "200px";
            box.style.left = "200px";
        }
    </script>

表格隔行变色、高亮显示

<style>
        td {
            width: 100px;
            height: 50px;
        }
    </style>
    <table border="1" style="border-collapse: collapse;">
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </table>
    <script>
        var trs = document.getElementsByTagName("tr");
        for (var i = 0; i < trs.length; i++) {
            if (i % 2 == 0) {
                trs[i].style.backgroundColor = "pink";
            } else {
                trs[i].style.backgroundColor = "skyblue";
            }
            var bgc;
            trs[i].onmouseover = function() {
                bgc = this.style.backgroundColor;
                this.style.backgroundColor = "yellow";
            }
            trs[i].onmouseout = function() {
                this.style.backgroundColor = bgc;
            }
        }
    </script>

tab选项卡切换

 <style>
        .box {
            width: 400px;
            height: 300px;
            border: 1px solid black;
            overflow: hidden;
        }
        
        .hd {
            height: 45px;
        }
        
        .hd span {
            display: inline-block;
            width: 90px;
            line-height: 45px;
            text-align: center;
            background-color: pink;
        }
        
        .hd span.current {
            background-color: skyblue;
        }
        
        .bd div {
            height: 255px;
            background-color: skyblue;
            display: none;
        }
        
        .bd div.current {
            display: block;
        }
    </style>
    <div class="box" id="box">
        <div class="hd" id="hd">
            <span class="current">体育</span>
            <span>娱乐</span>
            <span>新闻</span>
            <span>综合</span>
        </div>
        <div class="bd" id="bd">
            <div class="current">这是体育模块</div>
            <div>这是娱乐模块</div>
            <div>这是新闻模块</div>
            <div>这是综合模块</div>
        </div>
    </div>
    <script>
        var hd = document.getElementById("hd");
        var spans = hd.getElementsByTagName("span");
        var bd = document.getElementById("bd");
        var divs = bd.getElementsByTagName("div");
        for (var i = 0; i < spans.length; i++) {
            spans[i].index = i;	//添加一个新属性记录下标
            spans[i].onmouseover = function() {
                for (var j = 0; j < spans.length; j++) {
                    spans[j].className = "";
                    divs[j].className = "";
                }
                this.className = "current";
                divs[this.index].className = "current";

            };
        }
    </script>

排他思想:

​ 第一步: 排除其他的方法,就是将所有的项都恢复默认

​ 第二步:保留自己,设置自己的特殊样式

对应控制思想:

​ 当两组数据中存储了相同个数的元素时,一组数据变化时,会引起另一组变化

​ 方法:找到两组数据的共同点,

DOM节点操作

节点属性:

  1. nodeType 节点类型 属性值:数字 只读 有12种,其中1为元素节点,2为属性节点,3为文本节点
  2. nodeName 标签名称 只读
  3. nodeValue 节点值,返回或设置当前节点的值,其中元素节点 的nodeValue始终是null

父子节点常用属性

  • childNodes 只读属性,获取一个节点所有子节点的实时的集合,集合是动态变化的。

  • children 只读属性,返回一个节点所有的子元素节点集合,是一个动态更新的 HTML 元素 集合。

  • firstChild 只读属性,返回该节点的第一个子节点,如果该节点没有子节点则返回 null。

  • lastChild 只读属性,返回该节点的最后一个子节点,如果该节点没有子节点则返回 null。

  • parentNode 返回一个当前节点的父节点,如果没有这样的节点,比如说像这个节点是树结构 的顶端或者没有插入一棵树中,这个属性返回 null。

  • parentElement 返回当前节点的父元素节点,如果该元素没有父节点,或者父节点不是一个 DOM 元素,则返回 null。

 <div id="box">
        <p> 这是一段文字</p>
        <span>这是一个span标签</span>
    </div>
    <script>
        var box = document.getElementById("box");
        console.log(box.childNodes);
        console.log(box.children);
        console.log(box.firstChild);
        console.log(box.lastChild);
        console.log(box.lastElementChild);
        console.log(box.parentNode);
        console.log(box.parentElement);
    </script>

兄弟节点常用属性

  • nextSibling 只读属性,返回与该节点同级的下一个节点,如果没有返回null。

  • previousSibling 只读属性,返回与该节点同级的上一个节点,如果没有返回null。

  • nextElementSibling 只读属性,返回与该节点同级的下一个元素节点,如果没有返回null。

  • previousElementSibling 只读属性,返回与该节点同级的上一个元素节点,如果没有返回null。

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

创建新节点的方法

  • document.createElement(“div”) 创建元素节点

  • document.createAttribute(“id”) 创建属性节点

  • document.createTextNode(“hello”) 创建文本节点

    一般将创建的新节点存在变量中,方便使用。

 <div id="box">
        <p>text1</p>
        <p>text2</p>
        <p>text3</p>
    </div>
    <script>
        var div = document.createElement("div");
        console.dir(div);
        var cls = document.createAttribute("class");
        console.dir(cls);
        var txt = document.createTextNode("hello");
        console.dir(txt);
    </script>

节点常用操作

  • 添加

    parentNode.appendChild(child):将一个节点添加到指定父节点的子节点列表末尾。

    box.appendChild(div);
    div.appendChild(txt);
    
  • 替代

    parentNode.replaceChild(newChild, oldChild):用指定的节点替换当前节点的一个子节 点,并返回被替换掉的节点。

     box.replaceChild(div, p2);
    
  • 插入

    parentNode.insertBefore(newNode, referenceNode):在参考节点之前插入一个拥有指定 父节点的子节点,referenceNode 必须设置,如果 referenceElement 为 null 则 newNode 将被插入到子节点的末尾。

    box.insertBefore(div, p2);
    
  • 移出

    parentNode.removeChild(child):移除当前节点的一个子节点。这个子节点必须存在于当前节点中。

    box.removeChild(div);
    
  • 克隆

    Node.cloneNode():克隆一个节点,并且可以选择是否克隆这个节点下的所有内容。参数为 Boolean 布尔值,表示是否采用深度克隆,如果为 true,则该节点的所有后代节点也都会被克隆,如果为 false,则只克隆该节点本身,默认值为 true,节点下的内容会被克隆

    注意:克隆时,标签上的属性和属性值也会被复制,写在标签行内的绑定事件可以被复制,但是通过 JavaScript 动态绑定的事件不会被复制。

  • 判断是否有子节点

    Node.hasChildNodes():没有参数,返回一个 Boolean 布尔值,来表示该元素是否包含有子节点

    判断总结:

    ​ node.firstChild !== null

    ​ node.childNodes.length > 0

    ​ node.hasChildNodes()

    <div id="box">
            <p>段落内容 1</p>
            <div>
                <p id="p2">段落内容 2</p>
            </div>
            <p>段落内容 3</p>
            <p>段落内容 4</p>
        </div>
        <div id="demo"></div>
        <script>
            var box = document.getElementById("box");
            var p2 = document.getElementById("p2");
            var demo = document.getElementById("demo");
            // 1.hasChildNodes()
            console.log(box.hasChildNodes());
            console.log(p2.hasChildNodes());
            console.log(demo.hasChildNodes());
            //2.firstChild。length;
            console.log(box.firstChild != null);
            console.log(p2.firstChild != null);
            console.log(demo.firstChild != null);
            //3.childNodes.length
            console.log(box.childNodes.length > 0);
            console.log(p2.childNodes.length > 0);
            console.log(demo.childNodes.length > 0);
         </script>
    
  • 判断是否有此节点

    Node.contains(child):返回一个 Boolean 布尔值,来表示传入的节点是否为该节点的后代节点

     //判断是否有后节点
    console.log(box.contains(p2));
    

案列:

动态创建列表

<div id="box">

    </div>
    <script>
        var box = document.getElementById("box");
        // 添加数据
        var food = ["小龙虾", "酸辣粉", "串串", "麻辣烫", "火锅", "干锅"]
            //生成ul元素
        var ul = document.createElement("ul");
        //添加元素到box中
        box.appendChild(ul);
        // 根据数据添加li
        for (var i = 0; i < food.length; i++) {
            var li = document.createElement("li");
            ul.appendChild(li);
            li.innerText = food[i];
        }
    </script>

动态创建表格

 <style>
        th,
        td {
            width: 100px;
            height: 40px;
            text-align: center;
        }
    </style>
    <h1>动态创建表格</h1>
    <table border="1" style="border-collapse: collapse;">
        <thead>
            <tr>
                <th>姓名</th>
                <th>科目</th>
                <th>成绩</th>
                <th>操作</th>
            </tr>

        </thead>
        <tbody id="tb">

        </tbody>
    </table>
    <script>
        var tb = document.getElementById("tb");
        //添加数据
        var datas = [{
            name: "zs",
            subject: "语文",
            score: "80"
        }, {
            name: "cc",
            subject: "数学",
            score: "76"
        }, {
            name: "dl",
            subject: "英语",
            score: "90"
        }, {
            name: "yy",
            subject: "生物",
            score: "83"
        }, {
            name: "lld",
            subject: "地理",
            score: "90"
        }, {
            name: "sq",
            subject: "物理",
            score: "96"
        }];
        //生成tr
        for (var i = 0; i < datas.length; i++) {
            var tr = document.createElement("tr");
            tb.appendChild(tr);
            var data = datas[i];
            for (var k in data) {
                var td = document.createElement("td");
                tr.appendChild(td);
                td.innerText = data[k];
            }
            var td = document.createElement("td");
            tr.appendChild(td);
            var a = document.createElement("a");
            td.appendChild(a);
            a.innerText = "删除";
            a.href = "javaScript:void(0);";
            a.onclick = function() {
                tb.removeChild(this.parentNode.parentNode);
            }

        }
    </script>

选择水果

<style>
        select {
            width: 200px;
            height: 200px;
            background-color: pink;
            font-size: 18px;
        }
    </style>
    <select name="" id="all" multiple="multiple">
        <option value="">苹果</option>
        <option value="">梨</option>
        <option value="">哈密瓜</option>
        <option value="">西瓜</option>
        <option value="">橘子</option>
    </select>
    <input type="button" value=">>" id="btn1">
    <input type="button" value="<<" id="btn2">
    <input type="button" value=">" id="btn3">
    <input type="button" value="<" id="btn4">

    <select name="" id="choose" multiple="multiple"></select>
    <script>
        var all = document.getElementById("all");
        var choose = document.getElementById("choose");
        var btn1 = document.getElementById("btn1");
        var btn2 = document.getElementById("btn2");
        var btn3 = document.getElementById("btn3");
        var btn4 = document.getElementById("btn4");
        btn1.onclick = function() {
            var opts = all.children;
            var n = opts.length; //opts.length的值会随着元素到choose中而减小,不固定
            for (var i = 0; i < n; i++) {
                choose.appendChild(opts[0]);
            }
        }
        btn2.onclick = function() {
            // var opts = choose.children;
            // var n = opts.length; 
            // for (var i = 0; i < n; i++) {
            //     all.appendChild(opts[0]);
            // }
            fun1(choose, all);
        }

        btn3.onclick = function() {
            var opts = all.children;
            var arr = [];
            for (var i = 0; i < opts.length; i++) {
                if (opts[i].selected === true) {
                    arr.push(opts[i]);
                }
            }

            for (var i = 0; i < arr.length; i++) {
                choose.appendChild(arr[i]);
                arr[i].selected = false;
            }
        }

        btn4.onclick = function() {
                // var opts = choose.children;
                // var arr = [];
                // for (var i = 0; i < opts.length; i++) {
                //     if (opts[i].selected === true) {
                //         arr.push(opts[i]);
                //     }
                // }
                // for (var i = 0; i < arr.length; i++) {
                //     all.appendChild(arr[i]);
                //     arr[i].selected = false;
                // }
                fun2(choose, all);
            }
            //btn1,btn2的函数
        function fun1(a, b) {
            var opts = a.children;
            var n = opts.length;
            for (var i = 0; i < n; i++) {
                b.appendChild(opts[0]);
            }
        }

        //btn3,btn4的函数
        function fun2(a, b) {
            var opts = a.children;
            var arr = [];
            for (var i = 0; i < opts.length; i++) {
                if (opts[i].selected === true) {
                    arr.push(opts[i]);
                }
            }
            for (var i = 0; i < arr.length; i++) {
                b.appendChild(arr[i]);
                arr[i].selected = false;
            }
        }
    </script>

注册事件的其他方法

  1. element.addEventListener() 方法。

    参数:

    第一个参数:事件类型的字符串(直接书写”click”,不需要加 on)

    第二个参数:事件函数

    同一个元素可以多次绑定事件监听,同一个事件类型可以注册多个事件函数

    兼容性问题:不支持 IE9 以下的浏览器

<input type="button" value="按钮" id="btn">
    <script>
        var btn = document.getElementById("btn");
        // 绑定DOM0级
        btn.onclick = function() {
                alert(111);
            };
        //绑定DOM1级
        btn.addEventListener("click", function() {
            alert(222);
        });
        //多次绑定
         btn.addEventListener("click", function() {
            alert(333);
        });
    </script>

2.element.attachEvent() 方法。

参数:

​ 第一个参数:事件类型的字符串(需要加 on)

​ 第二个参数:事件函数

​ 同一个元素可以多次绑定事件监听,同一个事件类型可以注册多个事件函数

兼容性问题:只支持 IE10 及以下的浏览器

 btn.attachEvent("onclick",function () {
      alert(3);
    });
    btn.attachEvent("onclick",clickEvent);
    function clickEvent() {
      alert(4);
    }

3.自定义一个注册事件函数

参数:事件源,事件类型(不加 on),事件函数

IE9 及以上的浏览器,使用 addEventListener 方法

IE9 以下的浏览器,使用 attachEvent 方法

判断浏览器时,不需要判断它的版本,可以检测浏览器能力

浏览器能力检测:将某个方法的调用作为 if 语句的判断条件,如果浏览器认识该方法返回true,否则返回 false。

<input type="button" value="按钮" id="btn">
    <script>
        var btn = document.getElementById("btn");
        addEvent(btn, "click", function() {
            alert(222);
        });
        // 自定义函数
        function addEvent(ele, type, fn) {
            if (ele.addEventListener) {
                ele.addEventListener(type, fn);
            } else if (ele.attachEvent) {
                ele.attachEvent("on" + type, fn)
            }
        };

移出事件的其他方法

1.ele.οnclick=null

btn.onclick = null;

2.element.removeEventListener() 方法。

参数:

​ 第一个参数:事件类型的字符串(直接书写”click”,不需要加 on)

​ 第二个参数:事件函数引用名

注意:没有办法移除一个匿名函数,所以在注册事件时需要单独声明一个有函数名的事件函数。

兼容性问题:不支持 IE9 以下的浏览器

btn.addEventListener("click", fun);
btn.removeEventListener("click", fun);

3.element.detachEvent() 方法。

参数:

​ 第一个参数:事件类型的字符串(需要加 on)

​ 第二个参数:事件函数

注意:没有办法移除一个匿名函数,所以在注册事件时需要单独声明一个有函数名的事件函数。

兼容性问题:只支持 IE10 及以下的浏览器

btn.attachEvent("onclick", fun);
btn.detachEvent("onclick", fun);

4.自定义一个移出事件函数

参数:事件源,事件类型(不加 on),事件函数

IE9 及以上的浏览器,使用 removeEventListener 方法

IE9 以下的浏览器,使用 detachEvent 方法

建议:将自己封装的一些常用函数和方法,放到一个单独的 .js 文件中。

 function removeEvent(ele, type, fn) {
            if (ele.removeEventListener) {
                ele.removeEventListener(type, fn);
            } else if (ele.detachEvent) {
                ele.detachEvent("on" + type, fn);
            }
        }

DOM事件流

三阶段

第一阶段:事件捕获(从当前层往下走)

第二阶段:事件执行过程

第三阶段:事件冒泡(从当前层往上走)

addEventListener() 第三个参数为 false 时,事件冒泡 ,addEventListener() 第三个参数为 true 时,事件捕获

onclick 类型:只能进行事件冒泡过程,没有捕获阶段

attachEvent() 方法:只能进行事件冒泡过程,没有捕获阶段

事件委托

利用事件冒泡,将子级的事件委托给父级加载

案列:给点击的无序列表添加背景

 <ul id="list">
        <li>小龙虾</li>
        <li>小面</li>
        <li>火锅</li>
        <li>干锅</li>
        <li>麻辣烫</li>
    </ul>
    <script>
        var list = document.getElementById("list");
        var lis = list.children;
        list.onclick = function(e) {
            for (var i = 0; i < lis.length; i++) {
                lis[i].style.backgroundColor = "";
            }
            e.target.style.backgroundColor = "pink";
        }
    </script>

事件对象

只要触发事件,就会有一个对象,内部存储了与事件相关的数据。

e 在低版本浏览器中有兼容问题,低版本浏览器使用的是 window.event

事件对象常用的属性:

e.eventPhase 查看事件触发时所处的阶段

console.log(e.eventPhase);

1:捕获阶段 2:目标阶段 3:冒泡阶段

e.target 用于获取触发事件的元素

e.srcElement 用于获取触发事件的元素,低版本浏览器使用

 var target = e.target || e.scrElement;
 console.log(target);

e.currentTarget 用于获取绑定事件的事件源元素

console.log(e.currentTarget);

e.type 获取事件类型

console.log(e.type);

大多数时候,会给同一个对象添加不同的事件类型,对应执行的代码不同

  box3.onmouseover = fn;
  box3.onmouseout = fn;

        function fn(e) {
            e = e || window.event;
            switch (e.type) {
                case "mouseover":
                    box3.style.backgroundColor = "black";
                    break;
                case "mouseout":
                    box3.style.backgroundColor = "yellow";
                    break;
            }
        }

e.clientX/e.clientY 所有浏览器都支持,鼠标距离浏览器窗口左上角的距离

console.log(e.clientX);
console.log(e.clientY);

e.pageX/e.pageY IE8 以前不支持,鼠标距离整个HTML页面左上顶点的距离

 console.log(e.pageX);
 console.log(e.pageY);

案列

<style>
        #pic {
            position: fixed;
        }
</style>
<img src="images/tianshi.gif" alt="" id="pic">
<script>
        var pic = document.getElementById("pic");
        document.onmousemove = function(e) {
            e = e || window.event;
            pic.style.left = e.pageX + "px";//一定要加单位
            pic.style.top = e.pageY + "px";

        }
</script>

取消默认行为

1.普通方式 return false;

2.DOM的方式 e.preventDefault(); 低版本:e.returnValue=false;

阻止事件传播

1.e.stopPropagation(); 阻止冒泡,标准方式

2.e.cancelBubble = true; 阻止冒泡,IE 低版本,标准中已废弃

DOM特效

偏移量属性

offsetParent 偏移参考父级,距离自己最近的有定位的父级,如果都没有定位参考body(html)

offsetLeft/offsetTop 偏移位置

offsetWidth/offsetHeight 偏移大小(width+padding+border)

客户端大小

clientLeft/clientTop 边框区域尺寸,不常用

clientWidth/clientHeight 边框内部大小

滚动偏移属性

scrollLeft/scrollTop 盒子内部滚动出去的尺寸

scrollWidth/scrollHeight 盒子内容的宽度和高度

案列

拖拽

 <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        .nav {
            height: 30px;
            background-color: #036663;
            line-height: 30px;
            padding-left: 30px;
        }
        
        .nav a {
            color: #fff;
            font-size: 14px;
            text-decoration: 30px;
        }
        
        .d-box {
            width: 400px;
            height: 300px;
            border: 5px solid #eee;
            position: absolute;
            top: 40%;
            left: 40%;
            background-color: #fff;
            /* 不让文字被选中 */
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
        }
        
        .d-box .hd {
            width: 100%;
            height: 25px;
            background-color: #7c9299;
            color: #fff;
            line-height: 25px;
            cursor: move;
        }
        
        .close {
            float: right;
            cursor: pointer;
        }
    </style>
    <div class="nav">
        <a href="javaScript:void(0);">注册信息</a>
    </div>
    <div class="d-box" id="d_box">
        <div class="hd" id="hd">
            注册信息(可以拖拽)
            <span class="close" id="close">【关闭】</span>
        </div>
        <div class="bd"></div>
    </div>
    <script>
        var box = document.getElementById("d_box");
        var drop = document.getElementById("hd");
        var close = document.getElementById("close");
        drop.onmousedown = function(e) {
            e = e || window.event;
            // 记忆当前鼠标在内部的距离
            var l = e.pageX - box.offsetLeft;
            var t = e.pageY - box.offsetTop;
            drop.onmousemove = function(e) {
                e = e || window.event;
                var newl = e.pageX - l;
                var newt = e.pageY - t;
                box.style.left = newl + "px";
                box.style.top = newt + "px";
            };
        };
        // 当鼠标弹起后移动事件取消
        drop.onmouseup = function() {
            drop.onmousemove = null;
        };
        //点击关闭box
        close.onclick = function() {
            box.style.display = "none";
        }
    </script>

弹出层

<style>
        ul,
        li,
        ol,
        dl,
        dt,
        dd,
        div,
        p,
        span,
        h1,
        h2,
        h3,
        h4,
        h5,
        h6,
        a {
            padding: 0px;
            margin: 0px;
        }
        
        a {
            text-decoration: none;
            color: #000;
        }
        
        .login-header {
            width: 100%;
            height: 30px;
            font-size: 24px;
            line-height: 30px;
            text-align: center;
        }
        
        .login {
            width: 512px;
            height: 280px;
            position: absolute;
            left: 50%;
            margin-left: -256px;
            margin-top: 140px;
            border: 1px solid #ebebeb;
            background-color: #fff;
            z-index: 9999;
            display: none;
        }
        
        .title {
            position: relative;
            width: 100%;
            margin: 10px 0px 0px 0px;
            text-align: center;
            line-height: 40px;
            font-size: 18px;
            cursor: move;
            -moz-user-select: none;
            /*火狐*/
            -webkit-user-select: none;
            /*webkit浏览器*/
            -ms-user-select: none;
            /*IE10*/
            -khtml-user-select: none;
            /*早期浏览器*/
            user-select: none;
        }
        
        .title .close {
            position: absolute;
            right: -20px;
            top: -30px;
            width: 40px;
            height: 40px;
            border-radius: 20px;
            background-color: #fff;
            border: 1px solid #ebebeb;
            font-size: 14px;
            cursor: pointer;
        }
        
        .login-input-content {
            margin-top: 20px;
        }
        
        .login-input {
            overflow: hidden;
            margin: 0 0 20px 0;
        }
        
        .login-input label {
            float: left;
            width: 90px;
            text-align: right;
            font-size: 14px;
            height: 35px;
            line-height: 35px;
        }
        
        .login-input .list-input {
            float: left;
            width: 350px;
            height: 35px;
            line-height: 35px;
            border: 1px solid #ebebeb;
            text-indent: 5px;
        }
        
        .loginBtn {
            width: 50%;
            height: 40px;
            border: 1px solid #ebebeb;
            text-align: center;
            line-height: 40px;
            margin: 30px auto 0;
            font-size: 14px;
        }
        
        .login-bg {
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0px;
            left: 0px;
            background-color: #000;
            opacity: 0.3;
            -moz-opacity: 0.3;
            -khtml-opacity: 0.3;
            filter: alpha(opacity=30);
            display: none;
        }
    </style>
    <div class="login-header"><a href="javaScript:void(0);" id="link">点击弹出登录框</a></div>
    <div class="login" id="login">
        <div class="title" id="login_title">登录会员
            <span class="close" id="close">关闭</span>
        </div>
        <div class="login-input-content">
            <div class="login-input">
                <label for="">用户名:</label>
                <input type="text" placeholder="请输入用户名" id="userName" class="list-input">
            </div>
            <div class="login-input">
                <label for="">密码:</label>
                <input type="text" placeholder="请输入用户密码" id="password" class="list-input">
            </div>
        </div>
        <div class="loginBtn" id="loginBtn"><a href="javaScript:void(0);">登录会员</a> </div>
    </div>
    <div id="bg" class="login-bg"></div>
    <script>
        var link = document.getElementById("link");
        var close = document.getElementById("close");
        var bg = document.getElementById("bg");
        var login = document.getElementById("login");
        link.onclick = function() {
            login.style.display = "block";
            bg.style.display = "block";
        }
        close.onclick = function() {
            login.style.display = "none";
            bg.style.display = "none";
        }
    </script>