分类 JavaScript 下的文章

本文记录了从jQurey转到原生JavaScript开发的相关处理。

一 历史

二十一世纪初,IE 6还在统治浏览器的时代,出现了一批JavaScript框架。除了提高前端开发效率,还屏蔽了各个浏览器的JavaScript接口差异。那时有3个产品印象比较深刻:

  1. prototype,http://prototypejs.org/
    其特点是在原生JavaScript基础上做扩展,定义通用的方法或接口,屏蔽各个浏览器的差异。很轻量,个人比较喜欢。
  2. Ext JS,https://www.sencha.com/products/extjs/
    数据与界面分离,提供丰富的UI组建,便于页面开发。当时浏览器JavaScript性能不高,用起来不够流畅,不适合简单排版布局的页面。但是对于开发一些管理系统,确实很方便。
  3. jQuery,https://jquery.com/
    最大特别是查找HTML元素很方便(前提是熟悉其搜索语法),有点函数式编程的味道。在那个需要手工修改HTML界面的年代,确实很方便。

二 当前

看看当前的浏览器,已经是Webkit内核的天下,加上IE已亡,ECMAScript 6普及……各个浏览器的JavaScript兼容性大大提高。所以,我们可以直接采用浏览器原生JavaScript,替代jQuery这类用于遍历或搜索DOM的框架。当然,复杂的界面,主要是响应式前端框架(AngularJS、React、VUE)的世界。

三 实现方法

主要参考这个文章,从jQuery转到原生JavaScript。

另外,对于页面上的异步请求(ajax),该文章没有提出timeout的处理。以下整理一个示例:

// 请求错误的类,用于传递错误信息
let RespError = class {
  constructor(code, msg, respJson) {
    this.code = code;
    this.msg = msg;
    this.respJson = respJson;
  }
};

// POST提交Json数据。调用ajaxJson方法前加上async就是同步调用,直接调用就是异步调用
// 默认超时10秒
let ajaxJson = async (url, formParam={}, onSuccess=(respJson)=>{}, 
    onFailed=(respError)=>{}, timeoutSec=10) => {
  let controller = new AbortController();
  let timeoutId = setTimeout(() => {
    // 超时后停止请求
    controller.abort();
    // 抛出超时的错误
    onFailed(new RespError(-1, 'TIMEOUT', null));
  }, timeoutSec * 1000);
  try {
    // 发起请求
    let response = await fetch(url, {
        signal: controller.signal, // 用于接收中断请求信号
        method: 'POST',
        cache: 'no-cache',
        headers: {
          // 声明请求的参数是JSON
          'Content-Type': 'application/json; charset=UTF-8'
        },
        body: JSON.stringify(formParam)
    });
    // 注意,响应的数据只能获取一次,包括response.json()和response.text()
    let respJson = await response.json();
    if(!response.ok) {
      // 请求失败,抛出自定义的错误对象
      throw new RespError(response.status, response.statusText, respJson);
    }
    onSuccess(respJson);
  } catch(err) {
    onFailed(err instanceof RespError ? err : new RespError(-1, err.message, null));
  } finally {
    // 请求结束,停止执行定时函数。避免相应成功后,抛出超时的错误。
    clearTimeout(timeoutId);
  }
};

关于Fetch的使用,参考:

  1. Fetch API 教程
    https://www.ruanyifeng.com/blog/2020/12/fetch-tutorial.html
  2. mdn web docs - 使用 Fetch
    https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch

四 后记

推荐搭配 petite-vue ,实现数据与页面元素的绑定。