高级JSJavaScript前端基础

常用浏览器API整理

2021-08-21  本文已影响0人  z_hboot

面向对象编程,目前还是主流,个人也比较喜欢细化组件、切割对象.这样看起来比较清晰、每个对象职责单一,不会混淆造成混乱.

前端经常会和浏览器打交道,在处理一些与浏览器相关的逻辑时,就会调用浏览器API,整理日常会用到的API对象.

URL

构造、解析、规范化和编码URL.

创建URL对象

构造参数说明


// 指定绝对ULR地址

const url = new URL('http://www.baidu.com')

// 或者

const url = new URL('','http://www.baidu.com')

// 存在路径时

const url = new URL('http://www.baidu.com/hello')

// 或

const url = new URL('/hello','http://www.baidu.com')

构造完的url实例对象有哪些属性呢 , 可以从图中获取该url地址中所有的数据信息:

origin\searchParams 为只读属性 , 其他的属性则可以通过变量赋值进行设置.

image-20210821141202812.png

修改相关属性:


// 修改协议

url.protocol = "ftp:"        // href: 'ftp://www.baidu.com/hello',

// 修改路径

url.pathname = '/admin'      // href: 'ftp://www.baidu.com/admin',

// 追加hash

url.hash = 'app'            // href: 'ftp://www.baidu.com/admin#app',

实例方法

以为有啥不一样的地方,发现都是返现url地址.

还有静态方法,创建一个唯一的资源地址链接:


// File 对象,或者blob数据

const dataUrl = URL.createObjectURL('blob:**')

// 销毁创建的实例 , 访问失效

URL.revokeObjectURL(dataUrl)

URLSearchParams 对象

这个应该是我们经常会用到的,用于处理url的查询字符串.

在实例url中,存在searchsearchParams(只读)


// url实例追加一个查询条件

url.search = 'id=45'

// 重新读取时会包含 ? 注意

console.log(url.search)      // ?id=45

// 获取实例URL的查询参数对象

const searchParams = url.searchParams

创建实例

const searchParams = new URLSearchParams()

// ?id=45

const searchParams = new URLSearchParams("?id=45")    // { 'id' => '45' }

// id=45&name=admin

const searchParams = new URLSearchParams("id=45&name=321")    // { 'id' => '45', 'name' => '321' }

// [['id',45],['name','admin']]

const searchParams = new URLSearchParams([['id',45],['name',"admin"]])

// {'id':45,'name':'admin'}

const searchParams = new URLSearchParams({'id':45,'name':'admin'})

实例化的好处在于可以方便管理,比如添加、删除、查找等,通过实例方法很方便的管理数据.

实例方法

const searchParams = new URLSearchParams()

// 追加一个参数

searchParams.append("id","sv2341")      // { 'id' => 'sv2341' }

// 判断是否包含某个参数

searchParams.has("name")          // false

// 获取指定参数的值

searchParams.get("id")              // sv2341

// 获取所有参数的值

[...searchParams.values()]        // ['sv2341']

//

searchParams.toString();        //.

处理URL地址参数

不需要自己再去分隔字符串处理查询参数了,通过searchParams对象优雅处理查询参数,方便多了.


// 获取实例URL的查询字符串对象

const searchParams = url.searchParams

// 追加一个name查询参数

searchParams.append('name','admin')        // href: 'ftp://www.baidu.com/admin?id=45&name=admin#app',

如果是实例化的新的URLSearchParams , 则复制给url对象属性search


const url = new URL('http://www.baidu.com/hello')

// 新实例化的对象

const searchParams = new URLSearchParams()

searchParams.append("id","sv2341")

searchParams.append("name","test")

// 设置查询参数

url.search = searchParams            // href: 'http://www.baidu.com/hello?id=sv2341&name=test',

无法处理hash与pathname的位置顺序

让人头疼的是hashpathname 的位置,hash设置总是在pathname \ search 后面


const url = new URL('http://www.baidu.com')

// 赋值hash

url.hash = '/'

// 赋值路径

url.pathname = '/app'

// 赋值查询条件

url.search = 'id=45'

结果展示为http://www.baidu.com/app?id=45#/ 怎么调试也没能改变, 我想要的结果是http://www.baidu.com/#/app?id=45

不然重新打开一个新的tab页时,会导航到初始主路由 :cry:

所以只能去重新拼接一下URL地址:


const url = new URL('http://www.baidu.com/#/app')

const searchParams = new URLSearchParams()

searchParams.append("id","sv2341")

searchParams.append("name","test")

// 打开新的tab页面

window.open(url.toString()+"?"+searchParams.toString()) // http://www.baidu.com/#/app?id=sv2341&name=test

File

处理文件相关的信息.访问文件中的数据. UTF8编码

构造实例

参数定义:


const file = new File(bits,name,options)

可访问的属性,都为只读属性:

实例方法

自身没有定义方法,继承自Blob接口,可选的参数定义:


// 自定义文本内容

const file = new File(['hello world','luck for you'],'test.txt')

FileReader

上述只是定义个一个文件对象,我们要读取到文件的内容,则需要FileReader 对象读取数据.

构造实例

const fileReader = new FileReader();

可访问的属性:

实例方法

定义实例,则可以用来读取文件,文件的读取是一个异步过程. 那么异步就会存在异步流程,对应着不同的事件.

先看一下实例定义的方法:

可以继续之前的文件数据读取;


// 定义文件对象

const file = new File(['hello world','luck for you'],'test.txt')

// 定义文件读取的实例对象

const fileReader = new FileReader()

// 通过onload事件回调获取到文件内容

fileReader.onload = function(event){

    console.log(event.target.result)        // hello worldluck for you

}

// 读取文件为字符串

fileReader.readAsText(file)

这里是所有的事件:

定义文件下载

通常前端会处理一些简单的文件下载,比如文本、图片之类的. 会使用a标签进行下载处理


// 完成简单的自定义.txt文件下载

const file = new File(['hello world'],'test.txt')

// 定义读取文件对象

const fileReader = new FileReader()

// 读取文件

fileReader.onload = function(event){

    // 定义a标签,追加到body中,点击进行下载

    let a = document.createElement('a')

    a.download = 'hello.txt'

    a.href = event.target.result

    a.textContent = '下载'

    document.body.append(a)

}

// a标签下载接受的格式blob:或者data:

// 定义读取base64 格式的数据

fileReader.readAsDataURL(file)

可以读取远程的URL地址文件信息,在前端实现下载.

通常自定义实现的下载,不需要去点击,启动触发下载事件


// 通过click方法模拟点击事件,触发下载

a.click()

// 定义a标签不可见

a.style.display = 'none'

通过URL.createObjectURL定义文件下载

上述可以通过FileReader来读取文件内容,也可以通过URL静态方法创建blob:格式的URL对象,指向源内容.


// 创建文件内容ULR

const dataUrl = URL.createObjectURL(file)

// 构建下载

let a = document.createElement('a')

a.download = 'hello.txt'

a.href = dataUrl

a.textContent = '下载'

a.style.display = 'none'

document.body.append(a)

a.click();

准备写一下文件的上传、下载;主要是断点续传、分片上传等;先立个flag吧,不知道啥时候写完. :dog:

Image

常用的展示形式-图片,不可或缺. 通常的网站并不会处理图片,拿到ULR地址,直接做展示就好.如果是一个专门处理图片的工程的话, 就会对图片各方面处理要求的多. 通常先获取到图片的大小,初始画布等.

构造实例

实例同等于html元素img, 接受参数


const img = new Image()

// 等同于

img = document.createElement('img')

可访问属性:


// 定义实例

const img = new Image(150,160)

img.src = './test.png'

// 定义了宽度、高度,则可以直接获取到属性 img.width img.height

img.onload = function(){

  // 要获取实际的图片的大小,则必须等待图片加载完成

  // img.naturalWidth,img.naturalHeight

}

// 可以像普通的img标签添加到页面中

document.body.appendChild(img)

实例方法

基本没什么主要的方法提供调用,

继承自HTMLELement接口,拥有常规DOM的事件


// 主要是onload 加载完成获取到实际图片的大小信息

img.onload = function(){

  // 要获取实际的图片的大小,则必须等待图片加载完成

  // img.naturalWidth,img.naturalHeight

}

创建实例时,没有指定大小,img.widht/img.hegiht即是图片的真实大小。

响应式图片大小

现在的电子设备越来越多,屏幕大小、分隔各不相同,设计网站展示想达到完美的展示效果,则必须创建适合各个大小屏幕分隔的图片进行展示.

使用图片的srcset \ sizes定义图片资源


<img srcset="1.png 500w,

            2.png 800w,

            3.png 1200w"

    sizes="(max-width:520px) 500px,

            (max-width:820px) 800px,

            1200px"

    alt="图像"

  />

检测设备宽度, 检查符合条件的sizes列表媒体查询;获取到定义的展示图片的大小,从srcset加载到最符合size大小的图像进行展示.

可以通过定义srcset x 不同的分辨率;

MutationObserver

提供了监视对DOM树所做更改的能力 ,

这个是在vue指令滚动加载的时候看到源码里写的,之后就业务功能中也会使用它做一些加载的优化处理.

构造实例


// 实例化observer对象

const observer = new MutationObserver(handlerChange)

// 配置监听的dom,以及监听哪些属性的变动配置

const options = {

  childList:true, // 观察子节点的变化,添加或删除

  attributes:true, // 观察属性变动

  subtree:true, // 观察子孙节点

}

// 监听

observe.observe(document.querySelector("#app"),options)

// 回调事件

const handlerChange = function(mutationList,observer){

  // 触发变动的节点、属性

}

实例方法

滚动加载时加载初始数据

之前看到element的滚动加载的指令v-infinite-scroll , 在初始加载数据时,使用API监听子节点的变化,从而加载让数据内容去出现滚动条为止. 我们的滚动加载必须要有滚动条才能出发滚动事件.

(当然我们可以通过递归回调的方式判定数据区的offsetHeight/clientHeight 对比是否出现滚动条,进而追加数据)

但自动触发处理逻辑岂不更好 :smile:


let id = 0

// 加载数据的方法

function loadChild(){

    id++;

    let p = document.createElement('p')

    p.textContent = `数据id${id}`

    //

    dom.appendChild(p)

}

// 实例化observer对象

const observer = new MutationObserver(function(){

    // 触发之后,添加子节点

    loadChild()

    // 判断是否出现了滚动条,

    // 有滚动条了则不需要监听DOM 了

    if(dom.scrollHeight > dom.clientHeight){

        // 存在滚动条

        if(observer){

            observer.disconnect();

            observer = null;

        }

    }

})

// 配置监听的dom,以及监听哪些属性的变动配置

const options = {

    childList: true, // 观察子节点的变化,添加或删除

    attributes: false, // 观察属性变动

    subtree: false, // 观察子孙节点

}

// 监听

let dom = document.querySelector(".list-box");

observer.observe(dom, options)

// 初始调用一次

loadChild();

// 然后是正常的scroll 事件监听

dom.addEventListener('scroll',function(){

    // 滚动距离+可视高度 <= 内容区高度-20 追加数据

    let scrollBottom = dom.scrollTop + dom.clientHeight

    if(dom.scrollHeight - scrollBottom <= 20){

        loadChild();

    }

})

为了初始触发目标节点的变动,需要手动调用一次数据加载函数loadChild() , 当添加第一条数据后,DOM监听回调开始执行 ;一直到出现滚动条(可视高度不等于内容区域高度时)停止检测.

正常的scroll事件被监听,滚动到底部距离小于20(阀值)时,触发数据加载函数;

数据加载完成时,可以在loadChild函数中增加取消滚动事件,停止滚动加载时间触发.

MutationRecord

监听DOM 变更后回调第一个参数.

FormData

提供处理form表单数据的功能,form表单处理在日常开发中处处可见。现在的前端框架帮我很好的处理了这一问题,必要的学习了解还是必须的。

构造实例


//

const form = new FormData()

当我们传入form 参数时,每个form元素都需要name属性,这是必须的。会自动将表单值序列化


// 指定form元素,同步获取到表单里的表单属性、值。

const form = new FormData(document.querySelector('#form'))

实例方法


<form id="form">

    <div class="form-item">

        <label>姓名</label>

        <input type="text" name="name" value="admin" placeholder="输入姓名" />

    </div>

    <div class="form-item">

        <label>年龄</label>

        <input type="number" min="0" name="age" value="23" max="200" step="1" />

    </div>

    <div class="form-item">

        <label>性别</label>

        <input type="radio" name="gender" value="1" checked>男

        <input type="radio" name="gender" value="2">女

    </div>

</form>

定义的form表单,创建FormData实例后,操作表单元素,并可增加新的属性。


// 所有属性 ,按照表单元素的name属性序列化

form.keys()        // [...keys] - result:["name", "age", "gender"]

// 查找某个值

form.has('id')          // false

// 添加一个值,重复的name属性

form.append('name','test')       

form.get('name')              // 返回第一个符合的值, 为 admin

form.getAll('name')              // 返回所有的值得数组, ['admin','test']

XMLHttpRequest发送数据

创建一个ajax实例,发送请求。


// 直接发送数据

const xhr = new XMLHttpRequest()

xhr.open('post','/addUserInfo')

xhr.send(form)

使用File 创建文件,上传文件。


// 创建文件对象

const file = new File(['hello world'],'test.txt')

// 定义文件读取的实例对象

const fileReader = new FileReader()

// 定义请求实例

const xhr = new XMLHttpRequest()

// 通过onload事件回调获取到文件内容

fileReader.onload = function(event){

    // 读取到文件blob数据

    form.append('file',event.target.result)

    xhr.open('post','/addUserInfo')

    xhr.send(form)

}

// 读取文件为字符串

fileReader.readAsDataURL(file)

作为URLSearchParams 构造参数解析

可直接传入URLSearchParams解析,然后追加到URL上。


//

const params = new URLSearchParams(form)

// 可获取使用实例的方法

params.toString()                  // name=admin&age=23&gender=1&name=test

上一篇下一篇

猜你喜欢

热点阅读