笔记

axios这个库会根据传入的params格式来设置请求头(request-header)中的Content-Type字段。

1.第二个参数是对象时,Content-Type默认是application/json类型

1
axios.post(url, {a: 1, b: 2})

2.第二个参数是字符串的时候,Content-Type默认是application/x-www-form-urlencoded类型

1
2
let data = {a:1,b:2};
axios.post(url,qs.stringify({ data }))

3.第二个参数是formData类型的时候,默认是multipart/form-data类型,如果用form自带的action提交,也默认是这个类型。

1
2
3
4
let data = new FormData(); 
data.append('a',1');
data.append('b',2);
axios.post(url,data);

当跟后端做导出功能时,需要注意的点就是他需要的Content-Type和请求体的形式,不要慌。


padding-top: 20%;,当内边距的值为百分比时,相对的是该元素的宽度(width),在活动页中,标题的设计感很强,所以设计师会出一张背景图,包含着标题和背景图。我们往往要在标题下方展示内容,这时候会使用padding-top来空出来标题的空间。但在不同的移动设备上,页面宽度不同,所以标题的位置不定,所以使用padding-top时不应使用一个固定的像素值,而是找出设计师给的背景图中,标题距离顶部距离和宽度的比例。比如说比例为0.6:

1
2
3
4
.container {
  padding-top: 0.6vw;
  background-size: 100% auto;
}

因为即使移动设备的宽度不同,但是比例并不会变,而又由于我们设置了background-size: 100% auto;(展示背景图宽度完全),这样便可以解决这个问题。


有时,a标签既有href属性(指向一个跳转链接),也有onclick事件回调。这样一是为了标签的语义化,二是想让href属性的跳转不总是生效。href属性和onclick回调函数存在执行顺序,onlick回调函数先执行,href属性跳转后执行,如果想禁掉href属性跳转,可以在onclick的回调函数中使用event.preventDefault()来阻止。


addEventListener第三个参数,原来是一个布尔值, 代表是否在捕获(capture)阶段触发监听器,现在很多浏览器扩展了第三个参数,第三个参数变成了一个对象。 其中最重要的属性是passive属性,若该属性为false,监听器函数触发时,默认行为不会被调用,相当于帮我们 执行了event.preventDefault(),这样浏览器能够优化滚动等事件。为true时不会禁止掉默认行为,

并不是所有浏览器都支持这个新特性,需要兼容,兼容代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
try {
  let passiveSuported = false;
  const options = Object.defineProperty(
    {},
    'passive',
    {
      get: function() {
        passiveSuported = true;
      }
    }
);
window.addEventListener('test', null, options);

} catch(error) {}

声明了passive属性为访问器属性(access property),window.addEventListener('test', null, options);执行时,若支持第三个参数为对象,则会去读取options对象,passive属性的getter函数被调用,passiveSuported变量置为true,意味着浏览器支持。(test事件瞎写的,也可以写成testxixixix事件)若浏览器不支持该特性,try...catch会捕获错误,以防页面crash。之后便可以用下面这个变量赋值给addEventListener第三个参数了:

1
2
const passiveListener = passiveSupported ? { passive: false, capture: false } : false
window.addEventListener('mousestart', () => {}, passiveListener);

transform属性是一个复合属性,有时会给元素加动画特性,涉及到变形就会用到transform。注意的是,如果元素本身存在transform属性,动画的transform会覆盖(override)本身的transform,定义动画时,需要都写到transform上。


window.requestAnimationFrame(callback),callback函数在下次重绘前被调用。 浏览器一秒刷新屏幕60次,所以一秒内callback也会被调用60次。 但为了提高性能和电池寿命,因此在大多数浏览器里,当requestAnimationFrame() 运行在后台标签页或者隐藏的<iframe>里时,requestAnimationFrame() 会被暂停调用以提升性能和电池寿命。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
const el = document.querySelector('ball');
let startTime;

const step = (timeStamp) => {
  if (!startTime) {
    startTime = timeStamp;
  }
  const diffTime = timeStamp - startTime;

  el.style.transform = `translateX(${Math.min(200, diff * 0.1)}px)`;

  if (diffTime < 2 * 1000) {
    window.requestAnimationFrame(step);
  }
}

window.requestAnimationFrame(step);

返回值为一个数值,可以传入window.cancelAnimationFrame来取消callback的调用。使用场景 是使用JavaScript来实现动画。

typeof 是JS的检测变量类型的操作符,但是在TS的上下文中也可以使用:

1
2
const a = 'str';
const b: typeof a = 'otherstr'

内置构造函数(比如String、Number、Function)的prototype属性(是一个对象)拥有toString方法, 但是Promise构造函数的prototype属性不拥有,可以通过判断与Object.prototype.toString 是否相等证明(因为Object.prototype.toString一定存在,若等式返回true,说明该构造函数的prototype对象没有toString方法,又因为原型链向上查找特性,最后找到了Object.prototype.toString,被返回。若等式返回false,则说明构造函数的prototype属性拥有toString方法,所以原型链查找过程停止)。

1
2
String.prototype.toString === Object.prototype.toString; // false
Promise.prototype.toString === Object.prototype.toString; // true

async函数可以转化成生成器函数,然后不停地调用迭代器(调用生成器得到的函数),直到result.done为true,说是语法糖不为过。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function spawn(generator, context) {
  return new Promise((resolve, reject) => {
    const iterator = generator.call(context);

    function step(getNextResult) {
      let result;
      try {
        result = getNextResult();
      } catch(err) {
        reject(err);
        return;
      }

      if (result.done) {
        resolve(result.value);
        return;
      }

      Promise.resolve(result.value).then(
        (result) => step(() => iterator.next(result)),
        (error) => step(() => iterator.throw(error))
      )
    }

    step(() => {
      return iterator.next();
    })
  })
}

知乎上有一个问题就是问为什么一段async代码输出顺序在不同的浏览器中执行,结果不同,根本原因就是上面的 代码中的Promise.resolve(result.value),chrome最开始用的Promise.resolve(result.value),之后改成了new promise(() => resolve(result.value)),最后又改成了Promise.resolve(result.value)。。。

updatedupdated2021-05-162021-05-16