JS Web API

43 阅读2分钟

DOM

DOM

  • Document Object Model
  • 是JS能识别的html结构
  • 树结构

DOM节点操作

  • 获取DOM节点
    • getElementById
    • getElementsByTagName
    • getElementsByClassName
    • querySelectorAll
  • property
    • style
    • className
    • nodeName
    • nodeType
  • attribute
    • getAttribute
    • setAttribute
  • property和attribute区别
    • property修改对象属性,不会体现到html结构中
    • attr修改html属性,会改变html结构
    • 两者都可能引起DOM重新渲染

DOM结构操作

  • 新增/插入节点
    • createElement
    • appendChild
  • 获取子元素列表,获取父元素
    • parentNode
    • childNodes
  • 删除节点
    • removeChild

DOM性能

  • DOM操作非常“昂贵”,避免频繁的DOM操作
  • 对DOM查询做缓存
// 不缓存 DOM 查询结果
for (let = 0; i < document.getElementsByTagName('p').length; i++) {
    // 每次循环,都会计算 length ,频繁进行 DOM 查询
}

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

将频繁操作改为一次性操作(插入多个标签时,先插入 Fragment 然后再统一插入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)

事件

事件代理

  • 就是利用事件冒泡或者事件捕获机制,把一系列内层元素事件绑定到外层元素
  • 有点
    • 使代码简洁
    • 减少浏览器内存占用
    • 但是,不要滥用
function bindEvent(elem, type, selector, fn) {
    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)
      }
    })
  }
  const div3 = document.getElementById("div3");
  bindEvent(div3, "click", "a", function (event) {  // 注意,这里不可用箭头函数
    event.preventDefault();
    alert(this.innerHTML)
  })

Ajax

XMLHttpRequest

function ajax(url) {
  const p = new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          resolve(
            JSON.parse(xhr.responseText)
          )
        } else if (xhr.status === 404) {
          reject(new Error("404 not found"))
        }

      }
    }
    xhr.send(null)
  })
  return p
}
const url = "/data/test.json";
ajax(url)
  .then(res => console.log(res))
  .catch(err => console.log(err))

跨域

什么是跨域

  • ajax请求时,浏览器要求当前网页必须和server同源
  • 同源:协议、域名、端口,三者必须一致

加载图片,css,js可无视同源策略

跨域

  • 所有的跨域,都必须经过server端允许
  • 未经server端允许就实现跨域,说明浏览器有漏洞

JSONP

  • script可绕过跨域
  • 服务器可任意动态拼接数据返回
  • 所以,script就可以获得跨域的数据,只要服务器端愿意返回

CORS

  • 服务器端设置http header

存储

cookie

  • 用于浏览器和server通讯
  • 被借用到本地存储来
  • 可用document.cookie=""来修改
  • 缺点
    • 存储太小,最大4KB
    • http请求时,会发送到服务端,增加请求数据量
    • 只能用document.cookie来修改,太过简陋 localStorage与sessionStorage
  • html5专门为存储设计的,最大可存5M
  • API简单易用
  • 不会随着http请求发送出去
  • 区别
    • localStorage数据永久存储,除非手动或者代码删除
    • sessionStorage数据只存在于当前会话,浏览器关闭则清空