0
点赞
收藏
分享

微信扫一扫

JavaScript DOM基础

猎书客er 2022-03-13 阅读 71

1. 基本概念

文档对象模型(Document Object Model, 简称DOM),是W3C组织推荐的处理可扩展标记语言(HTML或XML)的标准编程接口。可以改变页面的内容结构和样式。

DOM 里面的专有名词

DOM 树

在这里插入图片描述

  1. 文档 :一个页面就是一个文档,在DOM中用document表示
  2. 元素:页面中的所有标签都是元素,DOM中使用element表示
  3. 节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示
    DOM 把以上内容都看做对象

2. 获取页面元素

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

1. 根据ID获取元素

使用getElementById()方法获取

<div id="time">2022-3-10</div>
<script>
    // 1.因为页面文档从上往下加载,所以得先有标签,所以script要写到标签的下面
    // 2.参数 id 是大小写敏感的字符串
    var timer = document.getElementById('time');
    console.log(timer, typeof timer); // 3. 返回的是元素对象
    // 4.console.dir 打印我们返回的元素对象 更好的查看里面的属性和方法
    console.dir(timer);
</script>
2. 根据标签名获取

使用 getElementsByTagName()方法可以返回带有指定标签名的对象的集合

// 1. 返回的是 获取过来的元素对象的集合 以伪数组的形式存储的
var lis = document.getElementsByTagName('li');
console.log(lis);
console.log(lis[2]); //<li>hhhhhhhhh3</li>
// 2.采取遍历 依次打印里面的元素对象
for(var i = 0; i < lis.length; i++){
    console.log(lis[i]);
}
  • 返回的是 获取过来的元素对象的集合 以伪数组的形式存储的
  • 页面只有一个li或者没有li返回的依旧是伪数组形式
  • element.getElementsByTagName(‘标签名’) 可以获取某个元素(父元素)内部所有指定标签名的子元素。 注意:父元素 必须是单个对象,获取的时候不包括父元素自己
var ol = document.getElementsByTagName('ol');
console.log(ol[0].getElementsByTagName('li')); //注意获取单个父元素ol[0] (即使只有一个ol也要这么写,因为是伪数组)
// 常用写法 给ol加id
var ol = document.getElementById('ol');
console.log(ol.getElementsByTagName('li'));
3. 根据H5新增的方法获取

H5新增:只兼容ie9以上

  1. getElementsByClassName()根据类名获取元素集合
// 返回的是伪数组 getElementsByClassName
var boxs = document.getElementsByClassName('box');
console.log(boxs);  
  1. querySelector(‘选择器’) 根据指定选择器返回第一个元素对象(不分id标签类了,但里面的选择器要加对应符号)
// querySelector(‘选择器’) 根据指定选择器返回第一个元素对象(不分id标签类了)
var firstBox = document.querySelector('.box');
console.log(firstBox); 
var firstNav = document.querySelector('#nav');
console.log(firstNav);
  1. querySelectorAll(‘选择器’); 根据指定选择器返回对应的所有对象 也是伪数组
// querySelectorAll('选择器'); 根据指定选择器返回对应的所有对象
var allBox = document.querySelectorAll('.box');
console.log(allBox);  // 也是伪数组
4. 特殊元素获取(body,html)
  1. 获取body元素
    document.body 返回body对象
var bodyEle = document.body;
console.log(bodyEle);
  1. 获取HTML元素
    document.documentElement 返回html对象
var htmlEle = document.documentElement;
console.log(htmlEle);

3. 事件基础

JavaScript 使我们有能力创建动态页面,而事件是可以被JavaScript侦测到的行为
触发 – 响应机制
网页中的每个元素都可以产生某些可以触发JavaScript的事件,如,我们可以在用户点击某按钮时产生一个事件,然后去执行某些操作

事件三要素:事件源、事件类型、事件处理程序
执行事件的步骤

  1. 获取事件源
  2. 注册事件(绑定事件)
  3. 添加事件处理程序(采取函数赋值的方式)
<button id="btn">唐伯虎</button>
<div>123</div>
<script>
    // 点击div 控制台输出 我被选中了
    // 1. 获取事件源
    var divFirst = document.querySelector('div');  // 获取第一个div对象
    // 2. 注册(绑定)事件 divFirst.onclick  
    // 3. 添加事件处理程序  
    divFirst.onclick = function() {
        console.log('我被选中了');
    }
</script>

常见的鼠标事件
在这里插入图片描述

4.操作元素 (较核心)

1.改变元素内容

下面两个属性都是可读写的,可以获取里面的内容

  1. element.innerText : 从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去除。 非标准

  2. element.innerHTML : 从起始位置到终止位置的全部内容,包括html标签,保留空格和换行,和innerText最大区别 :能识别html标签,推荐使用这个。 W3C标准。

<!-- innerText 和innerHTML区别 -->
<div></div>
<p>
    我是文字
    <span>123</span>
</p>
<script>
    // 1.innerText 不识别html标签
    var div = document.querySelector('div');
    div.innerText = '<strong>今天是:</strong> 2022年';
    // 可读写 获取元素里的内容 会去除标签 空格和换行
    var p = document.querySelector('p');
    console.log(p.innerText);
    // 2.innerHTML 识别HTML标签
    div.innerHTML = '<strong>今天是:</strong> 2022年';
    // 可读写 获取元素里的内容 保留标签 空格和换行
    console.log(p.innerHTML);
</script>

demo – 获取当前系统时间 结合函数

<button>显示当前系统时间</button>
<div>某个时间</div>
<script>
    // 点击按钮 div里面的文字发生变化 innerText
    var buttonFirst = document.querySelector('button');
    var divFirst = document.querySelector('div');
    buttonFirst.onclick = function() {
        divFirst.innerHTML = getDate();
    }
    function getDate(){
        var timer = new Date(); // 当前的系统时间
        var year = timer.getFullYear();
        var month = timer.getMonth() + 1; //注意0-11 要手动+1
        month = addZero(month);
        var date1 = timer.getDate();
        date1 = addZero(date1);
        var hour = timer.getHours();
        hour = addZero(hour);
        var min = timer.getMinutes();
        min = addZero(min);
        var second = timer.getSeconds();
        second = addZero(second);
        var dayArr = ['日', '一', '二', '三', '四', '五', '六']
        var day = dayArr[timer.getDay()]; //getDay() 0-6 0是周日
        return '现在是:'+year+'年'+month+'月'+date1+'日星期'+day+'  '+hour+':'+min+':'
        +second;
    }
    function addZero(x){
        x = x < 10 ? '0' + x : x;
        return x;
    }
</script>

2. 常用属性操作

在这里插入图片描述
demo1 – src 点击不同的按钮 出现不同的图片 其他属性操作类似

<button>1111</button>
<button>2222</button>
<img src="../images/yexuan1.jpg" alt="">
<script>
    // 点击不同的按钮 出现不同的图片
    var btns = document.getElementsByTagName('button');
    var img = document.querySelector('img');
    btns[0].onclick = function() {
        img.src = '../images/yexuan1.jpg' 
    }
    btns[1].onclick = function() {
        img.src = '../images/yexuan2.jpg' 
    }
</script>

demo2 – 根据时间不同显示不同的问候语和图片

<!-- demo 分时显示不同图片和问候语 -->
<div>上午好</div>
<img src="../images/yexuan1.jpg" alt="">
<script>
    // 重点是 对当前时间的判断
    // 1. 获取元素
    var div = document.querySelector('div');
    var img = document.querySelector('img');
    // 2. 绑定事件 怎样用时间绑定呢?
    // 得到当前的小时数 使用分支语句实现事件处理程序
    var date = new Date();
    var h = date.getHours();
    if (h <= 5) {
        div.innerHTML = '晚上好,早点休息';
        img.src = '../images/yexuan1.jpg';
    } else if (h <= 12) {
        div.innerHTML = '上午好';
        img.src = '../images/yexuan2.jpg';
    } else if (h <= 18) {
        div.innerHTML = '下午好';
        img.src = '../images/yexuan3.webp';
    } else {
        div.innerHTML = '晚上好';
        img.src = '../images/yexuan4.webp';
    }
</script>
3. 表单元素的属性操作在这里插入图片描述
  • 表单里面的值不能通过innerHTML改变,而是通过value修改
  • 如果想要某个表单被禁用 不能再点击 使用disabled
4. 样式属性操作

通过js修改元素的大小、颜色、位置等样式

  1. element.style 行内样式操作 适用于要修改的样式少 功能简单的情况
  • js使用驼峰命名法 如: backgroundColor
  • js修改style样式操作,产生的是行内样式,css权重较高
<!-- 样式属性操作 -->
<div style="width: 100px; height: 100px; background-color: pink;"></div>
<script>
    var div = document.querySelector('div');
    div.onclick = function(){
        // 行内样式操作 element.style 注意js是驼峰命名法
        div.style.backgroundColor = 'purple';
        div.style.width = '50px';
    }
</script>
  • 表单属性事件 onfocus得到焦点 onblur 失去交掉
<!-- 表单属性事件 onfocus onblur -->
<input type="text" value="请输入" style="color: #999;">
<script>
    // 1. 获取元素
    var text = document.querySelector('input');
    // 2. 注册事件 获得焦点 onfocus
    text.onfocus = function() {
        // 判断是不是默认字 是就清空
        if (this.value === '请输入') {
            this.value = '';
        }
        // 获得焦点 把文字颜色变深 
        this.style.color = 'black';
    }
    // 注册事件 失去焦点 onblur
    text.onblur = function() {
        // 判断 表单是否为空 为空就恢复默认字
        if (this.value === ''){
            this.value = '请输入';
        }  
        // 失去焦点 把颜色变回#999
        this.style.color = '#999';
    }
</script>
  1. element.className 类名样式操作 适合于功能较多,样式复杂的情况
  • 样式修改较多,使用这种方法
  • class因为是个保留字,因此使用className来操作元素类名属性
  • className会直接更改元素的类名,会覆盖原先的类名
<!-- element.className -->
<div class="first"></div>
<script>
    var div = document.querySelector('div');
    div.onclick = function(){
        // 类名样式操做 element.className
        // 将需要修改的一系列样式全部修改到change上
        div.className = 'change';
        // 如果想要保留原先的格式 使用如下写法 多类名选择器
        div.className = 'first change';
    }
</script>
5. 排他思想

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

  1. 所有元素全部清除样式(干掉其他人)
  2. 给当前元素设置样式(留下我自己)
<!-- 排它思想 -->
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
    // 1.获取所有的按钮元素
    var btns = document.getElementsByTagName('button');
    // 2.注册事件 使用for循环给每个按钮注册点击事件
    for (var i = 0; i < btns.length; i ++) {
        btns[i].onclick = function() {
            // 排它思想:点击时,1.把其他背景颜色全部去除,2.给当前按钮设置背景色
            for (var j = 0; j < btns.length; j ++) {
                btns[j].style.backgroundColor = ''; 
            }
            this.style.backgroundColor = 'pink';
        }
    }
</script>
  1. 自定义属性的操作
    自定义属性:程序员自己添加的属性
    (1) 获取属性值:
  • element.属性
    获取内置属性值(元素本身自带的属性)
  • element.getAttribute(‘属性’)
    主要获得自定义的属性(程序员自定义)

(2)设置属性值

  • element.属性 = ‘值’ 设置内置属性
  • element.setAttribute(‘属性’, ‘值’) 设置自定义属性

(3)移除属性

  • element.removeAttribute(‘属性’)
  1. H5自定义属性–规范
    自定义属性的目的:为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。 但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。
    因此H5给我们新增了自定义属性:H5规定自定义属性以data- 开头作为属性名并且赋值
    H5新增获取自定义属性:element.dataset.属性名(如果自定义属性里有多个-链接的单词,那么js中要使用驼峰命名法获取) 兼容ie11,兼容性较差,所以目前一般使用getAttribute()方法

5. 节点操作

1.节点操作的目的

获取元素通常使用两种方法

  1. 使用DOM提供的方法获取,如document.getElementById()等方式。逻辑性不强,繁琐
  2. 利用节点的层次关系来获取元素,逻辑性强,但兼容性稍差
    这两种方法后面都会使用,但是节点操作更简单

节点
页面中所有的内容都是节点,在DOM中,节点使用node来表示。HTML DOM 树中的所有节点均可以通过JavaScript进行访问,所有HTML元素(节点)均可被修改,也可以创建或删除。
在这里插入图片描述

2.demo – 制作下拉列表

思路

  1. ​一个nav,无序列表构成
  2. 一个对应内容sub-nav, .nav>ul>li.sub-nav=ul>li
  3. 获取元素:(1).nav ul子元素li (2) .sub-nav 子元素ul
  4. 注册事件 执行操作 for循环遍历(1),鼠标经过(1),显示(2);鼠标移开(1)且鼠标移开(2) 隐藏(2);

代码实现

<!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>
        /* flex布局 */
        *{
            margin: 0;
            padding: 0;
        }
        a{
            text-decoration: none;
            color: black;
        }
        ul{
            list-style: none;
        }
        .nav{
            display: flex;
            justify-content: center;
        }
        .nav>li{
            position: relative;
            width: 80px;
            height: 60px;  
            line-height: 60px; 
            text-align: center;
            font-size: 20px;
        }
        .nav li .sub-nav{
            display: none;
            position: absolute;
            top: 60px;
        }
        .nav li .sub-nav li{
            width: 80px;
            height: 30px;  
            line-height: 30px; 
            font-size: 16px;
            text-align: center;
        }
    </style>
</head>
<body>
    <ul class="nav">
        <li>
            <a href="#">狸花猫</a>
            <ul class="sub-nav">
                <li>狸花猫</li>
                <li>狸花猫</li>
                <li>狸花猫</li>
                <li>狸花猫</li>
                <li>狸花猫</li>
            </ul>
        </li>
        <li>
            <a href="#">波斯猫</a>
            <ul class="sub-nav">
                <li>波斯猫</li>
                <li>波斯猫</li>
                <li>波斯猫</li>
                <li>波斯猫</li>
                <li>波斯猫</li>
            </ul>
        </li>
        <li>
            <a href="#">无毛猫</a>
            <ul class="sub-nav">
                <li>无毛猫</li>
                <li>无毛猫</li>
                <li>无毛猫</li>
                <li>无毛猫</li>
                <li>无毛猫</li>
            </ul>
        </li>
        <li>
            <a href="#">英短</a>
            <ul class="sub-nav">
                <li>英短</li>
                <li>英短</li>
                <li>英短</li>
                <li>英短</li>
                <li>英短</li>
            </ul>
        </li>
        <li>
            <a href="#">暹罗猫</a>
            <ul class="sub-nav">
                <li>暹罗猫</li>
                <li>暹罗猫</li>
                <li>暹罗猫</li>
                <li>暹罗猫</li>
                <li>暹罗猫</li>
            </ul>
        </li>
    </ul>
    <script>
        // 制作下拉列表
        // 1. ​一个nav,无序列表构成 .nav=ul>li
        // 2. 一个对应内容sub-nav, .nav=ul>li.sub-nav=ul>li
        // 3. 获取元素:(1).nav ul子元素li (2) .sub-nav 子元素ul
        // 4. 注册事件 执行操作 for循环遍历(1),鼠标经过(1),显示(2);鼠标移开(1) 隐藏(2);
        var nav = document.querySelector('.nav');
        lis = nav.children;  // 获取子元素
        for (var i = 0; i < lis.length; i ++){
            lis[i].onmouseover = function(){
                var subNav = this.children;  // 这个获取元素要写在里面,写在外面经过for循环不断更新,结果subNav只能是获取到最后一个子元素
                // console.log(subNav[1]);
                subNav[1].style.display = 'block';
            }
            lis[i].onmouseout = function() {
                var subNav = this.children;
                // console.log(subNav[1]);
                subNav[1].style.display = 'none';  
            }
        }
        
    </script>
</body>
</html>

效果呈现
在这里插入图片描述

3.demo – 制作留言板

思路
在这里插入图片描述

  1. 一个大盒子.leave-word装整个留言板块 一个.word-input框输入留言, 一个button控制发布留言, li添加留言
  2. 获取元素 .word-input button li
  3. 注册事件 button.onclick 点击发布
  4. 执行程序 添加元素li 先创建 document.createElement(‘li’) 再添加,保持最新评论置顶 parentNode.insertBefore(li, parentNode[2])

代码实现

<!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>
        *{
            margin: 0;
            padding: 0;
        }
        body{
            display: flex;
            justify-content: center;
        }
        .leave-word{
            margin-top: 100px;
        }
    </style>
</head>
<body>
    <div class="leave-word">
        <!-- 多行文本 -->
        <textarea name="留言框" id="word-input" cols="30" rows="10"></textarea>
        <button>发布</button>
        <ul>
            <li>111</li>
        </ul>
    </div>
    
    <script>
        // 1. 一个大盒子.leave-word装整个留言板块 一个.word-input框输入留言, 一个button控制发布留言, li添加留言
        // 2. 获取元素 .word-input  button li
        // 3. 注册事件 button.onclick  点击发布
        // 4. 执行程序 添加元素li 先创建 document.createElement('li') 再添加,保持最新评论置顶 parentNode.insertBefore(li, parentNode[2])
        var leaveWord = document.querySelector('.leave-word');
        var wordInput = leaveWord.children[0];
        var btn = leaveWord.children[1];
        var ul = leaveWord.children[2];
        // console.log(btn);
        btn.onclick = function() {
            // wordInput.innerText = '222'; // ?明明可以写入却无法读取
            // console.log(wordInput.innerText);  // ?就是说textarea里面的内容不可读取
            // console.log(wordInput.textContent);  // 好了 可以使用textContent读取
            // 判断 wordInput 是否为空 为空弹出,你并未输入内容,无法发布
            if(wordInput.value== ''){  // 好家伙 看了视频 居然是用value 前面全部推翻
                alert('您并未输入内容,无法发布留言。');
            } else{
                // 不为空 1.创建元素
                var li = document.createElement('li');
                li.innerHTML = wordInput.value;
                // 2.添加元素 使新添加的是内容始终保持置顶
                ul.insertBefore(li, ul.children[0]);
                // 3.添加成功后,清除留言框内容
                wordInput.value = '';
            }
        }
        
    </script>
</body>
</html>

效果呈现
在这里插入图片描述

举报

相关推荐

0 条评论