• DOM


    一、概念

    1、简介

    Document Object Model ,DOM,文档对象模型,是编程接口

    通过这些接口可以改变网页的内容、结构和样式

    2、DOM 树

      ① 文档:一个页面就是一个文档,DOM 中使用 document 表示

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

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

    DOM 把以上内容都看作是对象 Object 类型

    二、获取元素

    1、获取普通元素

    (1)getElementById 方法

    <body>
        <div id="time">2019-9-9</div>
        <script>
            var timer = document.getElementById('time');
            console.log(timer);         //<div id="time">2019-9-9</div>   获取到id为timer的元素
            console.log(typeof timer);  //object   页面内的文档、元素、节点等都是对象类型
            console.dir(timer);         //div#time    dir()能查看元素对象的属性和方法
        </script>
    </body>

    (2)getElementsByTagName 方法

    <body>
        <ul>
            <li>知否知否1</li>
            <li>知否知否2</li>
            <li>知否知否3</li>
            <li>知否知否4</li>
            <li>知否知否5</li>
        </ul>
        <script>
            var lis = document.getElementsByTagName('li');
            console.log(lis);        //HTMLCollection(5) [li, li, li, li, li]  获取以伪数组存储的元素对象
            console.log(typeof lis); //object
            console.log(lis[0]);     //<li>知否知否1</li>   类似数组获取元素、遍历元素
        </script>
    </body>

    如果页面内只有一个或者没有这个 TagName,获取到的也是伪数组的形式

    还可以获取某个指定元素下的子元素,如下:

    <body>
        <ul>
            <li>知否知否1</li>
            <li>知否知否2</li>
        </ul>
        <ol id="ol">
            <li>应是绿肥红瘦1</li>
            <li>应是绿肥红瘦2</li>
        </ol>
        <script>
       //获取ol下的li,不要ul下的li
            //1.先通过getElementById获取指定元素
            var ol = document.getElementById('ol'); 
    
            //2.再通过getElementsByTagName获取指定元素的子元素
            var olLi = ol.getElementsByTagName('li'); 
            console.log(olLi);   //HTMLCollection(2) 以伪数组形式存储的元素对象
        </script>
    </body>

    (3)getElementsByClassName 方法

    <body>
        <div class="box">box1</div>
        <div class="box">box2</div>
        <script>
            var boxs = document.getElementsByClassName('box');
            console.log(boxs);  //HTMLCollection(2)
        </script>
    </body>

    (4)querySelecter 方法

    • H5 新增获取元素的方法
    • 只能获取第一个元素
    • 不同选择器需要加符号来区分
    <body>
        <div class="box">box1</div>
        <div class="box">box2</div>
        <div id="nav">
            <ul>
                <li>首页</li>
                <li>产品</li>
            </ul>
        </div>
        <script>
            var boxOne = document.querySelector('.box'); // class选择器用 .
            console.log(boxOne);   //<div class="box">box1</div> 只能获取第一个元素
            var nav = document.querySelector('#nav');    // id选择器用 #
            console.log(nav);  
            var liOne = document.querySelector('li');    // 标签选择器
            console.log(liOne); 
        </script>
    </body>

    (5)querySelecterAll 方法

    • H5 新增获取元素的方法
    • 能获取所有元素
    • 不同选择器需要加符号来区分
    <body>
        <div class="box">box1</div>
        <div class="box">box2</div>
        <div id="nav">
            <ul>
                <li>首页</li>
                <li>产品</li>
            </ul>
        </div>
        <script>
            var boxOne = document.querySelectorAll('.box'); // class选择器用 .
            console.log(boxOne);   //NodeList(2) 获取所有元素
            var nav = document.querySelectorAll('#nav');    // id选择器用 #
            console.log(nav);  
            var liOne = document.querySelectorAll('li');    //标签选择器
            console.log(liOne); 
        </script>
    </body>

    2、获取特殊元素

    (1)获取 body 元素

    <body>
        <script>
            var bodyEle = document.body;
            console.log(bodyEle);
        </script>
    </body>

    (2)获取 html 元素

    <body>
        <script>
            var htmlEle = document.documentElement;
            console.log(htmlEle);
        </script>
    </body>

    三、事件基础

    1、事件三要素

      ① 事件源,例如:按钮

      ② 事件类型,例如:点击、经过、键盘按下等

      ③ 事件处理程序,例如:弹出对话框

    2、执行事件步骤

      ① 获取事件源

      ② 注册事件

      ③ 添加事件处理程序

    <body>
        <!-- 点击div,控制台输出我被选中了 -->
        <div id="btn">盒子</div>
        <script>
            //1.获取事件源
            var btn = document.getElementById('btn')  //获取元素
            //2.注册事件----元素.事件
            //btn.onclick    
            //3.添加事件处理程序----匿名函数赋值
            btn.onclick = function() {    
                console.log('我被选中了!');
            }
        </script>
    </body>

    四、操作元素

    1、修改元素包含的内容

    (1)innerText 属性

    <body>
        <button>显示时间</button>
        <div>某个时间</div>
        <script>
            //点击button后,div 中的文字变为时间
            var btn = document.querySelector('button');
            var div = document.querySelector('div');
            btn.onclick = function() {
                div.innerText = '2022-04-05';  // innerText 是属性,用等号赋值
            }
        </script>
    </body>

    (2)innerHTML 属性

    <body>
        <div id="div1"></div>
        <div id="div2"></div>
        <script>
            var divEle1 = document.querySelector('#div1');
            var divEle2 = document.querySelector('#div2');
            divEle1.innerHTML = '我是一个盒子';
            divEle2.innerHTML = '<strong>我是</strong>第二个盒子';  //能识别html标签
        </script>
    </body>

    innerText 和 innerHTML 区别:

    • innerText:不识别 html 标签;去除空格和换行
    • innerHTML:识别 html 标签;保留空格和换行

    注意:修改表单元素中的内容和普通元素不同:

    • 普通元素通过修改 innerHTML 和 innerText 属性
    • 表单元素要修改 value 属性,尤其是

    2、修改元素的属性

    给属性重新赋值即可,案例:

    <body>
        <button id="btn1">有道词典</button>
        <img src="img/music.png"/>
        <script>
            //点击button,图片切换为QQ音乐
            var youdao = document.querySelector('#btn1');
            var img = document.querySelector('img');
            youdao.onclick = function() {
                img.src = 'img/youdao.png';  //修改img元素的src属性,直接给src重新赋值即可
            }
        </script>
    </body>

    3、修改元素的样式属性

    (1)通过 style 修改

    <script>
        var div = document.querySelector('div');
        div.onclick = function () {
            div.style.width = '500px';            // 元素名.style.样式属性名
            div.style.backgroundColor = 'blue'; // html是-,JS是驼峰   
        }
    </script>

    注意:JS 修改 style 样式属性,产生的是行内样式

    (2)通过 className 修改

    <div class="box"></div>
    <script type="text/javascript">
        var box = document.querySelector('div');
        box.onclick = function() {             //1.元素名.className 来操作元素类名属性
            this.className = 'box boxChange';  //2.这样修改样式属性会直接覆盖之前的类名,可以用多类名来解决
        }                                      //3.当修改样式较多时,可以使用className来修改
    </script>

    4、排他思想

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

    <script type="text/javascript">
        var btns = document.getElementsByTagName('button');
        //通过循环给所有按钮添加onclick点击事件
        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.再给某个元素设置想要的样式
                this.style.backgroundColor = 'pink';   //这里不能用btn[i] 不是同一个作用域 i不起作用
            }
        }
    </script>

    5、操作元素的自定义属性

    <div index="1" test="test"></div>
    <script type="text/javascript">
        var div = document.querySelector('div');
        //1.获得自定义属性值 getAttribute
        console.log(div.getAttribute('index'));  //1
        //2.设置自定义属性值 setAttribute
        div.setAttribute('index','2');
        console.log(div.getAttribute('index'));  //2
        //3.移除自定义属性值 removeAttribute
        div.removeAttribute('test');
    </script>

    6、H5 自定义属性

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

    但是自定义属性难以判断,所以 H5 新增了自定义属性命名方式:

    • data-xxx 

    获取自定义属性值:

    • 元素.dataset.xxx 
    <div data-time = "21时" data-index = "22" data-list-name = "andy"></div>
    <script type="text/javascript">
        var div = document.querySelector('div');
        //dataset 是一个集合,里面存放了所有以 data 开头的自定义属性
        console.log(div.dataset);         //DOMStringMap {time: '21时', index: '22'}
        console.log(div.dataset.time);    //获取自定义属性 只能获取data-开头的
        console.log(div.dataset.listName); // 驼峰命名法
        console.log(div.dataset['time']);
    </script>

     五、操作节点

    1、节点概述

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

    每种节点都至少拥有 nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)这三个基本属性

    • 元素节点 nodeType = 1
    • 属性节点 nodeType = 2
    • 文本节点 nodeType = 3 (文本节点包含文字、空格、换行等)

    实际操作中,主要操作的是元素节点

    2、节点层级

    (1)父节点

    • 获取父节点
    node.parentNode

    注意:

      ① 返回的是最近的父节点

      ② 没有父节点返回 null

    (2)子节点

    • 获取所有子节点
    // 方法一:返回所有的子节点,包含元素节点、文本节点等(不常用)
    node.childNodes
    // 方法二:返回子节点中的元素节点(常用) 
    node.children
    • 获取第一个子节点
    // 方法一:返回第一个子节点,包含元素节点、文本节点等(不常用)
    node.firstChild
    // 方法二:返回子节点中的第一个元素节点 (IE9 以上才支持)
    node.firstElementChild
    // 方法三:返回子节点中的第一个元素节点(常用)
    node.children[0]
    • 获取最后一个子节点
    // 方法一:返回最后一个子节点,包含元素节点、文本节点等(不常用)
    node.lastChild
    // 方法二:返回子节点中的最后一个元素节点 (IE9 以上才支持)
    node.lastElementChild
    // 方法三:返回子节点中的最后一个元素节点 (常用)
    node.children[children.length - 1]

    (3)兄弟节点(不常用)

    • 获取上一个兄弟节点
    // 方法一:返回上一个兄弟节点,包含元素节点、文本节点等(IE9 以上才支持)
    node.previousSibling
    // 方法二:返回兄弟节点中上一个元素节点(IE9 以上才支持)
    node.previousElementSibling
    • 获取下一个兄弟节点
    // 方法一:返回下一个兄弟节点,包含元素节点、文本节点等(IE9 以上才支持)
    node.nextSibling
    // 方法二:返回兄弟节点中下一个元素节点(IE9 以上才支持)
    node.nextElementSibling

    (4)创建、添加子节点

    <ul>
        <li>123</li>
    </ul>
    <script type="text/javascript">
        var ul = document.querySelector('ul');
        // 1.创建元素节点
        var li1 = document.createElement('li');
        var li2 = document.createElement('li');
        // 2.添加节点
        // (1)在后面追加
        ul.appendChild(li1);  
        // (2)在前面添加
        ul.insertBefore(li2, ul.children[0]);
    </script>

    (5)删除子节点

    <ul>
        <li>1</li>
        <li>2</li>
    </ul>
    <script type="text/javascript">
        var ul = document.querySelector('ul');
        ul.removeChild(ul.children[0]); //会把内容为1的子节点删除掉
    </script>

    (6)复制节点

    <ul>
        <li>1</li>
    </ul>
    <script type="text/javascript">
        var ul = document.querySelector('ul');
        // 1.括号为空或 false 为浅拷贝,只复制标签不复制内容
        var li1 = ul.children[0].cloneNode();
        // 2.括号为 true 为深拷贝,标签和内容都复制
        var li2 = ul.children[0].cloneNode(true);
        ul.appendChild(li1);
        ul.appendChild(li2);
    </script>

    (7)三种动态创建元素区别

    • document.write 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
    • innerHTML 是将多个内容写入某个 DOM 节点,不会导致页面重绘
    • innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
    • creatElement() 创建多个元素效率稍低一点点,但是结构更清晰

    六、注册事件

    1、概述

    给元素添加事件,称为注册事件或绑定事件;

    2、注册事件

    (1)传统方式注册事件

    同一个元素、多次注册同一个事件,只有一个生效,具有唯一性

    (2)方法监听注册事件

    同一个元素、多次注册同一个事件,都生效,不具有唯一性

    IE9 以上才支持

    <button type="button">事件侦听注册事件</button>
    <script type="text/javascript">
        var btn = document.querySelector('button');
        btn.addEventListener('click', function() {  //第一个参数是事件类型字符串:加引号、不带on
            alert('点击了事件侦听按钮!');             //第二个参数是事件处理程序函数
        })
    </script>

    3、删除事件

    (1)传统方式注册的事件

    <script type="text/javascript">
        var div = document.querySelector('div');
        div.onclick = function() {
            alert('要开心呀!!!');
            div.onclick = null;  //传统方式删除事件
        }
    </script>

    (2)方法监听注册的事件

    <script type="text/javascript">
        var div = document.querySelector('div');
        div.addEventListener('click', fn);         // 不用加小括号()
        function fn(){
            alert('一定要开心!');
            div.removeEventListener('click',fn);   // 方法监听注册事件删除事件
        }
    </script>

    七、DOM 事件流

    • DOM 事件流描述的是从页面接收事件的顺序
    • 捕获阶段当前目标阶段冒泡阶段
    • JS 代码中只能执行捕获或冒泡其中的一个阶段
    • onclick 、attachEvent 只能得到冒泡阶段
    • addEventListener 第三个参数是 true,表示在事件捕获阶段调用事件处理程序;如果是 false 或省略,表示在事件冒泡阶段调用事件处理程序
    • 实际开发中很少使用事件捕获,我们更关注事件冒泡 
    • 有些事件是没有冒泡的,比如 onblur、onfocus

    八、事件委托

    1、概念

    事件委托也称事件代理,在 jQuery 里面称为事件委派

    2、原理

    不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点

    九、事件对象

    • 事件对象是事件的一系列相关数据的集合,比如鼠标点击事件是鼠标事件对象(如鼠标坐标等)、键盘事件是键盘事件对象(如判断用户按下了哪个键等)
    • 事件对象在事件处理程序函数的小括号里,当形参来看
    • 事件对象只有有了事件才会存在,是系统给我们自动创建的,不需要我们传递参数
    • 事件对象可以自己命名,比如:event、evt、e等
    • 事件对象也有兼容性,ie678 通过 window.event 兼容性写法 e = e || window.event
    • 事件对象的常见属性和方法:
    • e.target 返回触发事件的对象(而 this 返回的是调用事件的对象,两者只在某些情况下结果相同)
    • e.type 返回事件的类型,比如 click、mouseover(不带 on)
    • e.preventDefault() 阻止默认事件的方法,比如让链接不跳转、让提交按钮不提交
    • e.returnValue 阻止默认事件的属性,ie678使用
    • 阻止事件冒泡:
    • e.stopPropagation() 方法
    • e.cancelBubble 属性

    十、常用的鼠标事件

    1、禁止右键菜单 contextmenu

    <p>禁止右键菜单</p>
    <script type="text/javascript">
        var p = document.querySelector('p');
        p.addEventListener('contextmenu', function(e) {
            e.preventDefault();
        })
    </script>

    绑定 contextmenu 事件后,用阻止默认事件的方法 e.preventDefault() 禁止掉就可以了

    2、禁止选中文字 selectstart

    <p>禁止选中文字</p>
    <script type="text/javascript">
        var p = document.querySelector('p');
        p.addEventListener('selectstart', function(e) {
            e.preventDefault();
        })
    </script>

    绑定 selectstart 事件后,用阻止默认事件的方法 e.preventDefault() 禁止掉就可以了

    3、鼠标事件对象的属性

    e.clientX 鼠标在可视区的 x 坐标

    e.clientY 鼠标在可视区的 y 坐标

    e.pageX 鼠标在页面文档的 x 坐标

    e.pageY 鼠标在页面文档的 y 坐标

    4、鼠标移动事件 mousemove

    跟随鼠标的天使案例:

    <head>
        <meta charset="utf-8">
        <title></title>
        <style type="text/css">
            img {
                position: absolute;    /* 图片要移动 而且不占位置 -> 绝对定位 absolute */
            }
        </style>
    </head>
    <body>
        <img src="img/angel.gif" alt="">
        <script>
            var pic = document.querySelector('img');
            document.addEventListener('mousemove', function(e) {  //只要鼠标移动 1px 就会触发事件
                var x = e.pageX;
                var y = e.pageY;
                pic.style.left = x + 'px'; // left 和 top 不要忘记单位px 
                pic.style.top = y + 'px';
            }) 
        </script>
    </body>

    十一、常用的键盘事件

    1、按键弹起 keyup

    • 弹起才触发
    <script type="text/javascript">
        document.addEventListener('keyup', function() {
            console.log('弹起');
        })
    </script>

    2、按键按下 keydown

    • 只要按下不松开就一直触发
    • keydown 能识别功能键,如:ctrl、shift、箭头等
    • 相同情况下 keydown 比 keypress 先执行
    <script type="text/javascript">
        document.addEventListener('keydown', function() {
            console.log('按下');
        })
    </script>

    3、按键按下 keypress

    • 只要按下不松开就一直触发
    • keypress 不识别功能键
    <script type="text/javascript">
        document.addEventListener('keypress', function() {
            console.log('按下');
        })
    </script>

    4、键盘事件对象的属性

    e.keycode 相应键的 ASCII 码

    • keyup 事件和 keydown 事件的 keycode 属性不区分大小写
    • keypress 事件的 keycode 属性区分大小写
  • 相关阅读:
    实验一
    MVVM Light Toolkit 学习
    配置mongodb分片群集(sharding cluster)
    【silverlight】web发布方法
    MongoDb数据库设计
    【解决方案】添加web服务失败:下载“http://localhost:2540/Service.asmx”时出错。无法生成***类型
    Codeforces #380 div2 C(729C) Road to Cinema
    Codeforces #380 div2 B(729B) Spotlights
    数据挖掘项目总结
    南方电网用电时间序列分析
  • 原文地址:https://www.cnblogs.com/eidolonw/p/15990049.html
Copyright © 2020-2023  润新知