web前端面试高频考点——JavaScript-Web-API 篇(一)DOM、BOM、事件

电玩女神 2023-09-28 18:45 69阅读 0赞

系列文章目录

JavaScript 知识梳理,收录了web前端面试 95%以上 的高频考点,满满的干货。给你做一个高效的知识梳理,为你的面试保驾护航!










































内容 参考链接
HTML & CSS 篇 HTML & CSS 篇
JavaScript 篇(一) JavaScript 篇(一)【JS的三座大山 】原型和原型链、作用域和闭包、异步
JavaScript 篇(二) JavaScript 篇(二)【JS 异步进阶】
JavaScript-Web-API 篇(一) JavaScript-Web-API 篇(一)DOM、BOM、事件
JavaScript-Web-API 篇(二) JavaScript-Web-API 篇(二)AJAX、存储
HTTP 篇 HTTP 篇
性能优化篇 性能优化篇(手写防抖、手写节流、XXS攻击、XSRF攻击)
经典面试题-JS篇 经典面试题 HTML、CSS、JavaScript篇

文章目录

  • 系列文章目录
  • JS-Web-API-DOM
    • DOM 节点操作
      • 获取 DOM 节点
      • DOM 节点的 property 和 attribute
    • DOM 结构操作
      • 新增、插入、移动节点
      • 获取子元素列表 & 获取父元素
      • 删除子元素
    • 如何优化 DOM 操作的性能
      • DOM 查询做缓存
      • 将频繁操作改为一次性操作
  • JS-Web-API-BOM
    • BOM 操作相关面试题
      • navigation 和 screen
      • 拆解 url 各部分
  • JS-Web-API-事件
    • 事件绑定
    • 事件冒泡
    • 事件代理
    • 通用事件绑定函数(考虑代理)

JS-Web-API-DOM

DOM 节点操作

获取 DOM 节点

  • document.getElementById():返回对拥有指定 id 的第一个对象的引用。
  • document.getElementsByTagName():返回带有指定标签名的对象集合。
  • document.getElementsByClassName():返回一个包含了所有指定类名的子元素的类数组对象。
  • document.querySelectorAll():返回与指定的选择器组匹配的文档中的元素列表 (使用深度优先的先序遍历文档的节点)。返回的对象是 NodeList 。

示例:获取 DOM 节点的 Demo

  1. <div id="div1" class="container">
  2. <p>一段文字</p>
  3. <p>一段文字</p>
  4. <p>一段文字</p>
  5. </div>
  6. <div id="div2" class="container">
  7. <img src="./code.png">
  8. </div>
  9. const div1 = document.getElementById('div1')
  10. console.log('div1', div1)
  11. const divList = document.getElementsByTagName('div')
  12. console.log('divList.length', divList.length)
  13. console.log('divList[1]', divList[1])
  14. const containerList = document.getElementsByClassName('container')
  15. console.log('containerList.length', containerList.length)
  16. console.log('containerList[1]', containerList[1])
  17. const pList = document.querySelectorAll('p')
  18. console.log('pList', pList)

在这里插入图片描述

DOM 节点的 property 和 attribute

  • property:修改对象属性,不会体现到 html 结构中
  • attribute:修改 html 属性,会改变 html 结构
  • 两者都有可能引起 DOM 的重新渲染

示例 1:property 修改对象属性(推荐使用)

  1. .container {
  2. border: 1px solid #ccc;
  3. }
  4. .red {
  5. color: red;
  6. }
  7. <div id="div1" class="container">
  8. <p>一段文字1</p>
  9. <p>一段文字2</p>
  10. <p>一段文字3</p>
  11. </div>
  12. // property 形式
  13. const pList = document.querySelectorAll('p')
  14. const p1 = pList[0]
  15. p1.style.width = '100px'
  16. console.log(p1.style.width)
  17. p1.className = 'red'
  18. console.log(p1.className)
  19. console.log(p1.nodeName)
  20. console.log(p1.nodeType)

在这里插入图片描述

示例 2:attribute 修改 html 属性

  1. .container {
  2. border: 1px solid #ccc;
  3. }
  4. .red {
  5. color: red;
  6. }
  7. <div id="div1" class="container">
  8. <p>一段文字1</p>
  9. <p>一段文字2</p>
  10. <p>一段文字3</p>
  11. </div>
  12. // attribute
  13. const pList = document.querySelectorAll('p')
  14. const p1 = pList[0]
  15. p1.setAttribute('data-name', 'imooc')
  16. console.log(p1.getAttribute('data-name'))
  17. p1.setAttribute('style', 'font-size: 30px;')
  18. console.log(p1.getAttribute('style'))

在这里插入图片描述

在这里插入图片描述

DOM 结构操作

新增、插入、移动节点

  • 新增节点:createElement
  • 插入节点:appendChild
  • 移动节点:已有的节点插入到别的容器就会发生移动

示例:

  1. <div id="div1" class="container">
  2. <p id="p1">一段文字1</p>
  3. <p>一段文字2</p>
  4. <p>一段文字3</p>
  5. </div>
  6. <div id="div2" class="container"></div>
  7. const div1 = document.getElementById('div1')
  8. const div2 = document.getElementById('div2')
  9. const newP = document.createElement('p')
  10. // 新建节点
  11. newP.innerHTML = '新增的一段文字'
  12. // 插入节点
  13. div1.appendChild(newP)
  14. // 移动节点
  15. const p1 = document.getElementById('p1')
  16. div2.appendChild(p1)

在这里插入图片描述

获取子元素列表 & 获取父元素

  • parentNode:父元素
  • childNodes:子元素
  • removeChild:删除子元素

示例 1:div1ChildNodes 不是数组,需要Array.from() 转为数组

  1. <div id="div1" class="container">
  2. <p id="p1">一段文字1</p>
  3. <p>一段文字2</p>
  4. <p>一段文字3</p>
  5. </div>
  6. const div1 = document.getElementById('div1')
  7. // 获取父元素
  8. console.log(p1.parentNode)
  9. // 获取子元素列表
  10. const div1ChildNodes = div1.childNodes
  11. console.log(div1.childNodes)
  12. const divChildNodesP = Array.from(div1ChildNodes).filter(child => {
  13. if(child.nodeType === 1) {
  14. return true
  15. }
  16. return false
  17. })
  18. console.log('divChildNodesP', divChildNodesP)

在这里插入图片描述

删除子元素

示例:在上文的基础上进行删除子元素

  1. div1.removeChild(divChildNodesP[0])

在这里插入图片描述

如何优化 DOM 操作的性能

DOM 查询做缓存

  • 做缓存,先接收所有的 length,避免循环的时候重复操作 DOM

示例 1:

  1. // 不缓存 DOM 查询结果
  2. for(let i = 0; i < document.getElementsByTagName('p').length; i++) {
  3. // 每次循环,都会计算 length,频繁进行 DOM 查询
  4. }

示例 2:

  1. // 缓存 DOM 查询结果
  2. const pList = document.getElementsByTagName('p')
  3. const length = pList.length
  4. for(let i = 0; i < length; i++) {
  5. // 缓存 length,只进行一次 DOM 查询
  6. }

将频繁操作改为一次性操作

  • 创建文档片段,把循环的内容先插入到文档片段中

示例 1:频繁的 DOM 操作

  1. <ul id="list"></ul>
  2. const list = document.getElementById('list')
  3. for(let i = 0; i < 10; i++) {
  4. const li = document.createElement('li')
  5. li.innerHTML = `List item ${
  6. i}`
  7. list.appendChild(li)
  8. }

示例 2:创建文档片段

  1. <ul id="list"></ul>
  2. const list = document.getElementById('list')
  3. // 创建一个文档片段,此时还没有插入到 DOM 树中
  4. const frag = document.createDocumentFragment()
  5. // 执行插入
  6. for(let i = 0; i <= 10; i++) {
  7. const li = document.createElement('li')
  8. li.innerHTML = `List item ${
  9. i}`
  10. // 先插入文档片段中
  11. frag.appendChild(li)
  12. }
  13. // 都完成之后,再统一插入到 DOM 树中
  14. list.appendChild(frag)

在这里插入图片描述

JS-Web-API-BOM

BOM 操作相关面试题

navigation 和 screen

  • navigation.userAgent:浏览器用于 HTTP 请求的用户代理头的值
  • screen.width:屏幕宽度
  • screen.height:屏幕高度
    在这里插入图片描述

拆解 url 各部分

  • location.href:返回完整的URL
  • location.protocol:返回一个URL协议
  • location.host:返回一个URL的主机名和端口
  • location.search:返回一个URL的查询部分
  • location.hash:返回一个URL的锚部分
  • location.pathname:返回的URL路径名。
    在这里插入图片描述

JS-Web-API-事件

事件绑定

示例:通用事件绑定函数

  1. <button id="btn1">一个按钮</button>
  2. function bindEvent(elem, type, fn) {
  3. elem.addEventListener(type, fn)
  4. }
  5. const btn1 = document.getElementById('btn1')
  6. bindEvent(btn1, 'click', event => {
  7. console.log(event.target) //
  8. alert('clicked')
  9. })

在这里插入图片描述

事件冒泡

  • 基于 DOM 树形结构
  • 事件会顺着触发元素往上冒泡
  • 应用场景:代理
  • stopPropagation:用于阻止事件冒泡


    激活


    取消


    取消


    取消




    取消


    取消


    1. function bindEvent(elem, type, fn) {
    2. elem.addEventListener(type, fn)
    3. }
    4. const p1 = document.getElementById('p1')
    5. const body = document.body
    6. bindEvent(p1, 'click', event => {
    7. event.stopPropagation() // 阻止冒泡
    8. console.log('激活')
    9. })
    10. bindEvent(body, 'click', event => {
    11. console.log('取消')
    12. })

不阻止冒泡,点击激活会冒泡到取消:

在这里插入图片描述

阻止冒泡,点击激活不会冒泡:

在这里插入图片描述

事件代理

  • 代码更简洁
  • 减少浏览器内存占用
  • 但是,不要滥用
  • 对于复杂,不好去每个都绑定事件的时候使用

示例:元素 a 把事件处理委托给自己的父元素 div 去处理

  1. <div id="div1">
  2. <a href="#">a1</a>
  3. <a href="#">a2</a>
  4. <a href="#">a3</a>
  5. <a href="#">a4</a>
  6. <button>加载更多...</button>
  7. </div>
  8. function bindEvent(elem, type, fn) {
  9. elem.addEventListener(type, fn)
  10. }
  11. const div1 = document.getElementById('div1')
  12. bindEvent(div1, 'click', event => {
  13. event.preventDefault() // 阻止页面跳转
  14. const target = event.target
  15. if(target.nodeName === 'A') {
  16. alert(target.innerHTML)
  17. }
  18. })

点击 a1-4 会弹出对话框,点击按钮则不会:

在这里插入图片描述

通用事件绑定函数(考虑代理)

  • fn 不能是箭头函数,箭头函数无法被 call

    1. <a href="#">a1</a>
    2. <a href="#">a2</a>
    3. <a href="#">a3</a>
    4. <a href="#">a4</a>
    5. <button>加载更多...</button>
    6. </div>
    7. <button id="btn1">点击</button>
    8. // 通用事件绑定函数
    9. function bindEvent(elem, type, selector, fn) {
    10. // 如果传入三个参数,把 selector 赋值给 fn,selector 置空
    11. if (fn == null) {
    12. fn = selector
    13. selector = null
    14. }
    15. elem.addEventListener(type, event => {
    16. const target = event.target
    17. if (selector) {
    18. // 代理绑定
    19. if (target.matches(selector)) {
    20. fn.call(target, event)
    21. }
    22. } else {
    23. // 普通绑定
    24. fn.call(target, event)
    25. }
    26. })
    27. }
    28. // 普通绑定
    29. const btn1 = document.getElementById('btn1')
    30. bindEvent(btn1, 'click', function(event) {
    31. event.preventDefault()
    32. alert(this.innerHTML)
    33. })
    34. // 代理绑定
    35. const div1 = document.getElementById('div1')
    36. bindEvent(div1, 'click', 'a', function (event) {
    37. event.preventDefault()
    38. alert(this.innerHTML)
    39. })

点击 a1-4 会弹出对话框,点击按钮则不会:

在这里插入图片描述

不积跬步无以至千里 不积小流无以成江海

点个关注不迷路,持续更新中…

发表评论

表情:
评论列表 (有 0 条评论,69人围观)

还没有评论,来说两句吧...

相关阅读