前端JS面试题-JS Web Api

JS基础知识,只规定了语法(ECMA 262 标准)
JS Web Api,是网页操作的API(W3C标准)
前者时后者的基础,两者结合才能真正实际应用。

本文包括以下部分:

  • DOM
  • BOM
  • 事件绑定
  • Ajax
  • 存储

一、DOM

题目

  1. DOM是哪种数据结构
  2. DOM操作常用的API
  3. attr和property的区别
  4. 一次性插入多个DOM节点,考虑性能

1. DOM是哪种数据结构

树型结构 DOM树

2. DOM操作常用的API

分为两类: DOM 节点操作和 DOM 结构操作
参考知识点2和3

3. attr和property的区别

  • property:修改对象属性,不会体现到HTML结构中
  • attribute:修改HTML属性,会改变HTML结构【一定】
  • 两者都有可能引起DOM重新渲染
  • 尽量使用property,因为DOM渲染是比较耗费性能的

4. 一次性插入多个DOM节点,考虑性能

const listNode = document.getElementById('list')

// 创建一个文档片段,此时还没有插入到 DOM 树中
const frag = document.createDocumentFragment()

// 执行插入
for (let x = 0; x < 10; x++) {
  const li = document.createElement('li')
  li.innerHTML = 'list item ' + x
  frag.appendChild(li)
}

// 都完成之后,再插入到 DOM 树中
listNode.appendChild(frag)

知识点

1. DOM本质

  • XML是可扩展的标记性语言,可以描述任何结构的数据
  • HTML是特定的XML,规定了标签;结构和XML一致
  • DOM本身是一棵树

2. DOM节点操作

获取DOM节点

  • attribute
const pList = document.querySelectorAll('p')
const p = pList[0]
p.getAttribute('data-name')
p.getAttribute('data-name', 'imooc')
p.getAttribute('style')
p.getAttribute('style', 'font-size: 30px')
  • property
    以 js对象属性操作 的形式来操作DOM
const pList = document.querySelectorAll('p')
const p = pList[0]
p.style.width = '100px'
p.className = 'p1'
console.log(p.nodeName)
console.log(p.nodeType)

3. DOM结构操作

新增/插入节点

const div1 = document.getElementById('div1')
// 添加新节点
const p1 = document.createElement('p')
p1.innerHTML = 'this is p1'
div1.appendChild(p1)  // 添加新创建的元素
// 移动已有节点
const p2 = document.getElementById('p2')
div1.appendChild(p2)

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

// 获取父元素
console.log(p1.parentNode)
// 获取子元素列表
const div1ChildNodes = div1.childNodes
const div1ChildNodesP = Array.prototype.slice.call(div1.childNodes).filter(child => {
  if (child.nodeType === 1) {
    return true
  }
  return false
})
console.log('div1ChildNodesP', div1ChildNodesP)

删除节点

const div1 = document.getElementById("div1")
const child = div1.childNodes
div1.removeChild(child[0])

4. DOM性能

DOM操作非常“昂贵”,避免频繁的DOM操作
对DOM查询做缓存
将频繁操作改为一次性操作
DOM查询做缓存
前端JS面试题-JS Web Api
将频繁操作改为一次性操作
前端JS面试题-JS Web Api

二、BOM

题目

  1. 如何识别浏览器的类型
  2. 分析拆解url各个部分

1. 如何识别浏览器的类型

const ua = navigator.userAgent
const isChrome = ua.indexOf('Chrome')
console.log(isChrome)

2. 分析拆解url各个部分

location.href  // 整个网址
location.protocol  // 协议
location.host  // 域名
location.pathname  // 路径
location.search  // 常用参数
location.hash  // 哈希,# 后的内容

知识点

1. navigator

const ua = navigator.userAgent
const isChrome = ua.indexOf('Chrome')
console.log(isChrome)

2. screen

前端JS面试题-JS Web Api

3. location

location.href  // 整个网址
location.protocol  // 协议
location.host  // 域名
location.pathname  // 路径
location.search  // 常用参数
location.hash  // 哈希,# 后的内容

整个网址是由上面的信息拼接起来的

4. history

history.back()  // 后退
history.forward()  // 前进

三、事件

题目

  1. 编写一个通用的事件监听函数
  2. 描述事件冒泡的流程
  3. 无线下拉的图片列表,如何监听每个图片的点击

1. 编写一个通用的事件监听函数

注意代理问题 this问题

// 既支持普通绑定,也支持代理绑定
function bindEvent(elem, type, selector, fn) {
  // 可传入3个参数,也可传入4个参数
  if(fn == null){
    fn = selector
    selector = null
  }
  elem.addEventListener(type, event=>{
    const target = event.target
    if(selector){
      // 代理绑定
      if (target.matches(selector)) {
        fn.call(target, event)
      }
    }else{
      // 普通绑定
      fn.call(target, event)
    }
  })
}

2. 描述事件冒泡的流程

  • 基于 DOM 树型结构
  • 事件会顺着触发元素向上冒泡
  • 应用场景:代理

3. 无线下拉的图片列表,如何监听每个图片的点击

要点:

  • 事件代理
  • 用 e.target 获取触发元素
  • 用 matches 来判断是否是触发元素

知识点

1. 事件绑定

// 普通的事件绑定
const btn = document.getElementById('btn1')
btn.addEventListener('click', event=>{
	console.log('clicked')
})

// 较为通用的绑定函数
function bindEvent(elem, type, fn) {
  elem.addEventListener(type, fn)
}
const a = document.getElementById('link1')
bindEvent(a, 'click', e=>{
	e.preventDefault()  // 阻止默认行为
	alert('clicked')
})

2. 事件冒泡

3. 事件代理

事件代理参考
“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown......)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。

优点:

  • 代码简洁
  • 减少浏览器内存占用

但是,不要滥用;可以应用于瀑布流

// html
<div id="div3">
    <a href="#">a1</a><br>
    <a href="#">a2</a><br>
    <a href="#">a3</a><br>
    <a href="#">a4</a><br>
    <button>加载更多...</button>
</div>

// js
const div3 = document.getElementById('div3')
bindEvent(div3, 'click', event=>{
	event.preventDefault() // 阻止 a 的跳转的默认行为
	const target = event.target
	if(target.nodeName === 'A'){ // 判断是否是 a 标签
		alert(target.innerHTML)
	}
})

不好每个都挨个绑定事件,那么我们把事件绑定到父元素上,这就是事件代理。

四、Ajax

题目

  1. 手写一个Ajax,支持post get,支持404
  2. 跨域的常用实现方式

1. 手写一个Ajax,支持post get,支持404

2. 跨域的常用实现方式

  • jsonp
  • CORS(纯服务端)

知识点

1. XMLHttpRequest

XMLHttpRequest 对象用于在后台与服务器交换数据。并且可以

  • 在不重新加载页面的情况下更新网页
  • 在页面已加载后从服务器请求数据
  • 在页面已加载后从服务器接收数据
  • 在后台向服务器发送数据
    所有现代的浏览器都支持XMLHttpRequest对象。
    以下给出 get 请求和 post 请求。
// get 请求
const xhr = new XMLHttpRequest()
xhr.open('GET', 'data/test.json', true)
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {
    if(xhr.status === 200) {
      console.log(
        alert(xhr.responseText)
    }
  }
}
xhr.send(null)

// post 请求
const xhr = new XMLHttpRequest()
xhr.open('POST', '/login', true)
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {
    if(xhr.status === 200) {
      console.log(
        alert(xhr.responseText)
    }
  }
}
const postData = {
	userName: 'zhangdan',
	password: 'xxx'
}
xhr.send(JSON.stringify(postData))

2. 状态码

readyState

  • 0 (未初始化)还没有调用sell()方法
  • 1(载入)已调用sell()方法,正在发送请求
  • 2(载入完成)sell()方法执行完成,已经接收到全部响应内容
  • 3(交互)正在解析响应内容
  • 4(完成)响应内容解析完成,可以在客户端调用。所以能在客户端判断的readyState的值只能是4

responseStatus

  • 2xx 表示成功处理请求,如200
  • 3xx 需要重定向,浏览器直接跳转,如301 302 304
  • 4xx 客户端请求错误,如404 403
  • 5xx 服务器端错误

3. 跨域

同源策略

  • ajax 请求时,浏览器要求当前网页和server必须同源(安全)
  • 同源:协议、域名、端口,三者必须一致
  • 前端
  • 加载图片 CSS js 可以无视同源策略
    • <img src=跨域的图片地址> // 可用于统计打点,可使用第三方统计服务
    • <link herf=跨域的css地址>
      <script src=跨域的js地址></script> // link script 可使用CDN,CDN一般都是外域 script 可实现JSONP
  • 跨域
    • 所有的跨域,都必须经过server端允许和配合
    • 未经server端允许就实现跨域,说明浏览器有漏洞,危险信号

跨域解决方案(待整理)

  • JSONP
  • CORS

五、存储

题目

  1. 描述cookie localStorage sessionStorage 区别
    从以下三方面来进行描述:
  • 容量
  • API易用性
  • 是否跟随HTTP请求发送出去

知识点

  • 本身用于浏览器和server通讯
  • 被“借用”到本地存储来
  • 可用 document.cookie = '...' 来修改 追加的过程,不是覆盖的过程 同一个key是覆盖,不同的key是追加

前端JS面试题-JS Web Api
cookie 的缺点

  • 存储大小,最大为4KB
  • http请求时需要发送到服务端,增加请求数据量
  • 只能用 document.cookie = '...' 来修改,太过简陋
  • 本身是来进行通信的,不是用来存储的

2. localStorage sessionStorage

  • HTML5专门为存储而设计,对于每个域名来说最大可存5M
  • API简单易用 setItem getItem
  • 不会随着http请求被发送出去
  • 强制类型转换成字符串形式

前端JS面试题-JS Web Api

两者区别

  • localStorage 数据会永久存储,除非代码或手动删除
  • sessionStorage 数据只存在于当前会话,浏览器关闭则清空
  • 所以,我们一般使用 localStorage
上一篇:Ajax


下一篇:原生ajax的封装