DOM简介

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

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

  • 文档:一个页面就是一个文档,DOM中使用document表示。
  • 元素:页面中所有标签都是元素,DOM中使用element表示。
  • 节点:网页中所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示。

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

获取元素

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

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

  • 根据ID获取
  • 根据标签名获取
  • 通过HTML5新增的方法获取
  • 特殊元素获取

根据ID获取

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

    <div id="time">2020-2-2</div>

    <script>
        var timer = document.getElementById('time');
        console.log(timer);
        console.log(typeof timer);
        console.dir(timer); //可以打印返回的元素对象,更好的查看里面的属性和方法
    </script>
  • get获得 element元素 by通过 驼峰命名法
  • 参数id是大小写敏感的字符串所以要加单引号
  • 返回的是一个元素对象

根据标签名获取

使用 getElementByTagName()方法可以获得所有标签名的对象的集合。

    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>

    <script>
        var list = document.getElementsByTagName('li')
        console.log(list);
        console.log(list[1]);
        //依次打印元素对象采用遍历的方式
        for (var i = 0; i < list.length; i++) {
            console.log(list[i]);
        }
    </script>
  • 返回的是获取到元素对象的集合,以伪数组的形式存储的。
  • 如果页面中只有一个标签,返回的还是伪数组的形式。
  • 如果页面中没有这个元素,返回的是一个空的伪数组。

还可以获取某个元素(父元素)内部所有指定标签名的子元素。

        Element.getElementsByTagName('标签名');

注意:父元素必须是单个对象(必须指明是哪一个元素),获取的时候不包括父元素自己。

        var ol = document.getElementById('ol');
        console.log(ol.getElementsByTagName('li'));

H5新增获取元素方式

  • 根据类名返回元素对象集合
        document.getElementsByClassName('类名');
  • querySelector返回指定选择器的第一个元素对象
document.querySelector('.类名');
document.querySelector('#ID名');
document.querySelector('标签名');
  • querySelectorAll()返回指定选择器的所有元素对象集合
document.querySelectorAll('.类名');
document.querySelectorAll('#ID名');
document.querySelectorAll('标签名');

获取特殊元素(body,html)

  • 获取body元素
        var bodyEle = document.body;//返回body元素对象
        console.log(bodyEle);
        console.dir(bodyEle);
  • 获取html元素
        var htmlEle = document.documentElement;//返回html元素对象
        console.log(htmlEle);

事件基础

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

简单理解:触发---相应机制

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

事件三要素

事件由三部分组成:事件源、事件类型、事件处理程序。

  • 事件源:事件被触发的对象,谁被点击---按钮
  • 事件类型:如何触发,什么事件,比如鼠标点击(onclick)还是鼠标经过或者是键盘按下。
  • 事件处理程序:通过一个函数赋值的方式完成。

案例:点击一个按钮,弹出对话框

    <button id="btn">按钮</button>
    <script>
        var btn = document.getElementById('btn');
        btn.onclick = function() {
            alert('弹出信息')
        }
    </script>

执行事件的步骤

  1. 获取事件源
  2. 注册事件(绑定事件)
  3. 添加事件处理程序(采取函数赋值形式)
        //1.获取事件源
        var div = document.querySelector('div');
        //2.绑定事件 注册事件--div.onclick
        //3.添加事件处理程序
        div.onclick = function() {
            console.log('我被点击了');
        }

常见的鼠标事件

鼠标事件触发条件
onclick鼠标点击左键触发
onmouseover鼠标经过触发
onmouseout鼠标离开触发
onfocus获得鼠标焦点触发
onblur失去鼠标焦点触发
onmousemove鼠标移动触发
onmouseup鼠标弹起触发
onmousedown鼠标按下触发

操作元素

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

改变元素内容

element.innerText

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

element.innerHTML

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

    <button>显示系统时间</button>
    <div>某个时间</div>
    <p>123</p>
    <script>
        var btn = document.querySelector('button');
        var div = document.querySelector('div');
        btn.onclick = function() {
            div.innerText = getDate();
        }

        function getDate() {
            var date = new Date();
            var year = date.getFullYear();
            var month = date.getMonth() + 1;
            var dates = date.getDate();
            var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
            var day = date.getDay();
            return '今天是:' + year + '年' + month + '月' + dates + '日' + arr[day];
        }
        //我们元素也可以不添加事件,但是会直接覆盖原内容
        var p = document.querySelector('p');
        p.innerText = getDate();
    </script>

innerTextinnerHTML的区别

  1. innerText不识别html标签,非标准
  2. innerHTML识别html标签,W3C标准
  3. 这俩个属性是可读写的,可以获取元素里面的内容。

修改元素属性

    <button id="btn1">111</button>
    <button id="btn2">222</button>
    <img src="111.jpg" alt="" title="111">
    <script>
        //修改元素属性 src
        //1.获取元素
        var btn1 = document.getElementById('btn1');
        var btn2 = document.getElementById('btn2');
        var img = document.querySelector('img');
        //注册事件,处理程序
        btn2.onclick = function() {
            img.src = '222.jpg';
            img.title = '222';
        }
        btn1.onclick = function() {
            img.src = '111.jpg';
            img.title = '111';
        }
    </script>

修改表单属性

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

typevaluecheckedselecteddisabled

    <button>按钮</button>
    <input type="text" value="请输入内容">
    <script>
        //1.获取元素
        var btn = document.querySelector('button');
        var input = document.querySelector('input');
        //2.注册事件处理程序
        btn.onclick = function() {
            // input.innerHTML = '点击了';  这个是普通盒子比如div标签里面的内容
            // 表单里面的值 文字内容是通过value来修改的
            input.value = '被点击了';
            //如果想要某个表单被禁用 不能再点击,disabled 
            //我们想要这个按钮button禁用
            //btn.disabled = true;
            this.disabled = true;
            //this 指向的是事件函数的调用者btn
        }
    </script>

修改样式属性

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

element.style    //行内样式操作
element.className    //类名样式操作

注意:

  1. JS里面的样式采取驼峰命名法,比如fontSize、backgroundColor
  2. JS修改style样式操作,产生的是行内样式,CSS权重比较高

使用element.style修改样式属性

如果样式比较少或者功能简单的情况下使用

    <style>
        div {
            width: 300px;
            height: 300px;
            background: red;
        }
    </style>
</head>

<body>
    <div></div>
    <script>
        //1.获取元素
        var div = document.querySelector('div');
        //2.注册事件处理程序
        div.onclick = function() {
            this.style.backgroundColor = 'blue';
            this.style.width = '250px';
            this.style.height = '250px';
        }
    </script>

使用className修改样式属性

适合于样式较多或者功能复杂的情况。

    <style>
        div {
            width: 100px;
            height: 100px;
            background: red;
        }
  
        .change {
            background-color: purple;
            color: #fff;
            font-size: 25px;
            margin-top: 100px;
        }
    </style>
</head>

<body>
    <div>文本</div>
    <script>
        //1.获取元素
        var div = document.querySelector('div');
        //2.注册事件处理程序
        div.onclick = function() {
            //让我们当前元素的类名改为了change
            this.className = 'change';
        }
    </script>


</body>
  1. 如果样式修改比较多,可以采取操作类名方式更改元素样式
  2. class因为是个保留字,因此使用className来操作元素类名属性
  3. className会直接更改元素的类名,会覆盖原先的类名

注意:如果想要保留原先的类名,可以选择多类名选择器

    this.className = 'first change';

操作元素总结

排他思想

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

  1. 所有元素全部清除样式(干掉其他人)
  2. 给当前元素设置样式(留下自己)
  3. 注意顺序不能颠倒,先干掉别人,再设置自己。

    <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() {
                //先把所有的按钮背景颜色去掉
                for (var i = 0; i < btns.length; i++) {
                    btns[i].style.backgroundColor = '';
                }
                //然后才让当前的背景颜色为pink
                this.style.backgroundColor = 'pink';
            }
        }
    </script>

自定义属性的操作

获取属性值

  • element.属性 获取属性值
  • element.getAttribute('属性') get得到获取 attribute属性
<body>
    <div id="demo"></div>
    <script>
        var div = document.getElementById('demo');
        //1.element.属性 获取属性值
        console.log(div.id); //demo
        //2.element.getAttribute('属性') 获取属性值
        console.log(div.getAttribute('id')); //deom
    </script>
</body>

区别:

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

element.getAttribute('属性') 主要获得自定义的属性(标准)我们自定义的属性

设置属性值

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

移除属性值

removeAttribute(属性) 移除属性值

        div.removeAttribute('index');

H5自定义属性

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

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

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

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

1.设置H5自定义属性

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

例:

或者使用JS设置:element.setAttribute('data-index',2)

2.获取H5自定义属性

  1. 兼容性获取 element.getAttribute('data-index');
  2. H5新增的方法:element.dataset.index 或者 element.dataset['index'] 其ie11才支持

dataset是一个集合,里面存放了所有以 data-开头的自定义属性,它只能获取 data-开头的。

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

节点操作

获取元素通常使用两张方式

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

  • document.getElementById()
  • document.getElementByTagName()
  • document.querySelector()
  • 逻辑性不强、繁琐

2.利用节点层级关系获取元素

  • 利用父子兄节点获取元素
  • 逻辑性强,但是兼容性稍差

这两种方式都可以获取元素节点,我但是节点操作更简单。

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

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

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

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

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

节点层级

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

1.父级节点

node.parentNode
  • parentNode属性可返回某节点的父节点,注意是最近的一个父节点
  • 如果指定的节点没有父节点则返回null
    <div class="demo">
        <div class="box">
            <span class="son">子</span>
        </div>
    </div>
    <script>
        var son = document.querySelector('.son')
        console.log(son.parentNode);//box
    </script>

2.子节点

parentNode.childNodes(标准)
  • 返回包含指定节点的子节点的集合,该集合为即使更新的集合。
  • childNode获得的是所有类型的子节点,包含元素节点、文本节点等,如果想要获得里面的元素节点,则需要专门处理,所以我们不提倡使用childNodes。
parentNode.children(非标准)

获取所有的子元素节点,也是我们实际开发常用的。

    <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
    <script>
        var uls = document.querySelector('ul');
        console.log(uls.children);
    </script>

第一个和最后一个子元素:

parentNode.firstChild

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

parentNode.lastChild

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

parentNode.firstElementChild

返回第一个子元素节点,找不到则返回null。IE9以上才支持。

parentNode.lastElementChild

返回最后一个子元素节点,找不到则返回null。IE9以上才支持。

实际开发中的解决方案,既没有兼容性问题又返回第一个子元素或最后一个元素。

        console.log(uls.children[0]);
        console.log(uls.children[uls.children.length - 1]);
End
最后修改:2022 年 05 月 14 日
如果觉得我的文章不错,请随手点赞~