技术思考 【获取元素与样式操作】

345 阅读6分钟

获取元素的几种方式的详细解读

查找 DOM 元素就是选择页面中标签的元素。对于获取事件源(即获取元素), JavaScript 提供了很多种方法供程序员选择,其中我又把他们分为两类:重点掌握类与酌情了解类。

重点掌握类

  • querySelect()

    querySelect()是最常用的用于获取单个元素的方法。其特点为:

    1. 获取的是一个对象,可直接使用,无需其他操作。

          let btn = document.querySelector('button')
          btn.addEventListener('click', function() {
              console.log(1);
          })
      
    2. 获取到的是第一个元素,后面有再多符合条件的元素也不会被获取到(性质有点像 return

      <button>我会被获取到</button>
      <button>那我呢?</button>
      
      let btn = document.querySelector('button')
      console.log(btn);
      

      结果如下图所示。

      获取按钮.png

    3. 如果没有找到符合条件的元素,则会返回空值 null ,在后续用这个变量绑定事件类型触发事件会报错。

      let btn = document.querySelector('abc')
      console.log(btn);
      btn.addEventListener('click', function() {
          console.log(1);
      })
      

      结果如下所示。

      控制报错.png

      提示 “不能为空值绑定属性” 。因此以后看到这个错误记得获取看看有没有获取到事件源。

  • querySelectAll()

    querySelectALL()用于获取多个符合条件的元素,其特点如下:

    1. 获取到的是一个伪数组,伪数组的定义是有长度有索引号的数组,但没有 pop()push() 等数组的方法。

    2. 每个元素才是我们需要的数据源。因此直接为 querySelectALL() 方法获取到的伪数组绑定事件会报错。

          let btn = document.querySelectorAll('button')
          console.log(btn);
          btn.addEventListener('click', function() {
              console.log(1);
          })
      

      结果如下所示。

      伪数组报错.png

      提示 “ btn.addEventListener 不是一个函数”。 因此以后看到类似错误记得看看是不是用伪数组绑定事件。利用循环遍历的形式获取每个元素,这样才能操作修改。

      let btn = document.querySelectorAll('button')
          console.log(btn);
          btn.forEach(element => {
              console.log(element);
              element.addEventListener('click', function() {
                  console.log(1);
              })
          });
      

      结果如下图所示。

      遍历.png

    3. 哪怕只获取到一个值,返回的还是伪数组,只不过是存了一个元素的伪数组。如果没获取到值则返回空数组。

      let btn = document.querySelectorAll('a')
      console.log(btn);
      

      结果如下所示。

      空伪数组.png

酌情了解类

在最初的版本获取事件源的方法,现如今使用复杂,操作麻烦等原因不再广泛使用,作为了解即可。

  • getElementById()

    方法 getElementById() 通过 ID 进行获取相应的元素,参数是大小写敏感的字符串,返回的是一个字符串。

    <p id="red">我会被获取到</p>
    <p id="Red">那我呢?</p>
    
    let red = document.getElementById('red')
    red.style.color = 'red'
    

    结果如下所示。

    红.png

  • getElementByTagName()

    方法 getElementByTagName() 通过标签名获取。获取过来元素对象的集合,以伪数组的形式存储的,想要依次打印里面的元素对象可以采取遍历的方式。

    <ul>
    <li>daodao</li>
    <li>daodao</li>
    <li>daodao</li>
    <li>daodao</li>
    </ul>
    
    let ulli = document.getElementsByTagName('li');
    console.log(ulli); // 结果以数组的方式返回ul里所有li
    console.log(ulli[0]); // 结果以元素对象返回第一个li
    for (let i = 0; i < ulli.length; i++) {
        console.log(ulli[i]);
    }
    

    它的特性与 querySelectAll() 一致,如果没有值,则返回空数组。

  • getElementsByClassName()

    该方法通过类名来获取事件源,返回 HTMLCollection 类型的伪数组。

    解释:

    1. HTMLCollectionHTML 元素的集合。
    2. HTMLCollection 对象类似一个包含 HTML 元素的数组列表。 来源:菜鸟教程
    <div class="box">box1</div>
    <div class="box">box2</div>
    
    let clas = document.getElementsByClassName('box');
    console.log(clas); // HTMLCollection(2) [div.box, div.box]
    

总结

querySelect()querySelectAll() 的区别以及注意事项。

  • 区别

    1. querySelect() 只能选择第一个符合条件的元素,可直接操作。
    2. querySelectAll() 获取到多个符合条件的元素,返回的是一个伪数组,需遍历操作。
  • 注意事项

    1. 括号内写 CSS 选择器。
    2. 括号内必须是字符串,因此需要加引号。


样式操作 classNameclassList 的差异

className

方法 className 适用于修改样式较多的场景,与以前修改 style 的方法相比更简单高效。

语法为:

元素.className = '类名'

注意:

由于 class 是关键字,因此用 className 来替代。

但是 className 有一个最大的弊端,就是会覆盖掉以前的类名,无论多少类名,他都通通覆盖,只保留下我们赋予的。

    <button>改背景</button>
    <div class="divborder">我是内容</div>
        .divborder {
            border: 5px solid #ccc;
        }
        
        .mydiv {
            width: 400px;
            height: 400px;
            background-color: skyblue;
        }
        let btn = document.querySelector('button')
        let div = document.querySelector('div')

        btn.addEventListener('click', function() {
            div.className = 'mydiv'
        })

结果如下图所示。

classname.png 很明显,他把之前的类名给覆盖了,导致边框失效。

classList

方法 classList 就是为了解决 className 覆盖类名的问题而诞生的。classList 方法还有着追加、删除、切换、查询类名的功能。

<button>添加一个字体大小样式</button>
<button class="two">移除一个字体大小样式</button>
<button>切换一个字体大小样式</button>
<button>判断元素是否有某个样式</button>
<p class="red">我是百变p元素</p>
        .red {
            color: red;
        }
        
        .size50 {
            font-size: 50px;
        }
        
        .underline {
            text-decoration: underline;
        }

获取元素。

let btn1 = document.querySelector('button')
let btn2 = document.querySelector('.two')
let btn3 = document.querySelector('button:nth-of-type(3)')
let btn4 = document.querySelectorAll('button')[3]
let p = document.querySelector('p')
  • 追加

    btn1.addEventListener('click', function() {
            // 添加类名
            p.classList.add('size50')
    })
    
  • 删除

    btn2.addEventListener('click', function() {
         // 移除类名
         p.classList.remove('size50')
    })
    
  • 切换 切换类名的操作是该元素有这个类名则删除,没有则加上。

    btn3.addEventListener('click', function() {
        // 切换类名(有就删,没就加)
        p.classList.toggle('underline')
    })
    
  • 查询

    btn4.addEventListener('click', function() {
        // 检测类名,返回布尔值
        let flag = p.classList.contains('underline')
        console.log(flag);
    })
    

    结果最终返回的是布尔值,符合返回 true ,没有返回 false

总结

className 会把原类名覆盖, classList 不会覆盖,且有更多的操作,如添加、删除、切换、查询,使用更灵活,因此更推荐使用 classList 方法。



定时器的特性及应用

特性:定时器能够每隔一段时间自动执行一段代码,不需要我们手动去触发,因此适用于轮播图、倒计时、动画等场景。

应用:

  1. 开启定时器

    定时器的声明语法为:

    let timeId = setInterval(函数, 间隔时间)
    

注意:

  1. 每隔一段时间自动调用这个函数。
  2. 间隔时间的单位是毫秒。
  3. 声明定时器的变量名一般为 timeIdtimerIdtId
  1. 关闭定时器

语法为:

clearInterval(变量名)

一般会达到一定要求再关闭定时器。



错误类型总结

  1. Cannot read properties of null (reading 'addEventListener')

    获取不到 dom 元素而返回空值 null ,空值 null 不能操控样式 style ,因此报错。

    解决方法:回去看看获取事件源的代码是否正确。

  2. mya is not defined

    let a = document.querySelector(mya);
    a.style.color = 'red';
    

    变量还没声明就使用了。

    解决方法:括号内没加引号,当作变量看待,全局作用域中没有这个变量所以报错。要在括号内加上引号,变为字符串的格式。

  3. Cannot set properties of undefined (setting 'color')

    let myh2 = document.querySelectorAll('span')
    myh2.style.color = 'green'
    

    不能为 undefined 设置 color 属性。

    解决方法:直接用 querySelectorAll() 方法获取过来的伪数组设置样式,浏览器会解析成先在 myh2 伪数组中查找 style 这个属性方法,肯定找不到,因为它根本没这个方法,因此返回 underfined ,再用 underfined 设置 color 属性,因此报错。所以我们要先遍历再设置事件。