浏览器对象、AJAX、DOM

115 阅读5分钟

浏览器对象

我们的网页是通过浏览器加载出来的, 而浏览器本身也有很多功能:

  • 浏览器本身版本信息
  • 当前窗口大小
  • 历史记录
  • ...

而这些数据都是绑定在 window 对象上的, 所以你可以认为对于浏览器加载的网页, window 就表示的浏览器本身

浏览器窗口大小

window 的如下4个属性控制这个浏览器的窗口大小, IE9+、Safari、Opera和Chrome都支持这4个属性

  • innerWidth : 页面视图的宽
  • innerHeight : 页面视图的高
  • outerWidth : 浏览器整个窗口的宽
  • outerHeight : 浏览器整个窗口的高

image.png可调整窗口大小再进行尝试

浏览器信息

我们在页面的时候, 如何知道用户使用的哪种浏览器, 好做不同的适配, 毕竟各种厂商的浏览器实现有各有差异

关于浏览器的相关信息都保存在 navigator 对象上面:

image.png

最常用的属性包括:

  • navigator.appName:浏览器名称;
  • navigator.appVersion:浏览器版本;
  • navigator.language:浏览器设置的语言;
  • navigator.platform:操作系统类型;
  • navigator.userAgent:浏览器设定的User-Agent字符串
  • navigator.userAgentData useragent:相关信息, Object

如何判断用户使用的是pc还是手机? image.png

屏幕信息

有时候 我们可能需要知道用户的屏幕尺寸, 方便我们做网页布局, 这时候就需要获取屏幕的数据:

image.png

访问网址

这个很有用, 为了保证每个用户访问该 URL 都呈现统一的效果, 我们的页面往往都需要读取当前 Page 的参数

image.png

下面是一些常用属性:

  • location.protocol: "https:"
  • location.host: "juejin.cn"
  • location.port: ""
  • location.pathname: "/creator/content/article/essays"
  • location.search: "?status=all"
  • location.hash: ""

要加载一个新页面,可以调用location.assign()。如果要重新加载当前页面,调用location.reload()

image.png

历史记录

history 对象保存了浏览器的历史记录,JavaScript 可以调用 history 对象的back()forward(),相当于用户点击了浏览器的“后退”或“前进”按钮

// <- 浏览器的“后退”按钮
history.back();

// -> 浏览器的“前进”按钮
history.forward()

AJAX

AJAX不是JavaScript的规范,它只是一个哥们“发明”的缩写:Asynchronous JavaScript and XML,意思就是用 JavaScript 执行异步网络请求

简单来说 就是浏览器中的 http client

在现代浏览器上写 AJAX 主要依靠 XMLHttpRequest 对象

XMLHttpRequest

// 新建XMLHttpRequest对象
var request = new XMLHttpRequest(); 

// 发送请求:
request.open('GET', 'https://www.baidu.com');
request.send();

如何就这样我们是获取不到请求结果, 由于js都是异步的, 我们需要定义回调来处理返回

request.onreadystatechange = function () {
    console.log(request.status)
    console.log(request.responseText)
}

对于 AJAX 请求特别需要注意跨域问题: CORS

简单请求

满足下面3个条件的是简单请求:

  • HTTP Method: GET、HEAD 和 POST
  • Content-Type: application/x-www-form-urlencoded、multipart/form-data和text/plain
  • 不能出现任何自定义头

通常能满足90%的需求

控制其跨域的关键头 来自于服务端设置的: Access-Control-Allow-Origin

对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段

  • 客户端发送请求时, Origin: xxxx
  • 服务端响应请求时, 设置: Access-Control-Allow-Origin: xxxx / *

如果服务端不允许该域,就跨越失败

如果想允许特点的Header, 服务端也可以通过添加: Access-Control-Expose-Headers 来进行控制

复杂请求

复杂请求:

  • HTTP Method: PUT、DELETE
  • Content-Type: 其他类型如application/json
  • 含自定义头, 比如我们后面携带的用于认证的X-OAUTH-TOKEN头

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)

preflight请求:

  • Method: OPTIONS
  • Header: Access-Control-Request-Method, 列出浏览器的CORS请求会用到哪些HTTP方法
  • Header: Access-Control-Request-Headers 该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段
OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

preflight响应:

  • Header: Access-Control-Allow-Origin, 允许的源(域)
  • Header: Access-Control-Allow-Methods, 服务端 允许的方法(所有方法, 一般大于请求的该头)
  • Header: Access-Control-Allow-Headers, 服务队 允许的自定义Header
  • Header: Access-Control-Max-Age, 用来指定本次预检请求的有效期, 避免多次请求, 该字段可选
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000

axios

很显然原生的client库,没那么好用, 于是诞生的Axios

页面(DOM)

浏览器当前加载的Page也是一个对象: window.document

由于 HTML 在浏览器中以 DOM 形式表示为树形结构,document 对象就是整个 DOM 树的根节点

比如我们获取当前 Document 中的一些属性: 比如 title documenttitle 属性是从 HTML 文档中的xxx读取的,但是可以动态改变

image.png

image.png

DOM查询

要查找DOM树的某个节点,需要从 document 对象开始查找。最常用的查找是根据 ID 和 Tag Name 以及 ClassName

在浏览器中打开一个 HTML 页面

<h1>列表</h1>
<ul id="list_menu" class="ul_class">
    <li>Coffee</li>
    <li>Tea</li>
    <li>Milk</li>
</ul>

image.png

image.png

image.png

当然我们也可以组合使用

image.png 等价于document.getElementById('list_menu').children

第一个子元素和最后一个子元素

image.png 获取父元素

image.png

更新DOM

获取的元素后, 我们可以通过元素的如下2个方法,修改元素:

  • innerHTML: 不但可以修改一个 DOM 节点的文本内容,还可以直接通过 HTML 片段修改 DOM 节点内部的子树
  • innerText: 只修改文本内容

image.png

使用innerText无法识别 HTML 格式 image.png 于是使用innerHTML

image.png

插入DOM

很多响应式框架都会根据数据新增,动态创建一个 DOM 元素,并插入到指定位置,

  • 使用 createElement 来创建一个 DOM 元素, 比如创建一个 a 标签
  • 使用 appendChild 进行追加子元素

image.png

如果我们想要控制元素插入的位置可以使用 insertBefore

insertBefore 的语法如下:

image.png

总结: 有2种方式可以插入一个DOM元素

  • appendChild: 把一个子节点添加到父节点的最后一个子节点
  • insertBefore: 插入到某个元素之前

删除DOM

删除一个 DOM 节点就比插入要容易得多

要删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的 removeChild 把自己删掉

removeChild 的语法如下:

parent.removeChild(childNode);

比如我们删除刚才添加的那个元素

image.png