Web APIs 知识总结【操作浏览器】

115 阅读6分钟

操作浏览器

Window对象

BOM(浏览器对象模型)

  1. 浏览器对象模型,是浏览器内置中的全局对象
  2. 包含了 navigatorlocationdocumenthistoryscreen 5个属性,即所谓的 BOM (浏览器对象模型)

定时器-延时函数

定义

JavaScript 内置的一个用来让代码延迟执行的函数

语法

setTimeout (回调函数, 等待的毫秒数)

特点

setTimeout 仅仅只执行一次,所以可以理解为就是把一段代码延迟执行, 平时省略 window

清除延时函数

  1. 设置句柄

    let timer = setTimeout(回调函数, 等待的毫秒数)
    
  2. 清除

    clearTimeout(timer)
    

拓展

  1. 通过递归 setTime 可以实现 setInterval

    function test() {
        div.innerText = new Date().toLocaleString()
        // :一个函数调用自身,就形成     函数递归
        setTimeout(test, 1000)
      }
      test()
    
  2. 通过自清除 setInterval 可实现 setTimeout

    function time() {
            let tid = setInterval(() => {
                console.log(1);
                clearInterval(tid)
            }, 1000);
    }
    time()
    
  3. 两种定时器对比

    • setInterval

      1. 重复执行,首次执行会延时
      2. 自清除可模拟 setTimeout
    • setTimeout

      1. 延时执行,只执行 1 次
      2. 结合递归函数,能模拟 setInterval 重复执行
      3. clearTimeout 清除由 setTimeout 创建的定时任务

JS执行机制

同步和异步

  1. 同步

    前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。

  2. 异步

    在做一件事情时,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情。

  3. 本质区别

    这条流水线上各个流程的执行顺序不同。

执行过程

  1. 同步任务

    同步任务都在主线程上执行,形成一个执行栈。

  2. 异步任务

    js 的异步是通过回调函数实现的,都放在任务队列中。

  3. 类型

    • 普通事件,如 clickresize
    • 资源加载,如 loaderror
    • 定时器,包括 setIntervalsetTimeout

执行机制

  1. 先执行执行栈中的同步任务,异步任务(回调函数)放入任务队列中(任务队列也称为消息队列)
  2. 一旦执行栈中所有同步任务执行完毕,系统会按次序读取任务队列中的异步任务,开始执行
  3. 由于主线不断地重复获取任务、执行任务、再获取任务、再执行任务,这种机制被称为事件循环

图解

js执行机制.png

location 对象

定义

数据类型是对象,它拆分并保存了 URL 地址的各个组成部分

常用属性和方法

  1. href 属性获取完整的 URL 地址,对其赋值时用于地址的跳转

    loacltionhref = 'http://www.baidu.com'
    
  2. search 属性获取地址中携带的参数,符号 ?后面部分

  3. hash 属性获取地址中的啥希值,符号 # 后面部分

  4. reload 方法用来刷新当前页面,传入参数 true 时表示强制刷新

navigator 对象

定义

数据类型是对象,该对象下记录了浏览器自身的相关信息

常用属性和方法

通过 userAgent 检测浏览器的版本及平台

histroy 对象

  1. 数据类型是对象,该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等

  2. 常用属性和方法

    1. 前进:history.foward()
    2. 后退:history.back()
    3. 前进或后退:history.go(参数) ——前进1步history.go(1); 后退一步 history.go(-1)


swiper 插件

  1. 插件定义:别人写好的一些代码,我们只需要复制对应的代码,就可以直接实现对应的效果
  2. 官网 www.swiper.com.cn/
  3. APi文档 www.swiper.com.cn/api/index.h…


本地存储

特性

  1. 数据存储在浏览器内
  2. 设置、读取方便、刷新不丢失数据
  3. 容量大
  4. 只能存储字符串

分类

  • loaclStorage

    1. 特点

      1. 存储在浏览器物理空间中
      2. 除非手动删除,理论上可以永久存在
      3. 可以跨页面使用,但是要保证是同一个浏览器
      4. 可以存储5MB左右
      5. 以键值对的形式存储使用
    2. 语法

      • 存储数据
        loaclStorage.setItem('名字key',值value);
        
      • 获取数据
        loaclStorage.getItem('名字key');
        
      • 删除数据
        loaclStorage.clear();
        

    注意事项 只能存储字符串,如果存储的不是字符串形式,会自动进行 toString() 将数据转换为字符串

存储复杂类型

  1. 本地只能存储字符串,无法存储复杂数据类型,要把复杂数据类型转换为 JSON 字符串再存储到本地
  2. 将复杂数据转换成JSON字符串,存储 本地存储中
    JSON.stringify(复杂数据类型)
    
  3. JSON 字符串转换成对象,取出 时候使用
    JSON.parse(JSON字符串)
    
  • sessionStorage(了解)

    1. 特点
      1. apilocalStorag 一样
      2. 它是存储在浏览器的缓存空间中
      3. 只是关闭当前会话,就会消失
      4. 不同会话不能混用,那个会话存储就只能这个会话使用
      5. 以键值对的形式存储使用


自定义属性

固有属性

标签天生自带的属性 比如 class id title等,又叫做内置属性,可以直接使用点语法操作

自定义属性

由程序员自己添加的属性,在 DOM 对象中找不到,无法使用点语法操作,必须使用专门的 API

随便自定义属性

  • 获取自定义属性
    getAttribute('属性名') 
    
  • 设置自定义属性
    setAttribute('属性名', '属性值') 
    
  • 删除自定义属性
    removeAttribute('属性名') 
    

data-自定义属性

  1. 定义:在标签上一律以 data- 开头
  2. 获取:以 dataset 对象方式获取

自定义属性.png



总结

操作浏览器.png



综合案例

数据编辑

整体效果如下所示。

数据编辑.png

点击编辑按钮会跳出模态框,同步当行的数据,修改数据后点击保存按钮后会保存数据重新渲染页面,并且刷新后也不会复原。

数据.png

页面结构布局:

该页面并没有用到自己写,而是使用 bootstarp 框架,bootstarp官网点击 javastrapt 组件,找到模态框,复制以下代码即可。

模态框.png 然后修改一下里面的内容。

<!-- 编辑模态框 -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
        <span aria-hidden="true">&times;</span>
      </button>
                <h4 class="modal-title" id="myModalLabel">编辑</h4>
            </div>
            <div class="modal-body">
                <form class="form-horizontal">
                    <div class="form-group">
                        <label for="name" class="col-sm-2 control-label">分类名称</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="name" placeholder="请输入分类名称" />
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="slug" class="col-sm-2 control-label">分类别名</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="slug" placeholder="请输入分类别名" />
                        </div>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">
        取消
      </button>
                <button type="button" class="btn btn-primary btnsave">保存</button>
            </div>
        </div>
    </div>
</div>

最后引入 css 样式与 jsjquery 包即可。

js 步骤解析:

  1. 获取事件源,由于这几个数据都是未来事件类型,因此要用到事件委托,获取他们的父类 tbody 。再获取名称和别称表单与保存按钮。

    let tbody = document.querySelector('tbody')
    let name = document.querySelector('#name')
    let slug = document.querySelector('#slug')
    let btnsave = document.querySelector('.btnsave')
    
  2. 声明一个数组模拟假数据,在封装一个页面渲染函数方便后续重复渲染,避免代码冗余。渲染页面步骤如下:

    1. 设置一个新变量 htmlStr ,赋值空字符串。
    2. 对数组进行遍历,用拼接字符串以及模板字符串的方式添加结构。
    3. tbody 赋值。
    // 1.模拟数据
    let list = [
      { id: 1, name: '爱代码', slug: 'love code' },
      { id: 2, name: '爱调试', slug: 'love debug' },
      { id: 3, name: '爱作业', slug: 'love homework' }
    ]
    // 2.实现动态渲染:遍历+拼接
    function init() {
      let htmlStr = ''
      list.forEach(function(v, i) {
        htmlStr += `<tr>
                    <td>${v.name}</td>
                    <td>${v.slug}</td>
                    <td class="text-center" width="100">
                      <button type="button" class="btn btn-primary btn_edit" data-id='${v.id}' data-name='${v.name}' data-slug='${v.slug}'>编辑</button>
                    </td>
                  </tr>`
      })
      tbody.innerHTML = htmlStr
    }
    init()
    
    1. 使用自定义 data-id 号、名称和别名属性存储起来。
  3. 事件委托的方式绑定事件。由于每项数据都不是固定写死的,会未来生成或删除,因此用事件委托来实现。为父类 tbody 绑定点击事件:

    1. e.target 可以获取被点击是那个元素,类名是内置属性,因此可以直接 e.target.classList.contains() 进行类名判断被点击的是否是编辑按钮,如果是编辑按钮,则弹出模态框。
    2. 获取之前存储的自定义属性 e.target.dataset ,让模态框的名称表单与别名表单的值等于这两个属性。
    3. 设置一个全局变量 id ,再在这里获取前面存储的 id 值,用于后面保存操作的 id 识别。如果这里没有设置成全局变量,而是直接用 let 声明,则会因为作用域问题报错,提示变量 id 未声明。
    tbody.addEventListener('click', function(e) {
        if (e.target.classList.contains('btn_edit')) {
            // 填充默认数据
            // 1.先获取你要填充的数据
            let data = e.target.dataset
            console.log(data);
            id = data.id
            // 2.填充数据
            name.value = data.name
            slug.value = data.slug
            $('#myModal').modal('show')
        }
    })
    
  4. 点击保存按钮后,对数组进行循环遍历,判断:

    1. 如果某一项 list[i].id 值等于当前被点击的编辑按钮的 id 则把表单内的值赋值给这一项的数据。
    2. 渲染页面
    3. 做本地存储,由于是复杂数据,因此要先转为 Json 格式,代码语法为:loaclStorage.setItem('book', JSON.stringify(list)) ,前面渲染页面函数内也要做这项操作,在发生改动之后渲染完页面也要再一次做本地存储。光存储不调用也不行,此时数组 list 无需使用固定死的数组数据,直接调用本地存储的数据,代码语法为:let list = JSON.parse(localStorage.getItem('book')) || []
    4. 点击保存按钮后关闭模态框,这项去看 bootstarp 官网文档即可。
    function init() {
        let htmlStr = ''
        list.forEach(function(v, i) {
            htmlStr += `<tr>
                <td>${v.name}</td>
                <td>${v.slug}</td>
                <td class="text-center" width="100">
                  <button type="button" class="btn btn-primary btn_edit" data-name='${v.name}' data-id='${v.id}' data-slug='${v.slug}'>编辑</button>
                </td>
              </tr>`
        })
        tbody.innerHTML = htmlStr
        localStorage.setItem('book', JSON.stringify(list))
    }
    
    btnsave.addEventListener('click', function() {
        // 循环数组,进行判断
        for (let i = 0; i < list.length; i++) {
            // 如果数组里的id值等于当前被点击的id,则更改它的值为表单的值
            if (list[i].id == id) {
                list[i].name = name.value
                list[i].slug = slug.value
            }
            init();
            localStorage.setItem('book', JSON.stringify(list));
            // 渲染页面,关闭编辑页面
            $('#myModal').modal('hide')
        }
    })
    

注意:

数组引用本地存储使用到或运算 || ,如果本地没有数据,则前半部分为假,或运算会把后半部分的空数组赋给 list ,如果本地有数据,则短路运算,直接把数据给 list 。这一步的目的是为了防止本地没数据 listnull ,空没有 forEach 属性而报错。