JS-Web-API 笔记

Posted ThinkerWing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS-Web-API 笔记相关的知识,希望对你有一定的参考价值。


一个完整的 javascript 实现是由以下 3 个不同部分组成的:

核心(ECMAScript)
文档对象模型(DOM)
浏览器对象模型(BOM)

JS-WEB-API

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

JS 基础知识

  • 变量的类型和计算
  • 原型和原型链
  • 作用域和闭包

JS-Web-API

DOM(document object model):文档对象模型,提供操作页面元素的方法和属性
比如文本、图片

BOM(browser object model);浏览器对象模型,提供一些属性和方法可以操作浏览器
比如浏览器的导航、跳转、地址

事件绑定 ;是给元素的某个行为绑定一个方法,目的是当事件行为触发的时候,可以做一些事情

ajax ; 是指一种创建交互式网页应用的网页开发技术。AJAX 是一种用于创建快速动态网页的技术。它可以令开发者只向服务器获取数据(而不是图片,html文档等资源)

存储 ; cookie、 Web Storage、 IndexedDB

DOM的本质是什么

题目

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

答案

  • 树(DOM 树)
  • DOM 节点操作
    DOM结构操作
    attribute 和 property
    https://www.cnblogs.com/clairexia/p/6635029.html
  • attribute 修改标签的属性 会改变html结构
    property修改js变量的属性 不会体现到html结构
    两者都可能引起 DOM 重新渲染
  • 对 DOM 查询做缓存
    将频繁操作改为一次性操作

知识点

  • DOM 本质
    HTML DOM 定义了访问和操作 HTML 文档的标准方法。DOM 将 HTML 文档表达为树结构。
  • DOM 节点操作
    ◇ 获取DOM 节点
const div1 = document.getElementById('div1')
console.log('div1', div1);

const divList = document.getElementsByTagName('div') // 集合
console.log('divList.length', divList.length);
console.log('divList[1]', divList[1]);

const containerList = document.getElementsByClassName('container')
console.log('containerList.length', containerList.length);
console.log('containerList[1]', containerList[1]);

const pList = document.querySelectorAll('p')
console.log('pList', pList);

◇ attribute

// 修改标签的属性 会改变html结构
p1.setAttribute('data-name', 'web')
console.log(p1.getAttribute('data-name'));
p1.setAttribute('style', 'font-size:50px;');

◇ property

// 修改js变量的属性 不会体现到html结构
p1.style.width = '100px'
console.log( p1.style.width ); // 100px
p1.className = 'red'
console.log( p1.className );
console.log(p1.nodeName);
console.log(p1.nodeType);

两者都可能引起 DOM 重新渲染

  • DOM 结构操作

◇ 新增/插入节点
◇ 获取子元素列表,获取父元素
◇ 删除子元素

const  div1 = document.getElementById('div1')
const  div2 = document.getElementById('div2')

// 新建节点
const newP = document.createElement('p')
newP.innerHTML = 'this is newP'
// 插入节点
div1.appendChild(newP)

// 移动节点
const p11 = document.getElementById('p1')
div2.appendChild(p11)

// 获取父元素
console.log( p11.parentNode );

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

div1.removeChild( div1ChildNodesP[0] )

  • DOM 性能
    ◇ DOM 操作是非常昂贵的,避免频繁的 DOM 操作
    ◇ 对 DOM 查询做缓存
// 不缓存 DOM 查询结果
for (let i= 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查询
}

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

const list = document.getElementById('list')

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

for (let i  = 0; i < 20; i++) {
    const li = document.createElement('li')
    li.innerHTML = `List item ${i}`

    // 先插入文档片段中
    frag.appendChild(li)
}

// 都完成之后,再统一插入到 DOM 结构中
list.appendChild(frag)

BOM相关的面试题

题目

  • 如何识别浏览器的类型
  • 分别拆解url各个部分

知识点

  • navigation
  • history
  • screen
  • location
// navigator
const ua = navigator.userAgent
const isChrome = ua.indexOf('Chrome')
console.log(isChrome);

// screen
console.log(screen.width);
console.log(screen.height);

// location
console.log(location.href); //"https://www.baidu.com/"
console.log(location.protocol);// "https:"
console.log(location.host); // "www.baidu.com"
console.log(location.pathname);
// pathname 属性是一个可读可写的字符串,可设置或返回当前 URL 的路径部分。
console.log(location.search)
console.log(location.hash)

// history
history.back()
history.forward()

事件

题目

  • 编写一个通用的事件监听函数
// 通用的绑定函数
function bindEvent(elem, type, fn) {
    elem.addEventListener(type, fn)
}

const btn1 = document.getElementById('btn1')
bindEvent(btn1, 'click', function (event) {
    // console.log(event.target) // 获取触发的元素
    event.preventDefault() // 阻止默认行为
    alert(this.innerHTML)
})

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)
        }
    })
}

  • 事件委托的原理(重)
    事件委托的原理:不给每个子节点单独设置事件监听器,而是设置在其父节点上,然后利用冒泡原理设置每个子节点。
    例如: 给 ul 注册点击事件,然后利用事件对象的 target 来找到当前点击的 li ,然后事件冒泡到 ul 上, ul 有注册事件,就会触发事件监听器。
    事件委托的作用
    只操作了一次 DOM ,提高了程序的性能。
    为什么要事件委托?(重)
    在JavaScript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的操作dom,那么引起浏览器重绘和回流的可能也就越多,页面交互的事件也就变的越长,这也就是为什么要减少dom操作的原因。每一个事件处理函数,都是一个对象,那么多一个事件处理函数,内存中就会被多占用一部分空间。如果要用事件委托,就会将所有的操作放到js程序里面,只对它的父级(如果只有一个父级)这一个对象进行操作,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能;

链接:https://juejin.cn/post/6965127548980166670

  • 描述事件冒泡的流程
    ◇ 基于 DOM 树形结构
    ◇ 事件会顺着触发元素往上冒泡
    ◇ 应用场景:代理
  • 无限下拉的图片列表,如何监听每个图片的点击
    ◇ 事件代理
    ◇ 用 e.target 获取触发元素
    ◇ 用 matches 来判断是否是触发元素

ajax

  • 题目
    ◇ 手写一个简易的 ajax
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 || xhr.status === 500) {
                    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.error(err))

◇ 跨域的常用实现方式
◆ 什么是跨域(同源策略)

  1. ajax 请求时,浏览器要求当前网页和server必须同源
  2. 同源:协议、域名、端口,三者必须一致
  3. 加载图片 css js 可无视同源策略
  4. 所有的跨域,都必须经过server端的允许和配合。未经server端允许就实现跨域,说明浏览器有漏洞,危险信号。

◆ JSONP

  1. JSONP原理
    利用 script标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的 JSON 数据。JSONP请求一定需要对方的服务器做支持才可以。
  2. JSONP和AJAX对比
    JSONP和AJAX相同,都是客户端向服务器端发送请求,从服务器端获取数据的方式。但AJAX属于同源策略,JSONP属于非同源策略(跨域请求)
  3. JSONP优缺点
    JSONP优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持get方法具有局限性,不安全可能会遭受XSS攻击。
  4. JSONP的实现流程
    声明一个回调函数,其函数名(如show)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)。
    创建一个script标签,把那个跨域的API数据接口地址,赋值给script的src,还要在这个地址中向服务器传递该函数名(可以通过问号传参:?callback=show)。
    服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是show,它准备好的数据是show(‘我不爱你’)。
    最后服务器把准备的数据通过HTTP协议返回给客户端,客户端再调用执行之前声明的回调函数(show),对返回的数据进行操作。

链接:https://juejin.cn/post/6844903767226351623
◆ CORS (服务端支持)

  • 知识点
    ◇ XMLHttpRequest
    ◇ 状态码
    ◇ 跨域:同源策略,跨域解决方案

存储

cookie、localStorage和sessionStorage 三者之间的区别以及存储、获取、删除等使用方式
https://juejin.cn/post/6844903516826255373

以上是关于JS-Web-API 笔记的主要内容,如果未能解决你的问题,请参考以下文章

前端知识体系-JS相关JS-Web-API总结

一文搞懂JS-Web-API——DOM

学习笔记:python3,代码片段(2017)

[原创]java WEB学习笔记61:Struts2学习之路--通用标签 property,uri,param,set,push,if-else,itertor,sort,date,a标签等(代码片段

sh bash片段 - 这些片段大多只是我自己的笔记;我找到了一些,有些我已经找到了

需要一种有效的方法来避免使用 Laravel 5 重复代码片段