Giter Site home page Giter Site logo

blog's Introduction

Hi there 👋

blog's People

Contributors

spiritree avatar

Watchers

 avatar  avatar

blog's Issues

2018年报总结

本文链接:https://deeptree.me/post/2018/12/2018/
简介:�毕业前后的一年,二零一八

迷茫与低迷

去年以「软件开发工程师」的身份进入上一家公司开始实习。在此期间,我大部分时间都在做后台管理系统,公司里的小伙伴人均「全栈」,
我自然也是学习Spring Boot全家桶(Java)+Vue全家桶(JavaScript),期间也完成了人生中第一个技术分享(关于webpack)。同时也很感谢陆老师和华哥,学到了各种经验。
但越学越迷茫,因为我做日常小需求没啥问题,可日后出去面试是前端还是后端呢?

随后在v2ex上征询了下前辈们的意见,最后还是决定向着自己更喜欢的前端方向走。年后找工作的经历跌宕起伏,但结果是好的。

重新开始

今年年中以「前端开发工程师」的身份进入现在的公司。从CSS弱鸡成长到常规布局和动画都能应付了;从Vue全家桶也转到React全家桶。
也接触了组件库开发、webpack优化、babel升级和node端的开发,这符合我心中大前端的概念。
虽然比较辛苦,但是也感觉到自己在快速成长中,感谢整个前端组的伙伴们,帮助了我许多。

展望

  1. �尽可能在开源社区做出贡献
  2. 深入基本原理
  3. 分享
  4. 健身?女朋友?

一键上传canvas所生成的图片至CDN

本文链接:https://deeptree.me/post/2018/07/uploadcanvasimg/
简介:�分析如何通过canvas生成图片并上传至CDN

起因

最近在做动态生成海报的项目,有生成海报后上传当前canvas图片的需求。

分析

脑袋一拍,思索出流程是这样canvas=>base64=>POST接口。但是常见的CDN不支持base64啊!查了下发现有canvas.toBlob(兼容性为Chrome50+)

于是流程改为canvas=>blob=>POST接口,但发现CDN还是不吃这一套,接口报错

思来想去,决定用普通的手动上传方式<input type="file" />看下请求格式(如图)

imgpost

Content-Type可以看出需要使用FormData对象去上传

红框部分则是<input type="file" />所生成的

分析一通后,梳理流程为canvas=>blob=>File=>FormData=>POST

代码

upload = () => {
  return new Promise((resolve, reject) => {
    canvasInstance.toBlob(blob => {
      // blob转file
      const file = new File([blob], 'poster.png', {
        type: 'image/png',
        lastModified: Date.now()
      })
      const xhr = new XMLHttpRequest()
      xhr.onreadystatechange = () => {
        try {
          if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 400) {
            const res = JSON.parse(xhr.responseText)
            resolve(res)
          }
        } catch {
          reject(new Error(xhr.statusText))
        }
      }
      xhr.open(
        'POST',
        `${cdnUrl}`,
        true
      )
      // 转换成通过input上传的文件
      let formData = new FormData()
      formData.append('file', file)
      xhr.send(formData)
    }, 'image/png')
  })
}

Why and How TypeScript?

本文链接:https://deeptree.me/post/2019/03/tsstart/
简介:�如何低成本且无痛地上手TypeScript

Why TypeScript?

业界动态

Facebook的yarn宣布用TypeScript重写

yarnpkg/yarn#6953

Facebook的Jest宣布用TypeScript重写

jestjs/jest#7554

storybook正在用TypeScript重构中

Vue3也在用TypeScript重构中


Github Trending

tsgithub.png


tsgithub2.png


Top 10 JavaScript errors from 1000+ projects (Rollbar)

1.jpg

  • Uncaught TypeError: Cannot read property,常见于a.b
  • TypeError: ‘undefined’ is not a function,常见于a.b()
  • TypeError: Cannot read property ‘length’,期望是数组
  • ‘X’ is not defined,ReferenceError
  • num.toFixed(102),RangeError

3.png


2.jpg


That's Why TypeScript

  • 提升代码的可读性与可维护性
    • 编译时报错
    • 配合VSCode的类型推导提升开发体验
    • 类型是最好的文档,加上注释后可以一定程度上替代文档
    • 自动生成index.d.ts(类型定义文件)
  • 社区活跃且是JavaScript名义上的唯一进化方向
    • 语法广受好评(师承C#)
    • 大部分热门库/框架都有类型定义
  • 与JavaScript兼容性良好
    • JavaScript的超集,.ts和.js可以共存

基础类型

// 字符串
const str: string = 'a'
// 布尔值
const isCC: boolean = true
// 数值
const LIMIT: number = 10
// 空
function consoleStr(): void {
  console.log('abc')
}
// null and undefined
const u: undefined = undefined
const n: null = null

数组

5.png


函数

func.png


接口(Interface)

在⾯向对象语⾔中,接⼝(Interfaces)是⼀个很重要的概念,它是对⾏为的抽象,⽽具体如何⾏动需要由类 (classes)去实现(implements)。

TypeScript 中的接⼝是⼀个⾮常灵活的概念,除了可⽤于 对类的⼀部分⾏为进⾏抽象以外,也常⽤于对「对象的形状(Shape)」进⾏描述。


interface1.png


类(Class)

TypeScript 拥有所有⽬前 ECMAScript class 进⼊标准或还在提案的属性。包括继承、getter、setter、静态⽅法、装饰器等。

在这个基础之上⼜添加 public、private 和 protected 三种修饰符。


class Animal1 {
  public name: string
  public constructor(name: string) {
    this.name = name
  }
}
let CatA = new Animal1('a')
console.log(CatA.name)
CatA.name = 'b'
console.log(CatA.name)

class Animal2 {
  private name: string
  public constructor(name: string) {
    this.name = name
  }
}
let CatC = new Animal2('c')
CatC.name = 'c'

class Animal {
  protected name: string
  public constructor(name: string) {
    this.name = name
  }
}

class Cat extends Animal {
  constructor(name: string) {
    super(name)
    console.log(this.name)
  }
}

// protect和private的区别就是protected可以在子类被访问

泛型(Generics)

泛型(Generics)是指在定义函数、接⼝或类的时候, 不预先指定具体的类型,⽽在使⽤的时候再指定类型的 ⼀种特性。


generics.png


How TypeScript?

FrontEnd

@babel/preset-typescript

Node.js

dev: ts-node
prod: tsc

Lint

typescript-eslint


addEventListener中的passive属性踩坑

本文链接:https://deeptree.me/post/2018/06/passive/
简介:在监听touchstart和touchmove时,发现preventDefault失效。本文介绍了踩坑详情和解决方法

起因

在移动端使用event.preventDefault()来阻止touchstarttouchmove事件发现无法实现

打开Chrome控制台发现打印了如下文字

[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080

点进网页看看发生了什么!

AddEventListenerOptions defaults passive to false. With this change touchstart and touchmove listeners added to the document will default to passive:true (so that calls to preventDefault will be ignored)..

If the value is explicitly provided in the AddEventListenerOptions it will continue having the value specified by the page.

This is behind a flag starting in Chrome 54, and enabled by default in Chrome 56. See https://developers.google.com/web/updates/2017/01/scrolling-intervention

大意是:为了移动端性能考虑,在监听touchstarttouchmove时,默认设置addEventListener中的passivetrue(这样就导致了preventDefault失效)

为什么Chrome这样做?

https://developers.google.com/web/updates/2017/01/scrolling-intervention

Performance!
可以减少250ms左右的延迟

Passive event listeners是2016年Google I/O 上同 PWA 概念一起被提出,但是同PWA不同,Passive event listeners
的作用很简单,如果用简单一句话来解释就是:提升页面滑动的流畅度。

Chrome 51 和 Firefox 49 已经支持 passive 属性。如果浏览器不支持,已经有人做了非常巧妙地 polyfill

// Test via a getter in the options object to see 
// if the passive property is accessed
var supportsPassive = false;
try {
  var opts = Object.defineProperty({}, 'passive', {
    get: function() {
      supportsPassive = true;
    }
  });
  window.addEventListener("test", null, opts);
} catch (e) {}

// Use our detect's results. 
// passive applied if supported, capture will be false either way.
elem.addEventListener(
  'touchstart',
  fn,
  supportsPassive ? { passive: true } : false
); 

在Vue中你可以通过如下代码来提升移动端性能够

<div v-on:scroll.passive="onScroll">...</div>

在React和其他框架/非框架中只能手动绑定了

elem.addEventListener('touchmove', func, { passive: true })

记得用完解绑!

elem.removeEventListener('touchmove', func, false)

解决方法

设置touch-action?

在网上搜了很多方法,有不少答案都指向设置touch-action: none

虽然设置后的确Chrome的确不报提示了,但是preventDefault依然没有生效

addEventListener中设置passive

只能自己手动来绑定事件了

elem.addEventListener('touchmove', func, { passive: false })

同样,用完要记得解绑~

elem.removeEventListener('touchmove', func, false)

参考文章

https://segmentfault.com/a/1190000007913386

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.