WebApis---DOM的初识及使用---二

244 阅读11分钟

事件

语法:btn:事件源:就是触发事件的dom元素

      btn.addEventListener('click', function() {
        console.log(123)
      })

addEventListener:事件监听机制提供的一个方法,通过它可以为元素绑定一个事件,并且在事件触发之后,调用指定的函数一定要进行处理

click事件类型,是指用户所进行的操作,click代表单击,说明用户必须单击指定的元素才会触发事件

function(){}:事件触发之后的处理函数

一:代码整体的意思是:我让事件监听机制帮我去监听用户是否进行某个操作,同时给它提供一个处理函数,告诉它,如果用户真的进行了这个操作,那么调用我给的函数进行处理。

二:1.开发者并不知道用户什么时候进行某个操作,谁知道?事件监听机制知道,但是它不知道应该如何处理

三:用户单击之后应该如何进行处理,开发者知道,但是我不知道用户是否单击了按钮

四:所以调用函数的并不是我,而是事件监听机制。

案例分享

单击关闭二维码

  <style>
    .erweima {
      position: relative;
      width: 160px;
      height: 160px;
      margin: 100px auto;
    }

    span {
      position: absolute;
      left: -20px;
      top: 0;
      display: block;
      width: 20px;
      text-align: center;
      border: 1px solid #ccc;
      /* 鼠标效果 */
      cursor: pointer;
    }
  </style>
</head>

<body>
  <div class="erweima">
    <img src="./images/code.png" alt="" />
    <span> X </span>
  </div>
  <script>
    let span = document.querySelector('span')
    let erweima = document.querySelector('.erweima')
    span.addEventListener('click', function () {
      // 关闭二维码
      erweima.style.display = 'none'
    })
  </script>
</body>

案例分享

随机点名

  <style>
    p {
      width: 200px;
      height: 100px;
      border: 1px solid red;
    }
  </style>
</head>
<body>
  <p>这里显示名字</p>
  <button class="start">开始随机点名</button>
  <button class="end">结束随机点名</button>
  <script>
    let names = [
      '彭',
      '徐',
      '温',
      '黄',
      '徐',
      '陈',
      '王'
    ]
    let p = document.querySelector('p')
    let start = document.querySelector('.start')
    let end = document.querySelector('.end')
    let timeId, index
    // 添加随机点名的效果
    start.addEventListener('click', function () {
      timeId = setInterval(function () {
        index = parseInt(Math.random() * names.length)
        p.innerHTML = names[index]
      }, 100)
    })
    // 结束本次点名
    end.addEventListener('click', function () {
      // 停止定时器
      clearInterval(timeId)
      // 删除指定的姓名
      names.splice(index, 1)
      // 判断是否需要禁用按钮
      if (names.length == 0) {
        start.disabled = true
        end.disabled = true
      }
    })
  </script>
</body>

事件的其它的绑定方式

let btn = document.querySelector('button')

btn.addEventListener('click',function(){})

on事件类型 onclick,onfocus,onblur,onmouseenter。。。

      btn.onclick = function() {
        console.log(123)
      }

常见的事件类型

按键事件

      username.addEventListener('keydown', function() {
        console.log('abc')
      })
      username.addEventListener('keyup', function() {
        console.log('1234')
      })

分别对应着键盘按键按下与弹起时触发的事件。

聚集事件

聚集事件:输入框获取焦点(光标)会触发聚集事件

      username.addEventListener('focus', function() {
        // console.log(123)
      })

失集事件:输入框失去焦点(光标)会触发失集事件

      username.addEventListener('blur', function() {
        // console.log(456)
      })

鼠标触发事件

      button.addEventListener('mouseenter', function() {
        ul.style.display = 'block'
      })
      button.addEventListener('mouseleave', function() {
        ul.style.display = 'none'
      })

分别对应鼠标悬停或离开时触发的事件。

其它事件类型

失焦事件

  // 失焦事件:只要失去焦点,就会触发
  // phone.addEventListener('blur', function() {
  //   console.log('blur')
  // })
  

失焦事件change

  // // 失焦事件change:失去焦点,同时内容变化 才会触发
  // phone.addEventListener('change', function() {
  //   console.log('change')
  // })
  

input事件

  // // 为输入框添加input事件,只要内容变化 就会触发
  // phone.addEventListener('input', function() {
  //   console.log(phone.value)
  // })
  

案例分享

需求1 "单击全选复选框,让列表中的所有复选框的状态和全选的一致

首先获取元素

      获取元素: 全选 -querySelector 列表中的所有复选框-querySelectorAll
      let chkAll = document.querySelector('#checkAll')
      let chks = document.querySelectorAll('.ck') // 伪数组,需要遍历使用
      let all = document.querySelector('.all') // 全选复选框对应的文本

为全选元素chkAll添加 click/change 事件,在事件处理函数中

      chkAll.addEventListener('click', function() {
        //   2.1 先获取全选复选框的checked状态:true/false
        let state = chkAll.checked
        //   2.2 遍历列表中的所有复选框,为其checked属性设置状态
        chks.forEach(function(ele, index) {
          ele.checked = state
        })
        //   2.3 修改文本内容
        all.innerHTML = state ? '取消' : '全选'
      })

需求2:单击列表中的复选框,影响 全选复选框

  • 1。经过本次单击,如果列表中的复选框全部选中,则全选也选中
    
  • 2。经过这次单击,如果列表中的复选框有一个没有选中,则全选也取消选中
    
    // 1.先为列表中所有复选框添加单击事件:遍历之后,一个一个绑定事件
    chks.forEach(function (ele, index) {
      // 为遍历出的复选框绑定事件
      ele.addEventListener('click', function () {
        // :checked:获取被选中的复选框
        let state = document.querySelectorAll('.ck:checked').length == chks.length
        chkAll.checked = state
        all.innerHTML = state ? '取消' : '全选'
      })
    })

方法二:

    // 1.先为列表中所有复选框添加单击事件:遍历之后,一个一个绑定事件
    chks.forEach(function (ele, index) {
      // 为遍历出的复选框绑定事件
      ele.addEventListener('click', function () {
        // 我先假设是被选中的
        chkAll.checked = true
        // 遍历列表中的所有复选框,但凡有一个没有选中,则全选也不选中,全部 选中了全选才选中
        chks.forEach(function (ele) {
          if (ele.checked == false) {
            chkAll.checked = false
          }
        })
        all.innerHTML = chkAll.checked ? '取消' : '全选'
      })
    })

案例分享--购物车加减操作

需求:用户点击加号,则文本框+1,点击减号,则文本框-1,如果文本框为1,则禁用减号

<body>
  <div>
    <input type="text" id="total" value="4" readonly />
    <input type="button" value="+" id="add" />
    <input type="button" value="-" id="reduce" />
  </div>
  <script>
    // 用户点击加号,则文本框+1,点击减号,则文本框-1,如果文本框为1,则禁用减号
    let add = document.querySelector('#add')
    let reduce = document.querySelector('#reduce')
    let total = document.querySelector('#total')
    // +
    add.addEventListener('click', function () {
      // 1.获取文本框的值
      let v = total.value
      // 2.自增: ++会自动的转换类型为数值
      v++
      // 3.重新赋值
      total.value = v
      // 重新启用减
      reduce.disabled = false
    })
    // -
    reduce.addEventListener('click', function () {
      // 1.获取文本框的值
      let v = total.value
      // 2.自减:--会自动的转换类型为数值
      v--
      // 3.重新赋值
      total.value = v
      // 如果值为1,则禁用按钮
      if (v == 1) {
        reduce.disabled = true
      }
    })
  </script>
</body>

this的使用介绍

  <script>
    let btns = document.querySelectorAll('button')
    btns.forEach(function (ele) {
      // 当前谁触发的事件,谁就是事件处理函数中的this
      // this是一个抽象对象
      ele.addEventListener('click', function () {
        console.log(this)
        // ele.style.color = 'red'
        this.style.color = 'red'
      })
    })
  </script>

排他思想

这是一种编成的思维。 可以理解为先取消所有的,清楚所有的,再拿到自己想要的。

有种置之死地而后生的感觉哈哈哈

案例分享

  <style>
    ul {
      list-style: none;
      width: 600px;
      display: flex;
      height: 50px;
    }
    li {
      flex: 1;
      background-color: #ccc;
      border-right: 1px solid blue;
      line-height: 50px;
      text-align: center;
    }
    .active {
      background-color: orange;
    }
  </style>
</head>
<body>
  <ul class="list">
    <li class="active">首页</li>
    <li>文章列表</li>
    <li>发表文章</li>
    <li>关于我们</li>
  </ul>

需求:

  • 1.单击li元素,在事件处理函数中
    
  • 1.1.先清除所有li元素的active样式
    
  • 1.2 为当前被单击的li元素添加active
    
    let lis = document.querySelectorAll('li')
    // 遍历,为每一个li元素绑定事件
    lis.forEach(function (ele) {
      ele.addEventListener('click', function () {
        // 先清除所有li元素的active样式:遍历,拿到每一个li元素,添加样式
        lis.forEach(function (subele) {
          // 清除所有li中的active
          subele.classList.remove('active')
        })
        // 为当前点击触发事件的元素添加active
        ele.classList.add('active')
        // ele.className = 'active'
      })
    })

上述案例优化写法,可以简化流程

      let lis = document.querySelectorAll('li')
      // 遍历,为每一个li元素绑定事件
      lis.forEach(function(ele) {
        ele.addEventListener('click', function() {
          // 找到当前有active样式的li元素,清除这个li元素的active样式
          // li.active:要求找到li元素,同时li元素有active样式 -- 交集选择器
          document.querySelector('.list > li.active').classList.remove('active')
          // 为当前被单击的li元素添加active
          ele.classList.add('active')
        })
      })

tab栏案例分享

页面静态结构

<div class="wrapper">
    <ul class="tab">
      <li class="tab-item active">国际大牌<span></span></li>
      <li class="tab-item">国妆名牌<span></span></li>
      <li class="tab-item">清洁用品<span></span></li>
      <li class="tab-item">男士精品</li>
    </ul>
    <div class="products">
      <div class="main active">
        <a href="###"><img src="imgs/guojidapai.jpg" alt="" /></a>
      </div>
      <div class="main">
        <a href="###"><img src="imgs/guozhuangmingpin.jpg" alt="" /></a>
      </div>
      <div class="main">
        <a href="###"><img src="imgs/qingjieyongpin.jpg" alt="" /></a>
      </div>
      <div class="main">
        <a href="###"><img src="imgs/nanshijingpin.jpg" alt="" /></a>
      </div>
    </div>
  </div>

tab栏效果图.png

最终需要实现上述效果,点击不同的分类,对应出相应的页面。利用排他思想

    // 获取元素
    let lis = document.querySelectorAll('.wrapper li')
    let mains = document.querySelectorAll('.products .main')
    // 伪数组的使用先遍历
    lis.forEach(function (ele, index) {
      ele.addEventListener('click', function () {
        // 排他li
        // 获取有active样式的li元素,干掉它的active样式
        document.querySelector('.wrapper li.active').classList.remove('active')
        // 为当前被单击的li元素添加active样式
        // lis[index].classList.add('active')
        ele.classList.add('active')
        // this.classList.add('active')
        console.log(index);
        // 排他main
        document.querySelector('.products .main.active').classList.remove('active')
        mains[index].classList.add('active')
      })
    })

案例分享

weibo发布案例

weibo案例效果图-字数动态.png

需要实现在文本域内输入内容的时候,下面的字数可以跟着响应相应的事件。

<body>
  <div class="w">
    <div class="controls">
      <img src="images/tip.png" alt="" /><br />
      <textarea placeholder="说点什么吧..." id="area" cols="30" rows="10" maxlength="200"></textarea>
      <div>
        <span class="useCount">0</span>
        <span>/</span>
        <span>200</span>
        <button id="send">发布</button>
      </div>
    </div>
    <div class="contentList">
      <ul></ul>
    </div>
  </div>
  <script>
    // 用户输入文字,可以计算用户输入的字数:input
    let area = document.querySelector('#area')
    let useCount = document.querySelector('.useCount')
    // 为文本域添加input内容改变事件
    area.addEventListener('input', function () {
      // 获取文本域的内容
      let content = area.value
      // 获取内容的长度
      let count = content.length
      // 将长度赋值 给批指定的元素
      useCount.innerHTML = count
    })
  </script>
</body>

题目及说明分享

第一题

1.下列有关 获取元素的方法 描述错误的是(B C )

  • A、document.getElementById方法会返回一个元素,如果获取不到元素,返回null
  • B、获取id为box的元素写法可以如下:document.querySelector(“box”)
  • C、document.querySelector方法无论有没有获取到元素,返回的都是伪数组
  • D、document.querySelectorAll 方法返回的是个伪数组

题目解析:

  • B:id类名获取需要添加“#”
  • C:querySelector方法获取的是满足条件的第一个元素,不是伪数组,所以D是对的

第二题

2.下列有关style属性 描述错误的是( D )

  • A、style属性操作的是元素的行内样式
  • B、设置背景图片写法:document.body.style.backgroundImage = “1.jpg”;
  • C、设置字体大小:document.body.style.fontSize = “20px”;
  • D、使用style设置比如字体大小font-size,背景颜色background-color等复合样式的时候,需要采用驼峰式写法

题目解析:

  • D、可以用小驼峰,也可以使用 ['font-size']['background-color']

第三题

3.关于DOM中获取元素的方法,下列说法正确的是 B

  • A、document.querySelector('.box') 是获取页面id为box的元素;
  • B、document.querySelector('.box') 是获取页面第一个类名为box的元素;
  • C、document.querySelectorAll('.box') 是获取页面所有id为box的元素;
  • D、document.querySelector('.box') 是获取页面所有类名为box的元素

题目解析:

  • A: 获取的是类名为“box”的第一个符合条件的元素
  • C: 获取的是类名为“box”的所有的符合条件的元素
  • D: 获取的是第一个符合条件的元素,不是所有。

第四题

4.关于innerText与innerHTML下列说法正确的是( D )

  • A、innerText与innerHTML作用完全一致,没有任何区别
  • B、innerText属性里设置的标签可以被解析
  • C、innerHTML获取内容的时候,如果内容中有HTML标签,标签会被忽略
  • D、innerHTML获取内容得到的是一个包含HTML标签的字符串

题目解析:

  • A、区别大了,一看就是错。innerHTML属性里设置的标签会被显示出来,形成完整的字符串
  • B、不可,是被浏览器页面解析,innerText只是获取了非标签的字符串
  • C、不会忽略,会形成字符串显示出来。

第五题

5.以下关于DOM的说法,错误的是( C )

  • A: DOM提供了操作浏览器界面元素的一套方法
  • B: DOM全称是文档对象模型,是将界面上的所有元素抽象成对象,使用对象的方式处理文档。
  • C: 使用DOM可以修改浏览器的地址栏。
  • D: 使用DOM可以获取到页面上的按钮

题目解析:

  • C: BOM才可以修改

第六题

6.请说明querySelectorquerySelectorAll的区别,你会分别在什么场合使用这两个方法呢?

题目解析:

  • querySelector 是用来获取第一个符合条件的元素的方法。

  • 而querySelectorAll 则可以获取所有符合条件的元素,并且形成一个伪数组。并不能直接使用。

  • 当只有一个元素需要被获取且使用的时候,使用querySelector

  • 而当需要批量选中元素的时候,使用querySelectorAll比较合适,但是获取的是伪数组,要遍历才可使用。这个要注意。

第七题

7、在代码中一个 box 变量对应界面上的一个 div,如下哪段代码可以将这个div的背景颜色设置成为红色( C )

  • A: box.className='red';
  • B: box.style.background-color='red';
  • C: box.style.backgroundColor='red';
  • D: 以上方法都可以实现

题目解析:

  • A: 这是修改元素内容的方式,并不能修改元素属性。
  • B: 其中background-color需要使用小驼峰命名法,或者添加中括号及引号。
  • backgroundColor['background-color']
  • D:骗谁呢,扯淡。

第八题

8.下列哪些方法可以获取到界面上所有的div( B E )

  • A: document.getElementsByClassName('div');
  • B: document.getElementsByTagName('div');
  • C: document.querySelectorAll('.div');
  • D: document.querySelector('div');
  • E: document.querySelectorAll('div')

题目解析:

  • A: ClassName是用来获取类名的,div是标签
  • C: 方法没错,但是选择上错了,用了类名选择方法选择了标签。
  • D: 选择没错,但是方法错了,这个方法只能获取第一个符合条件的元素。

第九题

9.下列有关 操作文本内容属性 描述错误的是( C )

  • A、innerText属性不能识别标签
  • B、使用innerHTML属性设置带标签的内容,标签可以起到效果
  • C、可以使用innerText属性来获取文本域中用户输入的内容
  • D、使用innerText和innerHTML在设置内容的时候都会覆盖原有内容

题目解析:

  • A:innerText 可以识别标签并剔除,只显示非标签内容形成字符串。
  • B:标签可以生效
  • C: 错了,百度如下,jq方法如下
  • 1.text()相当于innerText方法只能够获取到textarea的初始化文本值。
  • 2.html():相当于innerHTML
  • 2.val():value 方法不仅可以获取textarea的初始化文本值,当文本值改变时,也能正常获取到。
  • 3.textarea也属于表单元数

第十题

10.请简述className和classList的区别,同时能不能大致说说应用场景,或者能不能在举例的时候说明为什么使用其中一个呢?

  • className可以选择直接选择类名样式,引用到当前元素,但是会覆盖原先的类名样式,在明确知道此影响不会出问题的时候可以使用,例如自己敲的代码,可以考虑。
  • classList有四种常用的方法,分别如下。
  • classList.add (可以添加样式,可以选多个,并且是在之前的基础上添加的。不会照成覆盖。)
  • classList.remove (可以删除选中的样式,可以选多个。)
  • classList.toggle(可以理解为替换,只可以一次一个。如果本身就存在,就会删除该样式,如果不存在,则添加该样式上去)
  • classList.contains (是一种判断方法,判断该样式是否存在在该元素内,如果存在,则返回ture 如果不存在,返回false)

第十一题

11.当添加了定时器setInterval之后,代码会立刻执行。请问这句话是否正确呢?如果你认为不正确,说说理由哦!!

  • 错误的,立即执行的印象是因为设置的时间过短,从而忽略了时间。
  • 正确的逻辑是,先执行设置的时间,时间到了才开始执行内部函数代码。 例如:
  • setInterval(function(){代码内容},5000)
  • 页面加载完成后-等待五秒-执行代码内容-等待五秒-执行代码内容如此循环。

第十二题

12.有如下代码:doms.style.color = 'red'

  • 代码运行的时候有如下错误信息: Uncaught TypeError: Cannot read properties of null (reading 'style')

  • 这个错误信息传递了什么信息,你如何解决这个错误呢?重点说下你以后怎么避免这种错误呢?

  • 这个错误是指,无法读取null的属性(读取“style”)。

  • 我的理解是,获取流程是没问题的,不然会使undefined。而不是null

  • 产生这样的问题的原因是因为获取的过程中选择器并没有选中元素。

  • 解决问题就是重新判断选择器如何选中所需元素。

  • 为了避免这样的错误,要在获取元素前,将元素类名,静态结构,都写好,然后才开始获取元素,然后才是添加样式。

  • null是标签没有可以被选中的元素。

  • undefined的话是获取就出问题了,没有获取成功。