Giter Club home page Giter Club logo

mydiary's People

Contributors

amenzai avatar

Stargazers

 avatar  avatar  avatar  avatar

mydiary's Issues

我的各个账户备份

  • facebook: 郭金超(amenzai) gu*****.
  • twitter: 阿闷仔(amenzai) gu*******.
  • instagram: 阿闷仔(amenzai) gu*******.
    以上账户都是用邮箱注册,facebook email: [email protected]

装机软件集锦 | 2018-02-27

阿闷仔装机必备软件集锦

设计类

开发类

工具型

教程

1、Chrome DevTools 的一些使用技巧

2、dialog

HTML 5.2 新增了 元素,这个元素将来一定会广泛使用,因为它提供了浏览器原生 Modal 窗口。

3、[Optimizing React: Virtual DOM explained, by Evil] Martians(https://evilmartians.com/chronicles/optimizing-react-virtual-dom-explained)

React 的虚拟 DOM 机制的详细解释, JSX 代码如何变成虚拟 DOM 的数据结构。

4、Canvas: Draw on the web

5、分布式系统的全面介绍

分布式系统的基本概念和基本知识,这篇文章都谈到了。

6、各种数据结构的 JavaScript 实现

这篇文章针对初学者,介绍 Array、HashMaps、Sets、Linked Lists、Stacks、Queues 这六种数据结构的 JavaScript 实现。

7、Eloquent JavaScript 3rd edition 中文版

一本开源的 JavaScript 语言的入门教材。

8、git push --force-with-lease

不要用 git push --force,而要用 git push --force-with-lease 代替。在你上次提交之后,只要其他人往该分支提交给代码,git push --force-with-lease 会拒绝覆盖。

vue碎碎谈

1. vue-cli创建项目结构

  1. 装node(npm包含其中)
    使用node -v npm -v 验证是否安装成功
  2. 全局安装vue-cli
    npm install -g vue-cli
    嫌慢的话,安装cnpmnpm install -g cnpm --registry=https://registry.npm.taobao.org
    cnpm install -g vue-cli
  3. 初始化项目
    vue init webpack vue-demo
    cd vue-demo
    npm install or cnpm install
  4. 启动项目
    npm run dev

2. vue-router页面跳转

记住这些用于页面跳转的:

2.1 router-link

<router-link :to="'/home/:id'"></router-link>
<router-link :to="{path:'/home/login',query:{name:'tom'}}"></router-link>
<router-link :to="{path:'/home/login',params:{id:1}}"></router-link>

2.2 $router.push

//参数可以是字符串或对象
this.$router.push()

3. vuex

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state,
  mutations: {
    UPDATE_LOADING(state, status) {
      state.loading = status
    }
  },
  actions: {
    ToggleSideBar({ commit }) {
      commit('TOGGLE_SIDEBAR')
    },
    addVisitedViews({ commit }, view) {
      commit('ADD_VISITED_VIEWS', view)
    },
    delVisitedViews({ commit, state }, view) {
      return new Promise((resolve) => {
        commit('DEL_VISITED_VIEWS', view)
        resolve([...state.visitedViews])
      })
    }
  }
})

4. axios处理异步请求

查看详细教程

5. 组件之间数据传递

父组件向子组件:props
props:['data']
子组件向父组件:父组件自定义事件,子组件$emit触发事件
this $emit('eventName',data)

6. 其他

keep-alive 将组件保留在内存中,避免重新渲染
slot在子组件设置个插槽,这样父组件在调用时可以用其他结构替换。
子组件中:

<slot name="btn"></slot>

父组件:

<children-component>
  <button slot="btn"></button>
</children-component>

Web Worker | 2018-02-08

JavaScript语言采用的是单线程模型,也就是说,所有任务排成一个队列,一次只能做一件事。随着电脑计算能力的增强,这一点带来很大的不便,无法充分发挥JavaScript的潜力。尤其考虑到,File API允许JavaScript读取本地文件,就更是如此了。

Web Worker的目的,就是为JavaScript创造多线程环境,允许主线程将一些任务分配给子线程。在主线程运行的同时,子线程在后台运行,两者互不干扰。等到子线程完成计算任务,再把结果返回给主线程。因此,每一个子线程就好像一个“工人”(worker),默默地完成自己的工作。

普通的Wek Worker,只能与创造它们的主进程通信。还有另一类Shared worker,能被所有同源的进程获取(比如来自不同的浏览器窗口、iframe窗口和其他Shared worker)。

Web Worker有以下几个特点:

  • 同域限制。子线程加载的脚本文件,必须与主线程的脚本文件在同一个域。
    DOM限制。子线程无法读取网页的DOM对象,即document、window、parent这些对象,子线程都无法得到。(但是,navigator对象和location对象可以获得。)
  • 脚本限制。子线程无法读取网页的全局变量和函数,也不能执行alert和confirm方法,不过可以执行setInterval和setTimeout,以及使用XMLHttpRequest对象发出AJAX请求。
  • 文件限制。子线程无法读取本地文件,即子线程无法打开本机的文件系统(file://),它所加载的脚本,必须来自网络。

检查支持情况

if (window.Worker) {
  // 支持
} else {
  // 不支持
}

使用:

// 主进程文件
var worker = new Worker('http://127.0.0.1:9292/work.js');
  // 发送的数据可以是字符串或者对象
  // worker.postMessage("Hello World");
  worker.postMessage({method: 'echo', args: ['Work']});

  worker.addEventListener('message', function(e) {
      console.log(e.data);
  }, false);

// work.js
self.addEventListener('message', function(e) {
  console.log(e.data.method)
  // 可以进行一些操作在对主进程进行发送信息   
  self.postMessage('You said: ' + e.data.method);
}, false);

JS 中级面试

面试环节:

  • 一面:基础知识 html css3 js
  • 二面/三面(高级工程师):基础延伸(根据简历上自己的项目)、技术原理 优点 缺点
  • 三面/四面(业务负责人):项目中担任的角色,起的作用,业务处理
  • 终面(HR):性格、沟通、潜能、规划

面试准备:

  • 职位描述分析
    • 通过了解招聘公司的岗位描述和要求,搞清楚需要了解那些技术点,然后查阅资料搞懂
    • 深入分析,弄清侧重的技术点
  • 业务分析或实战模拟
    • 了解公司是哪个方向的业务,可以访问官网,查看源码了解技术栈
    • 比如:对于Jquery,了解下jQuery模板引擎、jQuery事件委托、事件代理、waifer延迟等
  • 技术栈准备
    • jQuery:核心架构 事件委托 插件机制
    • Vue React AngularJs NodeJs less sass grunt gulp npm webpack
    • 可以事先准备些自己熟知的项目、例子、技术点,将面试官往这方面引导
  • 自我介绍
    • 简历:基本信息、学历、工作经历、开源项目
      • 基本信息:姓名、年龄、手机、邮箱、籍贯
      • 学历:博士-硕士-本科
      • 工作经历:时间-公司-岗位-职责-技术栈-业绩
      • 开源项目:github和说明
    • 自我陈述
      • 把握面试的沟通方向
      • 豁达、自信的适度发挥
      • 自如谈兴趣、巧妙示实例、适时讨疑问
      • 节奏要适宜、切忌小聪明

一面二面

  • 页面布局
  • CSS盒模型
    • 标准模型和IE模型概念
    • 上述之间区别:content-box border-box
    • CSS如何设置上述两种模型
    • JS如何设置 获取盒模型的宽和高 IE: ele.currentStyle.width/heigh
    • 根据盒模型解释边距重叠
    • BFC(边距重叠解决方案)
      • BFC基本概念:块级格式化上下文
      • 原理,也就是BFC的渲染规则
        • BFC元素垂直方向的边距会发生重叠
        • BFC元素的区域不会与浮动元素的Box重叠
        • BFC在页面是一个独立的容器,外面的元素不会影响里面的元素反之亦然
        • 计算BFC高的时,浮动元素也会参与计算
      • 如何创建:
        • overflow: hidden/auto等, 不是visible
        • float的值不为none
        • position的值不为static 或者relative
        • display 是 table table-cell
      • 使用场景:
  • DOM事件
    • 基本概念:DOM事件的级别
      image
    • DOM事件模型
      • 捕获和冒泡
    • DOM事件流
      • 三个阶段
        第一阶段:从window对象传导到目标节点,称为“捕获阶段”(capture phase)。
        第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
        第三阶段:从目标节点传导回window对象,称为“冒泡阶段”(bubbling phase)。
    • DOM事件的捕获具体流程
    • Event对象的常见应用
      event.target:事件最初发生的节点
      event.currentTarget:事件当前所在的节点
      event.preventDefault()
      event.stopPropagation()
      event.stopImmediatePropagation():阻止同一个事件的其他监听函数被调用
    • 自定义事件
// 新建事件实例 如果需要传递数据则需要CustomEvent
var event = new Event('build');

// 添加监听函数
elem.addEventListener('build', function (e) { ... }, false);

// 触发事件
elem.dispatchEvent(event);
  • Http协议类
    • HTTP协议的主要特点
      简单快速:URL对应一个资源
      灵活:传个类型,就是请求对应文件类型的资源
      无连接:连接一次就会断掉
      无状态:不能区分两次连接的身份
    • HTTP报文的组成部分
      请求报文:请求行、请求头、空行、请求体
      image
      相应报文:状态行、响应头、空行、响应体
      image
    • HTTP的方法
      image
    • POST和GET的区别
      image
      记住三到四个
    • HTTP状态码
      image
      image
      image
    • 什么是持久连接
      image
    • 什么是管线化
      image
      image
  • 原型链类
    • 创建对象几种方法
      image
    • 原型、构造函数、实例、原型链
      image
    • instanceof的原理
      image
    • new运算符
      image
  • 面向对象
    • 类与实例
      类的声明
      生成实例
    • 类与继承
      如何实现继承
      继承的几种方式
  • 通信类
    • 什么是同源策略及限制
    • 前后端如何通信
    • 如何创建Ajax
    • 跨域通信的几种方式
  • 安全类
    • CSRF
      基本概念:跨站请求伪造
      攻击原理
      image
      防御措施:TOKEN验证、Referer验证(页面内来源验证)、隐藏令牌
    • XSS
      基本概念:跨域脚本攻击
      攻击原理:不需要登录验证,根据合法渠道,注入脚本
      防范措施:
  • 算法类
    • 排序
      image
      image
    • 堆栈、队列、链表
      image
    • 递归
      image
    • 波兰式和逆波兰式
      image
      先理解题目(问面试官给个提示,说自己知道用了什么技术点,自己说一下。。)

二面/三面

面试技巧:

  • 知识面要广
  • 理解要深刻
  • 内心要诚实
  • 态度要谦虚
  • 回答要灵活
  • 要学会赞美
  1. 渲染机制

什么是DOCTYPE及作用
image

浏览器渲染过程
image

重排Reflow

重绘

布局

  1. JS运行机制
    image

  2. 页面性能
    image

缓存:
image

  1. 错误监控
    image
    image

三面四面

面试技巧:

  • 准备要充分
  • 描述要演练(模拟演练)
  • 引导找时机(引导说出自己优势,做过的项目啥的)
  • 优势要发挥
  • 回答要灵活

考查能力:

  • 业务能力
    • 主动描述或被动回答
      5-1 mp4_20180806_111002 553
  • 团队协作能力
    up1
  • 事务推动能力
    5-2 mp4_20180806_111758 024
  • 带人能力
    5-2 mp4_20180806_111833 048
  • 其他能力
    • 组织能力
    • 学习能力
    • 行业经验

最终面

面试技巧:

  • 乐观积极
  • 主动沟通
  • 逻辑顺畅
  • 上进有责任心
  • 有主张,做事果断

考察问题:

  • 职业竞争力
    6-1 mp4_20180806_112528 128
  • 职业规划
    6-2 mp4_20180806_112910 520

node常用核心模块 | 2018-04-04

path模块

path.join()
连接路径,正确使用当前系统的路径分隔符path.join(myDir, 'test')

path.resolve()
将相对路径转为绝对路径,可以接受多个参数,依次表示所要进入的路径path.resolve([from ...], to)

fs模块

readFileSync()
同步读取文件,返回一个字符串

var text = fs.readFileSync(fileName, "utf8");

// 将文件按行拆成数组
text.split(/\r?\n/).forEach(function (line) {
  // ...
});

readFile()
异步读取文件

var fs = require('fs');
fs.readFile('example_log.txt', function (err, logData) {
  if (err) throw err;
  var text = logData.toString();
});

react简单说明 | 2018-02-08

  • Facebook 公司2013年推出
  • 现在最好的社区支持和生态圈
  • 大量的第三方工具

优点

  • 组件模式:代码复用和团队分工
  • 虚拟 DOM:性能优势
  • 移动端支持:跨终端

缺点

  • 学习曲线较陡峭
  • 全新的一套概念,与其他所有框架截然不同
  • 只有采用它的整个技术栈,才能发挥最大威力
  • 因为React许可协议, 可能不适用于某些公司的使用场景

总结:React 非常先进和强大,但是学习和实现成本都不低

其他

使用JSX语法,遇到{}就用JS语法解析,遇到<就用html语法解析,最外层只能有一个节点。
网上有很多组件库可以使用。

核心**:只要 State 发生变化,View 也要随之变化。
React 的本质是将图形界面(GUI)函数化。

React 本身只是一个 DOM 的抽象层,使用组件构建虚拟 DOM。
React 没有解决的问题:

  • 架构:大型应用程序应该如何组织代码?
  • 通信:组件之间如何通信?

React 只是视图层的解决方案,可以用于任何一种架构。

组件会发生三种通信

  • 向子组件发消息
  • 向父组件发消息
  • 向其他组件发消息
    React 只提供了一种通信手段:传参。对于大应用,很不方便。

Flux 只是一个概念,有30多种实现。

日记 | 2018-05-24

技术

移动端适配方案01:

(function (d, w) {
  const doc = d.documentElement;
  let tid;
  function rem() {
    const width = Math.min(doc.getBoundingClientRect().width, 768);
    doc.style.fontSize = width / 7.5 + 'px';
  }
  rem();
  w.addEventListener('resize', function () {
    clearTimeout(tid)
    tid = setTimeout(() => {
      rem()
    }, 300);
  });
})(document, window);

2

npm i postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano --S
module.exports = { "plugins": { "postcss-import": {}, "postcss-url": {}, "postcss-aspect-ratio-mini": {}, "postcss-write-svg": { utf8: false }, "postcss-cssnext": {}, "postcss-px-to-viewport": { viewportWidth: 750, // (Number) The width of the viewport. viewportHeight: 1334, // (Number) The height of the viewport. unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to. viewportUnit: 'vw', // (String) Expected units. selectorBlackList: ['.ignore', '.hairlines'], // (Array) The selectors to ignore and leave as px. minPixelValue: 1, // (Number) Set the minimum pixel value to replace. mediaQuery: false // (Boolean) Allow px to be converted in media queries. }, "postcss-viewport-units":{}, "cssnano": { preset: "advanced", autoprefixer: false, "postcss-zindex": false } } }

参考地址

我懂个P | 2018-01-21

网易云音乐banner U1K1 u1ku1ku.lofter.com
时光网banner 宽屏
广告狗:数英网 顶尖文案
剁手党:京东首页 天猫首页 任意一家旗舰店
建立文件夹:积累

搜图关键词:
大气:宇宙星空图 城市 山 大海
科技-VR-HTC vive Oculus Rift
利用不同领域的事物代替(蔬菜、水果代替罩杯?)。

不清楚时,关键词后加 壁纸、高清 HD

百度图片:图片尺寸过滤筛选(要特大尺寸)
比例、色彩等进行过滤筛选

免费图库:Pexels(先在这找,找不到去后面找) Pixabay(量太大,优势会搜出不想干的) Stocksnap(清新文艺)

Librestock(综合搜索)

一些屌的官网找图:Apple Nike
参考官网的排版设计

搜索的图,保存于电脑,设置为桌面壁纸轮播。

怎么找到匹配文本的图?
匹配文案中的关键词
匹配文案中的标点符号(从标点符号揣摩文本中体现的感情)
就是表情类图片啦(从标点符号中读出情绪)

三类图片非常抓眼球:
婴儿、野兽、美女、傻B(逗笑别人的图片)
逗比图库:gratisography.com
www.johnwilhelm.ch
500px.com/horazio

500px.com/adrian_sommeling

文字篇:
现代风:微软雅黑、方正兰亭黑、方正正黑、方正幼线体
**风:文悦青龙体、叶根友唐楷、苏新诗毛糙体
文艺风:方正小标宋、方正清刻本宋、方正粗黑宋、蒙纳秀明简
粗犷风:方正超粗黑、蒙纳简超刚黑、造字工房明黑、造字工房劲黑
柔情风:造字工房悦黑、汉仪意宋体、造字工房妙妙体、汉仪典雅体
可爱风:造字工房丁丁体、汉仪六字黑、汉仪黑荔枝体、字体管家方萌
扁平风:方正兰亭黑、微软雅黑、方正幼线体、造字工房悦黑

可免费上用字体:www.freechinesefont.com/tag/commercial-use-ok/

文字填充图

图标篇:
确保图标风格统一,同一图标在同一PPT中的唯一性。

instantlogosearch.com
pictogram2.com/?lang=en

视频库:
coverr

AmCharts

www.amcharts.com/svg-maps/
pixelmap.amcharts.com/

smartmockups.com

magicmockups.com

freedesignresources.net/4-business-card-mock-ups/

JS设计模式 | 2015-05-10

工厂模式

解决了创建多个相似对象的问题,没有解决对象识别的问题(怎样知道一个对象的类型)。

构造函数模式

JS基础面试

JS基础考题:

  • 变量的类型和计算
  • 原型和原型链
  • 作用域和闭包

原型和原型链:

  • Object是超级对象,原型链的顶端到Object.prototype,其中Object.prototype.__proto__为null。
  • 所有引用类型都有一个隐式原型对象:proto
  • 普通函数都有一个prototype对象,他是一个普通对象
function fn () {}
console.log(fn.__proto__ === Function.prototype)
console.log(Function.prototype.__proto__ === Object.prototype)
console.log(Object.prototype.__proto__ === null)

instanceof:

  • fn instanceof Foo查找逻辑
    • 看fn的__Proto__一层层往上,能否对应到Foo.prototype

原型链继承:
子类的原型对象实例化父类。


作用域和闭包:

  • 变量提升的理解
  • this的几种使用场景
  • 10个a标签,点击弹出对应序号
  • 如何理解作用域
  • 实际开发中闭包的应用

执行上下文:

  • 一段script标签或一个函数:生成一个执行上下文

this:

  • this要在执行时才能确认值,定义时无法确认。
  • 使用场景
    • 作为构造函数中执行
    • 作为对象属性执行
    • 作为普通函数执行
    • call bind apply

当前作用域没有定义的变量称为自由变量。

闭包的使用场景:

  • 函数作为函数返回值
  • 函数作为函数参数

异步和单线程

  • 同步异步区别,分别举一个例子(定时器,alert)
  • setTimeout笔试题
  • 前端使用异步的场景(可能发生等待的情况:定时器,ajax请求,事件绑定)

日期:

Math:

数组API:

对象API:


开发环境:加快开发效率

  • IDE(写代码的效率)
  • Git(代码版本管理,多人协作开发)
  • JS模块化
  • 打包工具
  • 上线回滚的流程

IDE:

  • webstorm:收费
  • sublime:轻量级,打开快
  • vscode:微软轻量版VS
  • atom:github开源的编辑器

后面三个编辑器,本身功能不多,需要依赖插件进行编码。


Git:

  • 正式项目都需要代码版本管理、版本回退等
  • 大型项目多人协作,解决代码合并问题
  • git linux同一个作者

免费的git服务:coding.net github.com

一般公司都有自己的git服务器(搭建工作无需了解太多)

git基本命令和操作.....


模块化:
假如有三个JS文件,until.js a-until.js a.js,a.js依赖a-until.js中的函数,a-until.js依赖until.js里的函数

不使用模块化情况:

  • 每个JS文件依次引入,并且until.js a-until.js中外界需要用到的函数都暴露到全局,污染全局变量
  • 依赖关系不明显(负责编写a.js文件的人,并不一定知道需要用到until.js文件)

使用模块化情况:

  • 页面只需引a.js,其他的根据依赖关系自动引入
  • until.js a-until.js中暴露的函数无需做成全局

AMD:require.js

  • 全局define函数
  • 全局require函数
  • 依赖JS会自动、异步加载

CommonJs(服务器端,硬盘同步读取):

  • nodejs模块化规范,前端开发的依赖(插件和库)都可以npm下载(package.json)
  • 构建工具高度自动化(自动编译、压缩、打包)
  • 同步一次性加载

对比:

  • 异步加载JS,用AMD
  • 用npm用CommonJS

构建工具:

  • grunt
  • gulp
  • fis3
  • webpack(目前常用)

上线回滚:

  • 基本流程
  • linux基本命令(买个服务器练练)

基本流程:
上线

  • 将测试完成的代码提交master分支
  • 将当前服务器的代码全部打包并记录版本号,备份
  • master分支代码提交覆盖到线上服务器,生成新的版本号

回滚

  • 将当前服务器的代码全部打包并记录版本号,备份
  • 将备份的上一个版本解压,覆盖到线上服务器,并生成新的版本号

linux基本命令:

# login
ssh name@server # 回车会让你输入用户名、密码

# 创建目录
mkdir content
ls
ll
cd content 
pwd
cd ..
rm -rf content
cp a.js a1.js
mv a1.js src/a1.js
rm a.js

# vi编辑器
vi a.js
i
esc
esc:w 
esc:q
wsc:wq

# 查看文件内容
cat a.js

# 查看前一些
head a.js
head -n 1 a.js
# 查看后面一些
tail a.js
tail -n 2 a.js

# 搜索操作
grep '2' a.js

运行环境:(浏览器)

  • 浏览器通过访问链接来得到页面内容
  • 通过绘制和渲染,显示出页面最终样子
  • 整个过程中需考虑的问题
    • 页面加载过程
    • 性能优化
    • 安全性

页面加载:

  • 输入URL到得到html的详细过程
  • window.onload(页面全部资源加载完才执行,包括媒体资源)和DOMContentLoaded(DOM渲染完即可执行)区别

加载资源的形式、加载一个资源的过程、浏览器渲染页面的过程

加载资源的形式:

  • 输入URL或跳转 加载HTML
  • 加载html中的静态资源

加载一个资源的过程:

  • 浏览器根据DNS服务器得到域名的IP地址
  • 向这个IP的机器发送http请求
  • 服务器收到、处理并返回http请求
  • 浏览器得到返回内容

浏览器渲染页面过程:

  • 根据HTML结构生成生成DOM树
  • 根据CSS生成CSSOM
  • 将DOM和CSSOM整合形成RenderTree(渲染树)
  • 根据 RenderTree 开始渲染和展示
  • 遇到script标签时,会执行并阻塞渲染(JS可能更改DOM树,所以等待JS加载执行)

思考:

  • CSS放到head中(如果不,出现跳动卡东、性能太差、渲染了两次)
  • JS放到body下面(防止页面渲染阻塞)
  • 图片是异步加载

性能优化:

  • 多使用内存、缓存或者其他方法
  • 减少CPU计算、减少网络

从这里入手:

  • 加载页面和静态资源
  • 页面渲染

加载资源优化:

  • 静态资源合并压缩
  • 静态资源缓存(浏览器策略)
  • 使用CDN让资源加载更快
  • 使用SSR后端渲染,数据直接输出到HTML中

渲染优化:

  • CSS放前面,JS放后面
  • 懒加载(图片懒加载,下拉加载更多)
  • 减少DOM查询,对DOM查询做缓存
  • 减少DOM操作,多个操作尽量合并在一起执行
  • 事件节流(多次同一个事件操作,可以设置个定时器(每次判断是否有这个定时器,若有则清除定时器),直到最后一次操作,则会执行一次定时器的逻辑)
  • 尽早执行操作(如DOMContentLoaded)

安全性:
大多是后端做的(数据库,服务器层面的)

  • XSS跨站请求攻击
  • XSRF跨站请求伪造

XSS:

  • 写博客插入一段script标签
  • 攻击代码中,获取cookie,发送自己的服务器

预防:

  • 替换: <为&lt 等
  • 后端替换

XSRF:

  • 登录购物网站,正在浏览商品
  • 付费接口是xxxxx.com/pay?id=100,但没有任何验证
  • 收到一封邮件,隐藏着一个图片,地址就是付费接口

预防:

  • 增加验证流程(输入指纹、密码、短信验证码)
  • 后端验证

面试技巧:

  • 简历
  • 过程

简历:

  • 简洁明了,重点突出项目经历和解决方案(项目简介、用了什么技术、难点,怎么解决)
  • 个人博客放在简历中,定期维护更新博客
  • 开源项目放在简历中,并维护
  • 简历别造假(能力经历真实性)

过程:

  • 如何看待加班(加班就像借钱,救急不救穷)
  • 不可挑战面试官,不要反考面试官
  • 学会给面试官惊喜,但不要太多
  • 遇到不会回答的问题,说出你知道的也可以
  • 谈谈你的缺点(说说你最近正在学什么就可以了)

日记 | 2018-06-12

我查了一下,更新node版本是:

先清除npm缓存:npm cache clean -f

然后安装n模块:npm install -g n

升级node.js到最新稳定版:n stable

n后面也可以跟随版本号比如:n v 3.7.3

AutoHotkey.ahk 文件设置

;Notes: #==win !==Alt 2015-05-20  ^==Ctr  +==shift
;==========================打开常用网址====================================
#m::Run www.amenzai.me
;==========================打开常用软件====================================
!n::run notepad
!l::run, C:\tools\Listary\Listary.exe
!y::run, C:\Users\amenz\AppData\Roaming\baidu\BaiduNetdisk\baidunetdisk.exe
!w::run, C:\mySoftware\Tencent\WeChat\WeChat.exe
!k::run, C:\mySoftware\YoukuClient\proxy\YoukuDesktop.exe
!q::run, C:\mySoftware\Tencent\TIM\Bin\TIM.exe
!v::run, C:\dev\VMware\VMware Workstation\vmware.exe
!x::run, C:\Program Files (x86)\NetSarang\Xshell 5\Xshell.exe
!g::run, C:\mySoftware\TGP\tgp_daemon.exe
!i::run, C:\Users\amenz\AppData\Local\Programs\iceworks-desktop\Iceworks.exe
!v::run, C:\mySoftware\Microsoft VS Code\Code.exe
!m::run, C:\mySoftware\CloudMusic\cloudmusic.exe
!d::run, C:\mySoftware\微信web开发者工具\微信web开发者工具.exe
;==========================================================================

;----------------------------------

::/mail::775166868@qq.com
::/pass::guojinchao.
::/me::http://amenzai.me/
::/cl::console.log();
::/js::javascript:;
::/j::javascript
::/h::html
;-------------------------------------------

;-----复制对应文件路径-----

^+c::
; null= 
send ^c
sleep,200
clipboard=%clipboard% ;%null%
tooltip,%clipboard%
sleep,500
tooltip,
return
;------------------------------------------------

;replace CapsLock to LeftEnter; CapsLock = Alt CapsLock
;$CapsLock::Enter
;LAlt & Capslock::SetCapsLockState, % GetKeyState("CapsLock", "T") ? "Off" : "On"
;!u::Send ^c !{tab} ^v
;------------------------------

^#c::
MouseGetPos, mouseX, mouseY
; 获得鼠标所在坐标,把鼠标的 X 坐标赋值给变量 mouseX ,同理 mouseY
PixelGetColor, color, %mouseX%, %mouseY%, RGB
; 调用 PixelGetColor 函数,获得鼠标所在坐标的 RGB 值,并赋值给 color
StringRight color,color,6
; 截取 color(第二个 color)右边的6个字符,因为获得的值是这样的:#RRGGBB,一般我们只需要 RRGGBB 部分。把截取到的值再赋给 color(第一个 color)。
clipboard = %color%
; 把 color 的值发送到剪贴板
return
;-------------

浏览器端存储方案 | 2018-03-12

Cookie

Cookie 是服务器保存在浏览器的一小段文本信息,每个 Cookie 的大小一般不能超过4KB。浏览器每次向服务器发出请求,就会自动附上这段信息。

window.navigator.cookieEnabled属性返回一个布尔值,表示浏览器是否打开 Cookie 功能。

document.cookie一次只能写入一个 Cookie,而且写入并不是覆盖,而是添加。

document.cookie = 'test1=hello';
document.cookie = 'test2=world';
document.cookie

浏览器向服务器发送 Cookie 的时候,是使用一行将所有 Cookie 全部发送。

GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: cookie_name1=cookie_value1; cookie_name2=cookie_value2
Accept: */*

服务器告诉浏览器需要储存 Cookie 的时候,则是分行指定。

HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: cookie_name1=cookie_value1
Set-Cookie: cookie_name2=cookie_value2; expires=Sun, 16 Jul 3567 06:23:41 GMT

服务器向浏览器发送 Cookie 的时候,除了 Cookie 本身的内容,还有一些可选的属性也是可以写入的,它们都必须以分号开头。

Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]

浏览器根据本地时间,决定 Cookie 是否过期,由于本地时间是不精确的,所以没有办法保证 Cookie 一定会在服务器指定的时间过期。
max-age属性用来指定Cookie有效期,比如60 * 60 * 24 * 365(即一年31536e3秒)。
HttpOnly属性用于设置该Cookie不能被JavaScript读取

Set-Cookie: key=value; HttpOnly

删除一个 Cookie 的唯一方法是设置其expires为一个过去的日期。

document.cookie = 'fontSize=;expires=Thu, 01-Jan-1970 00:00:01 GMT';

数量的限制:
Firefox 是每个域名最多设置50个 Cookie,而 Safari 和 Chrome 没有域名数量的限制。
所有 Cookie 的累加长度限制为4KB。超过这个长度的 Cookie,将被忽略,不会被设置。

同源政策:
浏览器的同源政策规定,两个网址只要域名相同和端口相同,就可以共享 Cookie。不要求协议相同

localStorage&sessionStorage

// 存入
sessionStorage.setItem("key","value");
localStorage.setItem("key","value");

// 读取
var valueSession = sessionStorage.getItem("key");
var valueLocal = localStorage.getItem("key");

// 清除
sessionStorage.removeItem('key');
localStorage.removeItem('key');

// 所有
sessionStorage.clear();
localStorage.clear(); 

// 遍历所有的键
for(var i = 0; i < localStorage.length; i++){
    console.log(localStorage.key(i));
}

// 当储存的数据发生变化时,会触发storage事件。
window.addEventListener("storage",onStorageChange);
function onStorageChange(e) {
     // 保存发生变化的键名
     console.log(e.key);    
// 其他属性
// oldValue:更新前的值。如果该键为新增加,则这个属性为null。
// newValue:更新后的值。如果该键被删除,则这个属性为null。
// url:原始触发storage事件的那个网页的网址。
}

值得特别注意的是,该事件不在导致数据变化的当前页面触发。如果浏览器同时打开一个域名下面的多个页面,当其中的一个页面改变sessionStorage或localStorage的数据时,其他所有页面的storage事件会被触发,而原始页面并不触发storage事件。可以通过这种机制,实现多个窗口之间的通信。所有浏览器之中,只有IE浏览器除外,它会在所有页面触发storage事件。

JS中两个大数求和 | 2018-04-027

/**
 * 计算两个大数的和
 * @param  {[Number]} a [数值A]
 * @param  {[Number]} b [数值B]
 * @return {String]}   [大数和]
 */
function sumBIgNum(a, b) {
  var l1 = 0,
    l2 = 0,
    lt, // 参数小数点位数
    result = '', // 保存最终结果字符串
    carry = 0, // 保存进位
    tmpArr = []; // 临时数组

  // 获取小数位数开始
  try {
    l1 = a.toString().split('.')[1].length
  }
  catch(e) {}
  try {
    l2 = b.toString().split('.')[1].length
  }
  catch(e) {}
  lt = Math.max(l1, l2);
  // 获取小数位数结束
  
  a = (a * Math.pow(10, lt)).toString().split('');
  b = (b * Math.pow(10, lt)).toString().split('');
  while (a.length || b.length || carry) {
    // 对每一项相加
    carry += ~~a.pop() + ~~b.pop(); // ~~'1'等 1  ~~undefined 等 0 ~~'2.33' 等 2
    result = carry % 10 + result; // 每一项相加后的个位
    carry = carry > 9 ? 1 : 0; // 每一项相加和大于10进1
  }
  result.replace(/^0+/, ''); // 去除最终结果前面的'0'
  tmpArr = result.split('');
  if (lt > 0) {
    tmpArr.splice(-lt, 0, '.');
    result = tmpArr.join('');
  }
  return result;
}

VScode个人参数设置

扩展

  • ESLint
  • One Dark Theme
  • Seti-theme
  • Sublime Text Keymap
  • vetur
  • Prettier
  • Bracket Pair Colorizer
  • px2rem
  • auto close tag
  • auto rename tag
  • beautify
  • git history
  • JavaScript (ES6) snippets
  • Markdown Preview Enhanced
  • markdown preview github
  • markdown all in one
  • Terminal
  • Path Intellisense
  • Open in Browser
  • react/redux/react-router
  • editorconfig for vscode

个人设置

// 将设置放入此文件中以覆盖默认设置
{
    "window.zoomLevel": -1,
    "editor.tabSize": 2,
    "workbench.colorTheme": "One Dark Theme",
    "editor.snippetSuggestions": "top",
    "explorer.confirmDragAndDrop": false,
    // "editor.formatOnSave": true,
    // 控制字体系列。
    "editor.fontFamily": "Consolas, 'Courier New', monospace, Dengxian",
    "editor.multiCursorModifier": "ctrlCmd",
    "files.associations": {
        "*.inc": "html",
        "*.ejs": "html",
        "*.wxss": "css",
        "*.wpy": "vue"
    },
    "explorer.confirmDelete": false,
    "vsicons.dontShowNewVersionMessage": true,
    "prettier.singleQuote": true,
    "prettier.semi": false,
    "vetur.format.defaultFormatter.html": "js-beautify-html",
    "vetur.format.defaultFormatterOptions": {
        "wrap_attributes": "force-aligned"
    },
    "emmet.syntaxProfiles": {
        "vue-html": "html",
        "vue": "html",
        "wpy": "html"
    },
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        "html",
        {
            "language": "vue",
            "autoFix": true
        }
    ],
    "eslint.autoFixOnSave": true,
    "beautify.language": {
        "js": {
            "type": [
                "javascript",
                "json"
            ],
            "filename": [
                ".jshintrc",
                ".jsbeautify"
            ]
        },
        "css": [
            "css",
            "less",
            "scss"
        ],
        "html": [
            "htm",
            "html"
        ]
    },
    "git.autofetch": true,
    "git.enableSmartCommit": true,
    "javascript.implicitProjectConfig.experimentalDecorators": true,
    "emmet.includeLanguages": {
        "wxml": "html"
    },
    "minapp-vscode.disableAutoConfig": true
}

参考文章

近期需了解的技术点 | 2018-04-28

和董事长谈了些技术方面的知识,发现有以下几点需要提高:

考研正式启动,这几点了解一下 | 2018-05-05

浙江大学软件学院(330)

专业课:>=120 C语言 数据结构
数学:>=110 高数、线代、数理统计
政治:>=60 找资料背诵
英语:>=60 单词 刷题
总>=350

需要学习哪些知识点?这些知识点在哪些书上?都要做哪些题,做几遍?背哪些东西?
总共的复习时间是几个月?给每一个任务分配多长时间?

最好是把耗神的任务和机械化的任务交错进行

复习前先设定理想分数,把需要掌握的知识点列出来,后面标明它们在过去被考的概率,然后像小坦克碾轧一样,一批一批地消灭掉

  1. 让基础知识、常规题成为主体
  2. 继续加强计算能力的考查
  3. 继续加强应用能力的考查
  4. 考查全面

JS碎碎谈 | 2018-05-06

字符串

是个特殊的数组

var str = 'hello'
str[0] // h

想要使用数组方法需要借助call方法。
unicode编码
\n 反斜杠转义
base64编码:btoa()编码 atob()解码
中文在进行base编码时,先用encodeURIComponent()进行编码,解码一样

对象

创建方法:

var o1 = {};
var o2 = new Object();
var o3 = Object.create(Object.prototype); //用于继承

其他,大括号问题
eval('{foo: 123}') // 123
eval('({foo: 123})') // {foo: 123}

检查变量是否声明:
if ('a' in window) {
// 变量 a 声明过
} else {
// 变量 a 未声明
}

查看对象属性:Object.keys(obj)
删除属性:delete //不能删除继承属性(不可枚举)

var o = Object.defineProperty({}, 'p', {
  value: 123,
  configurable: false
});

o.p // 123
delete o.p // false

in运算符检查对象是否包含对应属性
不能识别继承的,可以用hasOwnproperty()

var o = { p: 1 };
'p' in o // true

for in 循环遍历对象
它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性
它不仅遍历对象自身的属性,还遍历继承的属性(使用构造函数和原型创建的对象)。

with语句
它的作用是操作同一个对象的多个属性时,提供一些书写的方便。

// 例一
with (o) {
  p1 = 1;
  p2 = 2;
}
// 等同于
o.p1 = 1;
o.p2 = 2;

单纯从上面的代码块,根本无法判断x到底是全局变量,还是o对象的一个属性。
这非常不利于代码的除错和模块化,编译器也无法对这段代码进行优化,只能留到运行时判断,这就拖慢了运行速度。
因此,建议不要使用with语句,可以考虑用一个临时变量代替with。

with(o1.o2.o3) {
  console.log(p1 + p2);
}

// 可以写成

var temp = o1.o2.o3;
console.log(temp.p1 + temp.p2);

数组

数组是个特殊的对象
伪数组转为数组
var arr = Array.prototype.slice.call(arrayLike);
数组空位
var arr = [1,,2]
空位就是数组没有这个元素,所以不会被遍历到,而undefined则表示数组有这个元素,值是undefined,所以遍历不会跳过。

函数

给函数参数设置默认值

function f(a){
  a = a || 1;
  return a;
}

f('') // 1
f(0) // 1

改进

function f(a) {
  (a !== undefined && a !== null) ? a = a : a = 1;
  return a;
}

f() // 1
f('') // ""
f(0) // 0

函数参数传递分为:传值传递、传址传递。
函数参数获取的是一个拷贝

arguments

// 用于apply方法
myfunction.apply(obj, arguments).

// 使用与另一个数组合并
Array.prototype.concat.apply([1,2,3], arguments)

变为真正的数组

var args = Array.prototype.slice.call(arguments);

// or

var args = [];
for (var i = 0; i < arguments.length; i++) {
  args.push(arguments[i]);
}

闭包

闭包的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。
请看下面的例子,闭包使得内部变量记住上一次调用时的运算结果。

function createIncrementor(start) {
  return function () {
    return start++;
  };
}

var inc = createIncrementor(5);

inc() // 5
inc() // 6
inc() // 7

闭包的另一个用处,是封装对象的私有属性和私有方法。

function Person(name) {
  var _age;
  function setAge(n) {
    _age = n;
  }
  function getAge() {
    return _age;
  }

  return {
    name: name,
    getAge: getAge,
    setAge: setAge
  };
}

var p1 = Person('张三');
p1.setAge(25);
p1.getAge() // 25

注意,外层函数每次运行,都会生成一个新的闭包,而这个闭包又会保留外层函数的内部变量,所以内存消耗很大。因此不能滥用闭包,否则会造成网页的性能问题。

立即执行函数

var = function(){}();
(function(){})();
+function(){}();

eval函数

将字符串当做语句执行

操作符

void(0)返回undefined

<a href="javascript:void window.open('http://example.com/')">
  点击打开新窗口
</a>
  <a href="javascript:void(0);"></a>

数据类型转换

Number()

// 数值:转换后还是原来的值
Number(324) // 324

// 字符串:如果可以被解析为数值,则转换为相应的数值
Number('324') // 324

// 字符串:如果不可以被解析为数值,返回NaN
Number('324abc') // NaN

// 空字符串转为0
Number('') // 0

// 布尔值:true 转成1,false 转成0
Number(true) // 1
Number(false) // 0

// undefined:转成 NaN
Number(undefined) // NaN

// null:转成0
Number(null) // 0

Number函数将字符串转为数值,要比parseInt函数严格很多。基本上,只要有一个字符无法转成数值,整个字符串就会被转为NaN。

parseInt('42 cats') // 42
Number('42 cats') // NaN

String()
Boolean()

错误处理机制

Error对象

JavaScript解析或执行时,一旦发生错误,引擎就会抛出一个错误对象。JavaScript原生提供一个Error构造函数,所有抛出的错误都是这个构造函数的实例。

var err = new Error('出错了');
err.message // "出错了"

JavaScript的原生错误类型

  1. SyntaxError
    语法错误

  2. ReferenceError
    ReferenceError是引用一个不存在的变量时发生的错误。

  3. TypeError
    TypeError是变量或参数不是预期类型时发生的错误

  4. URIError
    URIError是URI相关函数的参数不正确时抛出的错误

可以人为设置错误信息

new Error('出错了!');
new RangeError('出错了,变量超出有效范围!');
new TypeError('出错了,变量类型无效!');

实例的message属性获取

自定义错误

function UserError(message) {
   this.message = message || "默认信息";
   this.name = "UserError";
}

UserError.prototype = new Error();
UserError.prototype.constructor = UserError;

throw语句

// 抛出一个字符串
throw "Error!";

// 抛出一个数值
throw 42;

// 抛出一个布尔值
throw true;

// 抛出一个对象
throw {toString: function() { return "Error!"; } };

JavaScript引擎一旦遇到throw语句,就会停止执行后面的语句,并将throw语句的参数值,返回给用户。

try catch 结构

为了对错误进行处理,需要使用try...catch结构。

var n = 100;

try {
  throw n;
} catch (e) {
  if (e <= 50) {
    // ...
  } else {
    throw e;
  }
}

finally代码块

try...catch结构允许在最后添加一个finally代码块,表示不管是否出现错误,都必需在最后运行的语句。

openFile();

try {
  writeFile(Data);
} catch(e) {
  handleError(e);
} finally {
  closeFile();
}

内置对象

Object

  1. Object()
Object() // 返回一个空对象
Object() instanceof Object // true

Object(undefined) // 返回一个空对象
Object(undefined) instanceof Object // true

Object(null) // 返回一个空对象
Object(null) instanceof Object // true

Object(1) // 等同于 new Number(1)
Object(1) instanceof Object // true
Object(1) instanceof Number // true

Object('foo') // 等同于 new String('foo')
Object('foo') instanceof Object // true
Object('foo') instanceof String // true

Object(true) // 等同于 new Boolean(true)
Object(true) instanceof Object // true
Object(true) instanceof Boolean // true

如果Object方法的参数是一个对象,它总是返回原对象。

var arr = [];
Object(arr) // 返回原数组
Object(arr) === arr // true

var obj = {};
Object(obj) // 返回原对象
Object(obj) === obj // true

var fn = function () {};
Object(fn) // 返回原函数
Object(fn) === fn // true
  1. Object 对象的静态方法
    Object.keys():不包含不可枚举类型属性
    Object.getOwnPropertyNames():包含
    但两者都不包货继承属性

  2. Object.prototype
    valueOf():返回当前对象对应的值。
    toString():返回当前对象对应的字符串形式。
    toLocaleString():返回当前对象对应的本地字符串形式。
    hasOwnProperty():判断某个属性是否为当前对象自身的属性,还是继承自原型对象的属性。
    isPrototypeOf():判断当前对象是否为另一个对象的原型。
    propertyIsEnumerable():判断某个属性是否可枚举。

Array

Array.isArray()判断是否是数组

sort

[10111, 1101, 111].sort(function (a, b) {
  return a - b;
})
// [111, 1101, 10111]

[
  { name: "张三", age: 30 },
  { name: "李四", age: 24 },
  { name: "王五", age: 28  }
].sort(function (o1, o2) {
  return o1.age - o2.age;
})
// [
//   { name: "李四", age: 24 },
//   { name: "王五", age: 28  },
//   { name: "张三", age: 30 }
// ]

some
some方法是只要有一个数组成员的返回值是true,则整个some方法的返回值就是true,否则false。

var arr = [1, 2, 3, 4, 5];
arr.some(function (elem, index, arr) {
  return elem >= 3;
});
// true

every
every方法则是所有数组成员的返回值都是true,才返回true,否则false。
注意,对于空数组,some方法返回false,every方法返回true,回调函数都不会执行

Number

属性:MAX_VALUE MIN_VALUE
方法:toFixed() toString() toExponential() // 科学计数表示 toPrecision() // 保留有效位数

自定义方法

Number.prototype.add = function (x) {
  return this + x;
};

String

match()
match方法用于确定原字符串是否匹配某个子字符串,返回一个数组,成员为匹配的第一个字符串。如果没有找到匹配,则返回null。

'cat, bat, sat, fat'.match('at') // ["at"]
'cat, bat, sat, fat'.match('xt') // null
var matches = 'cat, bat, sat, fat'.match('at');
matches.index // 1
matches.input // "cat, bat, sat, fat"

match方法还可以使用正则表达式作为参数

search()
等同于match,但是返回值为匹配的第一个位置。如果没有找到匹配,则返回-1。

replace()
用于替换匹配的子字符串,一般情况下只替换第一个匹配(除非使用带有g修饰符的正则表达式)。

'aaa'.replace('a', 'b') // "baa"

正则表达式

test esec

Promise

Promise对象只有三种状态。
异步操作“未完成”(pending)
异步操作“已完成”(resolved,又称fulfilled)
异步操作“失败”(rejected)

var promise = new Promise(function(resolve, reject) {
  // 异步操作的代码

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

promise应用-图片加载

var preloadImage = function (path) {
  return new Promise(function (resolve, reject) {
    var image = new Image();
    image.onload  = resolve;
    image.onerror = reject;
    image.src = path;
  });
};

Ajax

function search(term, onload, onerror) {
  var xhr, results, url;
  url = 'http://example.com/search?q=' + term;

  xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);

  xhr.onload = function (e) {
    if (this.status === 200) {
      results = JSON.parse(this.responseText);
      onload(results);
    }
  };
  xhr.onerror = function (e) {
    onerror(e);
  };

  xhr.send();
}

search("Hello World", console.log, console.error);

or

function search(term) {
  var url = 'http://example.com/search?q=' + term;
  var xhr = new XMLHttpRequest();
  var result;

  var p = new Promise(function (resolve, reject) {
    xhr.open('GET', url, true);
    xhr.onload = function (e) {
      if (this.status === 200) {
        result = JSON.parse(this.responseText);
        resolve(result);
      }
    };
    xhr.onerror = function (e) {
      reject(e);
    };
    xhr.send();
  });

  return p;
}

search("Hello World").then(console.log, console.error);
var xhr = new XMLHttpRequest();

// 指定通信过程中状态改变时的回调函数
xhr.onreadystatechange = function(){
  // 通信成功时,状态值为4
  if (xhr.readyState === 4){
    if (xhr.status === 200){
      console.log(xhr.responseText);
    } else {
      console.error(xhr.statusText);
    }
  }
};

xhr.onerror = function (e) {
  console.error(xhr.statusText);
};

// open方式用于指定HTTP动词、请求的网址、是否异步
xhr.open('GET', '/endpoint', true);

// 发送HTTP请求
xhr.send(null);

跨域

CORS
Q
请求
GET /cors HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
相应
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8

JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。

本地存储

localStorage
sessionStorage
方法:
getItem setItem removeItem clear()

遍历操作

for(var i = 0; i < localStorage.length; i++){
    console.log(localStorage.key(i));
}

storage事件

window.addEventListener("storage",onStorageChange);
// 回调函数接受一个event对象作为参数。这个event对象的key属性,保存发生变化的键名。
function onStorageChange(e) {
     console.log(e.key);    
}

除了key属性,event对象的属性还有三个:
oldValue:更新前的值。如果该键为新增加,则这个属性为null。
newValue:更新后的值。如果该键被删除,则这个属性为null。
url:原始触发storage事件的那个网页的网址。

值得特别注意的是,该事件不在导致数据变化的当前页面触发。如果浏览器同时打开一个域名下面的多个页面,当其中的一个页面改变sessionStorage或localStorage的数据时,其他所有页面的storage事件会被触发,而原始页面并不触发storage事件。可以通过这种机制,实现多个窗口之间的通信。所有浏览器之中,只有IE浏览器除外,它会在所有页面触发storage事件。

IndexedDB

现有的浏览器端数据储存方案,都不适合储存大量数据:Cookie 不超过4KB,且每次请求都会发送回服务器端;LocalStorage 在 2.5MB 到 10MB 之间(各家浏览器不同)。
所以,需要一种新的解决方案,这就是 IndexedDB 诞生的背景。

indexedDB.open()打开数据库

var openRequest = indexedDB.open("test",1);

上面代码表示,打开一个名为test、版本为1的数据库。如果该数据库不存在,则会新建该数据库。如果省略第二个参数,则会自动创建版本为1的该数据库。

打开数据库的结果是,有可能触发4种事件。

success:打开成功。
error:打开失败。
upgradeneeded:第一次打开该数据库,或者数据库版本发生变化。
blocked:上一次的数据库连接还未关闭。

var openRequest = indexedDB.open("test",1);
var db;

openRequest.onupgradeneeded = function(e) {
    console.log("Upgrading...");
}
 
openRequest.onsuccess = function(e) {
    console.log("Success!");
    db = e.target.result;
}
 
openRequest.onerror = function(e) {
    console.log("Error");
    console.dir(e);
}

target.result属性就指向打开的IndexedDB数据库。

indexedDB实例对象的方法:
就是上面的DB

createObjectStore方法
用于创建存放数据的“对象仓库”(object store),类似于传统关系型数据库的表格。

db.createObjectStore("firstOS");

同源限制-跨文档通信

cookie localStorage indexedDB iframe DOM Ajax
document.getElementById("myIFrame").contentWindow.document // 父窗口获取子窗口 不同源把偶偶
window.parent.document.body // 同理

对于完全不同源的网站,目前有两种方法,可以解决跨域窗口的通信问题。

片段识别符(fragment identifier)

http://example.com/x.html#fragment的#fragment
// 父窗口可以把信息,写入子窗口的片段标识符。
var src = originURL + '#' + data;
document.getElementById('myIFrame').src = src;
// 子窗口通过监听hashchange事件得到通知。
window.onhashchange = checkMessage;

function checkMessage() {
var message = window.location.hash;
// ...
}
// 子对父
parent.location.href= target + “#” + hash;

跨文档通信API(Cross-document messaging) window.postMessage

// 父窗口aaa.com向子窗口bbb.com发消息
var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');

window.opener.postMessage('Nice to see you', 'http://aaa.com');

// 父窗口和子窗口都可以通过message事件,监听对方的消息。
<!-- event.source:发送消息的窗口
event.origin: 消息发向的网址
event.data: 消息内容 -->
window.addEventListener('message', function(e) {
  console.log(e.data);
},false);

ajax跨域:

  1. JSONP
  2. Websocket
    origin:在白名单中

单线程模型

JavaScript同时只能执行一个任务,其他任务都必须在后面排队等待。

挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。这种机制就是JavaScript内部采用的Event Loop机制。

消息队列:

运行线程只要发现消息队列不为空,就会取出排在第一位的那个消息,执行它对应的回调函数。等到执行完,再取出排在第二位的消息,不断循环,直到消息队列变空为止。

进入消息队列的消息,必须有对应的回调函数。

另一种情况是setTimeout会在指定时间向消息队列添加一条消息。如果消息队列之中,此时没有其他消息,这条消息会立即得到处理;否则,这条消息会不得不等到其他消息处理完,才会得到处理。因此,setTimeout指定的执行时间,只是一个最早可能发生的时间,并不能保证一定会在那个时间发生。

一旦当前执行栈空了,消息队列就会取出排在第一位的那条消息,传入程序。程序开始执行对应的回调函数,等到执行完,再处理下一条消息。

Event Loop:

所谓Event Loop机制,指的是一种内部循环,用来一轮又一轮地处理消息队列之中的消息,即执行对应的回调函数。

下面是一些常见的JavaScript任务

  • 执行JavaScript代码
  • 对用户的输入(包含鼠标点击、键盘输入等等)做出反应
  • 处理异步的网络请求

同步任务指的是,在JavaScript执行进程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入JavaScript执行进程、而进入“任务队列”(task queue)的任务,只有“任务队列”通知主进程,某个异步任务可以执行了,该任务(采用回调函数的形式)才会进入JavaScript进程

所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。

运行以后的程序叫做“进程”(process)

日记 | 2018-05-14

待办事项

  • 英语第二章过一遍,复习第一章(早上)

  • 张宇视频第二节,对应书籍章节过一遍

英语背诵情况不太好,估计一开始背的太多,难以消化,明天可以用正确的记忆方法,设置好可以接受的量(每天50个),早上背完,晚上复习,以及新的50个,第二天早上复习昨晚的,加新的50个,如此循环一周,周末对每周背诵的进行全面复习。

数学,以后每晚看章视频和书,题目统一周末做。

技术

  1. 语雀里了个团队,互相督促码文。
  2. 出了几个前端面试题,争取早日找到前端

生活
学习还是很容易分心,静不下来,正在慢慢从浮躁中过渡。
估计是想的太多,外界因素干扰,明晚要把心沉下来,专注于高数的学习

个人简历 | 2018-02-27

郭金超个人简历

联系方式

个人信息

技能清单

  • 能够编写语义化的 HTML,模块化的 CSS,完成较复杂的布局
  • 熟悉Less / Sass / Stylus等CSS预处理语言
  • 熟悉原生Javascript,能脱离jQuery等类库编码
  • 了解RequireJS,能运用模块化、面向对象的方式编程
  • 了解AngularJS,熟悉Vue、React
  • 熟悉gulp、webpack等构件工具
  • 可以使用Node配合MongoDB编写接口
  • 了解前端兼容、安全、性能优化方面的一些知识

工作经历

杭州志卓科技股份有限公司( 2017年7月 ~ 2018年4月 )

主要负责云客网、优化师后台的前端开发工作

  1. 使用Vue全家桶(vue、vueRouter、vuex、axios)进行开发
  2. 配合ElementUI组件库,自主编写项目需要的组件

负责云客网、云搜宝网站的活动页面开发,及前端维护

  1. 根据设计稿,使用HTML5 + CSS3编写页面
  2. 使用jquery编写页面交互效果

鼎捷软件股份有限公司( 2017年4月 ~ 2017年7月 )

参与厂内智能物流APP的开发与维护工作

  1. 针对客户需求,编写模块,完成界面与业务逻辑的开发并与后台编写的接口进行对接和调试。
  2. 使用requireJS进行模块管理,运用angularJS编写业务逻辑,使用Ionic开发混合APP,打包及真机测试。

镇江巨和网络科技( 2015年3月 ~ 2016年12月 )

负责公司前端开发业务,实现客户需求

  1. 主要使用html、css、Javascript、Jquery、Ajax等技术对网站进行布局以及交互效果的编写
  2. 使用Git进行代码版本的管理,使用gulp自动化构建工具,加快前端开发的速度
  3. 使用Javascript面向对象编程,对常用功能进行封装,使用接口开发

个人项目

互联网招聘APP

  • 简介:使用react全家桶、node开发的webapp(项目仍在进行中...)
  • 技术点
    • react编写虚拟DOM,react-redux应用数据管理、react-router路由控制
    • 基于Ant Design Mobile开发
    • 服务端使用node的express框架编写接口
    • 采用MongoDB数据库储存数据
  • 成果查看:

微型植物工厂智能监控系统

  • 简介:利用软硬件结合,实现自动监测温室植物各项参数及控制等功能,根据角色分配不同的权限。
  • 技术点
    • 前端使用Vue全家桶开发、webpack构建
    • 服务端配置CORS以及nginx代理解决接口跨域问题
    • 针对重要功能,使用Vue开发了对应的移动端版本
  • 成果查看:

响应式web图书馆

  • 简介:运用响应式web技术改造高校图书馆网站
  • 技术点
    • 采用媒体查询、弹性网格、响应式多媒体技术
    • 针对retina屏的图片、分割线进行优化
    • gulp自动化构建,git版本控制
  • 成果查看:

html5阅读器

  • 简介:用HTML5、Ajax异步、Touch事件等技术,开发Web APP
  • 技术点
    • Zepto基本使用
    • Base64格式的图片
    • HTML5的LocalStorange本地存储
    • Ajax异步请求、Touch事件
    • 模块化编程
  • 成果查看:

自我描述

  • 有UI设计经验,可以更好更快地实现网页的效果和用户体验
  • 遇到问题喜欢到Stackoverflow 、Segmentfault等社区找解决方案
  • 严重强迫症,不能忍受界面一个像素的偏差,同样不能忍受代码格式一个空格的偏差
  • 学习能力强,以上绝大多数的技能都是大二之后自学修得的

致谢

感谢您花时间阅读我的简历,期待能有机会和您共事。

小六课程笔记 | 2018-01-21

阅读的四个问题?

  1. 这本书讲了什么?
  2. 作者详细说了什么
  3. 这本书说的有道理吗
  4. 这本书和你有什么关系

快速阅读

只读自己喜欢、想读的

  1. 五分钟预览(搞清楚读这本书的目的)
  2. 快,不要停(寻找两类关键词、突出的、自身拥有,你没有察觉的-标记之)
  3. 跳读(遇到关键词的地方,方面速度阅读)
  4. 输出(读书笔记、书评、思维导图、视觉手绘)

一周一本书的训练方法

明确目的、设定时间、检视阅读


主题阅读

  • 书单:大神书单、豆瓣、电子书论坛、图书馆借阅
  • 百度搜索(书单+ )
  1. 检视阅读
  2. 建立框架(从一本书开始建立一个小框架)

例如:

  • 思维导图列出书中结构
  • 根据框架进行第二遍阅读,找关键章节,罗列所有观点
  • 筛选观点
  • 主题分享(从主题中选出话题)
  • 发布主题文章

精读一本书:

看、思考、保存、行动

4个人步骤读懂一本书

  1. 提问

制定阅读计划(下一周看完xxx书)
实施(从头到尾阅读一本苏,将其中比较重要的点摘取出来,继承笔记)
回顾和整理(把提前放到印象笔记里的进行整理,比如分组和赋予标签或者画出一张思维导图,将书中的要点以一个整体形式再现出来)

带着问题去读书

  • 我已具备了那些相关知识
  • 我又学到了哪些新的知识

学会给自己出题然后考核自己

  1. 拆解
  2. 练习
  3. 整合

能力
影响力
人脉
如何盈利
营销

个人品牌


成果型:从工作、生活中得到了什么?

制造信息不对称,比别人先懂,先实践,先分享

研究型:钻研某个问题,成为某个领域的专家

模范型:榜样

打造个人能力四个步骤:


天赋、能力、时间

找到HOLD住的方向:


输入(阅读)-整理(思考、实践)-输出(写作)-输入

深度模仿(模仿一群):
找出最厉害的那几个人,模仿他们

学会对每一个技能进行知识管理
获取-整理-分享-利用-创新-提问

刻意练习:
快速迭代,最小可行的产品


建立自己的影响力:

打造自己的爆款产品
多平台占位
系列化输出(输出系统化)

维护自己的人脉

人脉=等价交换

付费、扎堆

盈利

简书-打赏
今日头条-广告
微课

营销

职业规划、选定专业领域、个人品牌价值定位

程序员-项目管理-产品

六个月-写作赚钱

1 为什么要写作
自我?工作?组织
工作之外,做自己喜欢的事,才能找到自我。

工作有考核,自我学习就是用写作检验

写书评40周,锻炼阅读和书写能力

怎么写文章?多读 多写就可以了

2 怎么靠写作赚钱
一日一更,找机会爆款

多平台卡位,不给钱也上场

3 写作的2类型
成果型,研究型

  1. 6要素
    需求:
    人们想了解哪方面的内容

试错:
哪个主题?

文案:
标题勾引、结论硬朗、内容清晰

故事:
让别人讲道理、让我们讲故事
雾满拦江、阿诚

营销:
李叫兽、叶茂中、Frank

服务:
发布只是第一步,需要持续服务来实现用户粘度

模仿大神

忘掉做王红、做产品经理才有星辰大海

如何快速学会任何一门技能

  1. 获取

  2. 整理

  3. 分享

  4. 利用

  5. 创新

  6. 提问

知识管理:
生理需求(温饱)、安全需求(保护、隐私、秩序)、社会需求(爱情、友谊)、尊重需求(受尊重和肯定)、自我实现的需求(发挥潜能、实现理想)

知识分层:
通用的知识-专业基础-专业知识

知识的分类:
会?不会 是否知道

通用技能:沟通能力、时间管理、阅读能力

专业基础:写作能力,知识管理、团队管理

产品管理、项目管理

去哪获取我想要的知识?
阅读、微博、微信、搜搜、晕课堂、社群

阅读的分类:
主食:生存需求-美食:**需求-蔬果:工具需求-甜点:休闲需求

随时随地收集信息:剪藏等(使用印象笔记来做知识收集)
花瓣收集图片信息
使用Calibre管理电子书
扫描纸上的有用信息,实现共享
Pocket 印象笔记 有大运笔记 为知笔记

收藏完以后:

分门别类,命好名(定义好命名规则)
文件夹目录+GIT管理自己的文件

收集和整理 分享和利用

例如时间管理的知识管理:A-时间管理 A1-时间管理-收集 整理 分享(添加个分享的名字) 利用

快速在自己的知识库搜索信息

学了为什么老是记不住?
主动学习VS被动学习
主动:训练他人、实际演练、做的过程中学、小组讨论
被动:示范演示、声音图片、阅读、听讲

上述都依次递减的

知识的分享:

  1. 线下社群分享
  2. 线上分享
  3. 自媒体
  4. 个人电台
  5. 写作

如何涨工资

行动 转化

知识的创新
演化:基于现有知识的突破
跨界: 跨知识领域进行创新

从自己的专业领域出发
每一个技能都可以用知识管理的6个步骤进行管理

视觉呈现、PPT、思维导图、知识管理、高效阅读、时间管理、行动学习、写作

小程序常用方法、API 基于Wepy | 2018-04-17

// 一些属性方法
this.$wxapp
this.$pages
this.$invoke('./ComB', 'func1', 'p1', 'p2');
this.$broadcast('broadcast-event', 'p1', 'p2');
this.$emit('emit-event', 'p1', 'p2');
this.$apply();
this.$nextTick().then(function() {
  console.log('UI updated');
});

// 路由
this.$redirect('./page2', {
  a: 1,
  b: 2
});
this.$redirect({
  url: './pages?a=1&b=2'
});
this.$navigate(url: String | Object, [params: Object])
this.$switch(url: String | Object)
wepy.navigateBack({
  delta: 2 // 返回的页面数,如果 delta 大于现有页面数,则返回到首页。
})
wepy.reLaunch({ // 关闭所有页面,打开到应用内的某个页面。
  url: 'test?id=1'
})


// 登录
wx.login().then(res => {
  console.log(res)
  if (res.code) {
    wepy.getUserInfo().then(res => {
      console.log(res)
      wepy.request('').then(res => {
        console.log(res)
      })
    })
  } else {
    console.log('登录失败!' + res.errMsg)
  }
})

// 授权
wepy.authorize({
  scope: 'scope.record'
}).then(res => {
  console.log(res)
})

// 转发
wepy.showShareMenu({
  withShareTicket: true
})
wepy.hideShareMenu()

onShareAppMessage(res) {
  if (res.from === 'button') {
    // 来自页面内转发按钮
    console.log(res.target)
  }
  return {
    title: 'eeeeee',
    // imageUrl: ''
    path: '/pages/draw/draw',
    success(res) {
      console.log(res)
    }
  }
}

// 请求
const requestTask = wepy.request({
  url: 'test.php', //仅为示例,并非真实的接口地址
  method: 'GET',
  data: {
    x: '',
    y: ''
  },
  header: {
    'content-type': 'application/json'
  }
}).then(res => {
  console.log(res.data)
})
requestTask.abort() // 取消请求任务

// 本地存储
wx.setStorage({
  key: "key",
  data: "value"
})
wx.setStorageSync('key', 'value')

wx.getStorage({
  key: 'key',
  success: function(res) {
    console.log(res.data)
  }
})

wx.getStorageInfo({
  success: function(res) {
    console.log(res.keys)
    console.log(res.currentSize)
    console.log(res.limitSize)
  }
})

wx.removeStorage({
  key: 'key',
  success: function(res) {
    console.log(res.data)
  }
})

try {
  wx.removeStorageSync('key')
} catch (e) {
  // Do something when catch error
}

wx.clearStorage()

// 界面交互 弹窗等
wx.showToast({
  title: '成功',
  icon: 'success', // loading none
  image: '',
  mask: false, // 默认为false
  duration: 2000
})
wx.hideToast()

wx.showLoading({
  title: '加载中',
  mask: false
})
wx.hideLoading()

wx.showModal({
  title: '提示',
  content: '这是一个模态弹窗',
  showCancel: true, // 是否显示取消按钮
  cancelText: '取消',
  cancelColor: '#444',
  confirmText: '确认',
  confirmColor: '#3CC51F',
  success: function(res) {
    if (res.confirm) {
      console.log('用户点击确定')
    } else if (res.cancel) {
      console.log('用户点击取消')
    }
  }
})

wx.showActionSheet({
  itemList: ['A', 'B', 'C'], // 按钮的文字数组
  itemColor: '#444', // 按钮的文字颜色
  success: function(res) {
    console.log(res.tapIndex) // 用户点击的按钮,从上到下的顺序,从0开始
  },
  fail: function(res) {
    console.log(res.errMsg)
  }
})

// 在当前页面显示导航条加载动画。
wx.showNavigationBarLoading()
  // 隐藏
wx.hideNavigationBarLoading()

wepy.setTabBarBadge({
  index: 0, // tabBar的哪一项,从左边算起
  text: '1' // 显示的文本,超过 3 个字符则显示成“…”
})
wx.removeTabBarBadge({
  index: 0 // tabBar的哪一项,从左边算起
})
wx.showTabBarRedDot({
  index: 0
})
wx.hideTabBarRedDot({
  index: 0
})

// 点击 tab 时触发
onTabItemTap(item) {
  console.log(item.index)
  console.log(item.pagePath)
  console.log(item.text)
}

// 动画使用方法
// <view animation="{{animationData}}" style="background:red;height:100rpx;width:100rpx"></view>
{
  data: {
    animationData: {}
  },
  onShow: function() {
    var animation = wx.createAnimation({ // 创建动画
      duration: 1000,
      timingFunction: 'ease',
      // delay: '' 动画延迟时间
    })

    this.animation = animation

    animation.scale(2, 2).rotate(45).step()

    this.setData({
      animationData: animation.export()
    })

    setTimeout(function() {
      animation.translate(30).step()
      this.setData({
        animationData: animation.export()
      })
    }.bind(this), 1000)
  },
  rotateAndScale: function() {
    // 旋转同时放大
    this.animation.rotate(45).scale(2, 2).step()
    this.setData({
      animationData: this.animation.export()
    })
  },
  rotateThenScale: function() {
    // 先旋转后放大
    this.animation.rotate(45).step()
    this.animation.scale(2, 2).step()
    this.setData({
      animationData: this.animation.export()
    })
  },
  rotateAndScaleThenTranslate: function() {
    // 先旋转同时放大,然后平移
    this.animation.rotate(45).scale(2, 2).step()
    this.animation.translate(100, 100).step({ duration: 1000 })
    this.setData({
      animationData: this.animation.export()
    })
  }
}

// 回到顶部
wepy.pageScrollTo({
  scrollTop: 0,
  duration: 300
})

// 自动下拉刷新
wepy.startPullDownRefresh()
  // 停止
wepy.stopPullDownRefresh()

// 页面相关事件方法
onPullDownRefresh: function() {
  // Do something when pull down.
}
onReachBottom: function() {
  // Do something when page reach bottom.
}
onShareAppMessage: function() {
  // return custom share data when user share.
}
onPageScroll: function() {
  // Do something when page scroll
}


// 登陆
wepy.login().then(res => {
  console.log('loginInfo', res)
  if (res.code) {
    wx.request({
      url: 'https://test.com/onLogin',
      data: {
        code: res.code
      }
    })
  } else {
    console.log('登录失败!' + res.errMsg)
  }
})

// 获取用户信息
wepy.getUserInfo().then(res => {
  console.log('userInfo', res)
  this.globalData.userInfo = res.userInfo
})

// 微信支付
wepy.requestPayment({
  'timeStamp': '',
  'nonceStr': '', // 随机字符串,长度为32个字符以下。
  'package': '', // 统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
  'signType': 'MD5',
  'paySign': '', // 签名
  'success':function(res){
  },
  'fail':function(res){
  }
})

wepy使用指南 | 2018-03-26

安装

# 安装工具
npm install wepy-cli -g

# 查看项目模板
wepy list

# 初始化项目
wepy init standard myproject

cd myproject
npm  install

# 实时监控修改并编译
wepy build --watch

两个文件示例

app.wpy

<style lang='less'>
.container {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  box-sizing: border-box;
}
</style>

<script>
import wepy from 'wepy'
import 'wepy-async-function'

export default class extends wepy.app {
  config = {
    // 配置需要展示的页面路径
    pages: [
      'pages/index'
    ],
    window: {
      // backgroundColor: '#fff', 窗口背景色
      // enablePullDownRefresh 是否开启下拉刷新
      // onReachBottomDistance 页面上拉触底事件触发时距页面底部距离,单位为px
      backgroundTextStyle: 'light', // 下拉 loading 的样式,仅支持 dark/light
      navigationBarBackgroundColor: '#fff', // 导航栏背景色
      navigationBarTitleText: 'WeChat', // 文字内容
      navigationBarTextStyle: 'black' // 导航栏标题色
    },
    tabBar: {
      color: '#888', // 文字
      selectedColor: '#89bdf7', // 选中文字
      backgroundColor: '#fff',
      borderStyle: 'white', // 上边框颜色 white black
      position: 'bottom', // 'top',   default: 'bottom' 
      list: [{
          pagePath: 'pages/index/index', // 点击跳转的页面路径
          text: '首页',
          iconPath: 'images/home.png',
          selectedIconPath: 'images/home_active.png'
      }]
    },
    debug: true,
    networkTimeout: {
      // 相关请求超时时间
      request: 10000,
      connectSocket: 10000,
      uploadFile: 10000,
      downloadFile: 10000
    }
  }

  globalData = {
    userInfo: null
  }

  constructor () {
    super()
    this.use('promisify') // 开启promise
    this.use('requestfix')
    this.intercept('request', {
      // 发出请求时的回调函数
      config (p) {
          // 对所有request请求中的OBJECT参数对象统一附加时间戳属性
          p.timestamp = +new Date();
          console.log('config request: ', p);
          // 必须返回OBJECT参数对象,否则无法发送请求到服务端
          return p;
      },
      // 请求成功后的回调函数
      success (p) {
          // 可以在这里对收到的响应数据对象进行加工处理
          console.log('request success: ', p);
          // 必须返回响应数据对象,否则后续无法对响应数据进行处理
          return p;
      },
      // 请求失败后的回调函数
      fail (p) {
          console.log('request fail: ', p);
          // 必须返回响应数据对象,否则后续无法对响应数据进行处理
          return p;
      },
      // 请求完成时的回调函数(请求成功或失败都会被执行)
      complete (p) {
          console.log('request complete: ', p);
      }
    })
  }
  onLaunch() {
    this.testAsync()
  }

  sleep (s) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('promise resolved')
      }, s * 1000)
    })
  }

  async testAsync () {
    const data = await this.sleep(3)
    console.log(data)
  }

  getUserInfo(cb) {
    const that = this
    if (this.globalData.userInfo) {
      return this.globalData.userInfo
    }
    wepy.getUserInfo({
      success (res) {
        that.globalData.userInfo = res.userInfo
        cb && cb(res.userInfo)
      }
    })
  }
}
</script>

index.wpy

<!-- 存在src属性且有效时,会忽略内联代码。 -->
<style lang="less">
  .userinfo {
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  .userinfo-avatar {
    width: 80rpx;
    height: 80rpx;
    border-radius: 50%;
  }

  .userinfo-nickname {
    color: #aaa;
  }
</style>
<template>
  <!-- 循环渲染用 repeat标签 -->
  <!-- <repeat for="{{list}}" key="index" index="index" item="item">
      <child :item="item">这个是引入的组件 传递了item数据</child>
  </repeat> -->

  <!-- <view @tap="tapName({{index}}, 'wepy', 'otherparams')"> Click me! </view> -->
  <view class="container">
    <view class="userinfo" @tap="handleViewTap">
      <image class="userinfo-avatar" src="{{ userInfo.avatarUrl }}" background-size="cover"/>
      <view class="userinfo-nickname">{{ userInfo.nickName }}</view>
    </view>
    
    <panel>
      <view class="title" slot="title">测试数据绑定</view>

      <text class="info">{{normalTitle}}</text>
      <text class="info">{{setTimeoutTitle}}</text>
      <text class="info">{{mixin}}</text>
      <text class="info">{{mynum}}</text>
      <text class="info">{{now}}</text>
      <button @tap="plus('a')" size="mini">  +  </button>
    </panel>

    <panel>
      <view class="title" slot="title">其它测试</view>
      <button @tap="toast" size="mini">第三方组件</button>
      <button @tap="communicate" size="mini">组件通信</button>
      <button @tap="tap" size="mini">混合TAP事件</button>
    </panel>

    <panel>
      <view class="title" slot="title">测试并发网络请求</view>
      <view>返回结果: <text>{{netrst}}</text></view>
      <button @tap="request" size="mini"> 点我发起10个请求 </button>
    </panel>

    <panel>
      <view class="title" slot="title">测试组件</view>

      <text class="testcounter">计数组件1: </text>
      <view class="counterview">
        <counter1 @index-emit.user="counterEmit" />
      </view>

      <text class="testcounter">计数组件2: </text>

      <view class="counterview">
        <counter2 :num.sync="mynum"></counter2>
      </view>
    </panel>

    <panel>
      <view class="title" slot="title">测试组件Repeat</view>
      <repeat for="" index="index" item="item" key="key">
        <group :grouplist="item" :indexa="index"></group>
      </repeat>
    </panel>

    <panel>
      <view class="title" slot="title">测试列表</view>
      <list></list>
    </panel>

    <toast />
  </view>
</template>

<script>
  // 异步函数中更新数据的时,必须手动调用$apply方法,才会触发脏数据检查流程的运行
  // wepy.request('xxxx').then((d) => console.log(d));
  // this.$parent 获取APP实例中的方法 数据
  
  import wepy from 'wepy'
  import Panel from '@/components/panel' // alias example
  import Counter from 'counter' // alias example
  import List from '../components/list' // aliasFields example
  import moduleA from 'module-a' // aliasFields ignore module example
  import Group from '../components/group'
  import Toast from 'wepy-com-toast'
  import testMixin from '../mixins/test'

  console.log('moduleA ignored: ', moduleA) // => moduleA ignored: {}


  export default class Index extends wepy.page {
    // 页面配置
    config = {
      navigationBarTitleText: 'test'
    }
    // 组件调用
    // 组件传值: 静态传值、动态传值
    // 静态(只能传递String字符串类型): <child title="mytitle"></child>  props = {title: String };
    // 动态:<child :title="parentTitle" :syncTitle.sync="parentTitle" :twoWayTitle="parentTitle"></child>
    // child.wpy
    // props = {
    //     // 静态传值
    //     title: String,

    //     // 父向子单向动态传值
    //     syncTitle: {
    //         type: String,
    //         default: 'null'
    //     },

    //     twoWayTitle: {
    //         type: Number,
    //         default: 'nothing',
    //         twoWay: true
    //     }
    // };
    // this.$parent.parentTitle = 'p-title-changed'; 拿到父组件数据,进行更改
    // this.$parent.$apply(); 同步
    components = {
      panel: Panel,
      counter1: Counter, // 为两个相同组件的不同实例分配不同的组件ID,从而避免数据同步变化的问题
      counter2: Counter,
      list: List,
      group: Group,
      toast: Toast
    }

    // 公用属性、方法、事件对象
    // methods响应事件 先响应组件本身响应事件,然后再响应混合对象中响应事件
    mixins = [testMixin]

    // 内部数据
    data = {
      mynum: 20,
      userInfo: {
        nickName: '加载中...'
      },
      normalTitle: '原始标题',
      setTimeoutTitle: '标题三秒后会被修改',
      count: 0,
      netrst: '',
      groupList: [
        {
          id: 1,
          name: '点击改变',
          list: [
            {
              childid: '1.1',
              childname: '子项,点我改变'
            }, {
              childid: '1.2',
              childname: '子项,点我改变'
            }, {
              childid: '1.3',
              childname: '子项,点我改变'
            }
          ]
        },
        {
          id: 2,
          name: '点击改变',
          list: [
            {
              childid: '2.1',
              childname: '子项,点我改变'
            }, {
              childid: '2.2',
              childname: '子项,点我改变'
            }, {
              childid: '2.3',
              childname: '子项,点我改变'
            }
          ]
        },
        {
          id: 3,
          name: '点击改变',
          list: [
            {
              childid: '3.1',
              childname: '子项,点我改变'
            }
          ]
        }
      ]
    }

    // 计算属性 和vue一样
    computed = {
      now () {
        return +new Date()
      }
    }

    watch = {
      // num (newValue, oldValue) {
      //     console.log(`num value: ${oldValue} -> ${newValue}`)
      // }
    }

    // 页面绑定事件对应的处理函数
    methods = {
      plus () {
        this.mynum++
      },
      toast () {
        let promise = this.$invoke('toast', 'show', {
          title: '自定义标题',
          img: 'https://raw.githubusercontent.com/kiinlam/wetoast/master/images/star.png'
        })

        promise.then((d) => {
          console.log('toast done')
        })
      },
      tap () {
        console.log('do noting from ' + this.$name)
      },
      communicate () {
        console.log(this.$name + ' tap')

        this.$invoke('counter2', 'minus', 45, 6)
        this.$invoke('counter1', 'plus', 45, 6)

        this.$broadcast('index-broadcast', 1, 3, 4)
      },
      request () {
        let self = this
        let i = 10
        let map = ['MA==', 'MQo=', 'Mg==', 'Mw==', 'NA==', 'NQ==', 'Ng==', 'Nw==', 'OA==', 'OQ==']
        while (i--) {
          wepy.request({
            url: 'https://www.madcoder.cn/tests/sleep.php?time=1&t=css&c=' + map[i] + '&i=' + i,
            success: function (d) {
              self.netrst += d.data + '.'
              self.$apply()
            }
          })
        }
      },
      counterEmit (...args) {
        let $event = args[args.length - 1]
        console.log(`${this.$name} receive ${$event.name} from ${$event.source.$name}`)
      }
    }

    // WePY组件事件处理函数对象,存放响应组件之间通过$broadcast、$emit、$invoke所传递的事件的函数
    // this.$broadcast('some-event', arg) 父亲向所有孩子
    // this.$emit('some-event', arg) 孩子向所有父亲
    // this.$invoke('Acomponent path', 'someMethod' ,arg) A组件调用B组件
    events = {
      'index-emit': (...args) => {
        let $event = args[args.length - 1]
        console.log(`${this.$name} receive ${$event.name} from ${$event.source.$name}`)
      }
    }

    // 生命周期函数
    onLoad() {
      let self = this
      this.$parent.getUserInfo(function (userInfo) {
        if (userInfo) {
          self.userInfo = userInfo
        }
        self.normalTitle = '标题已被修改'

        self.setTimeoutTitle = '标题三秒后会被修改'
        setTimeout(() => {
          self.setTimeoutTitle = '到三秒了'
          self.$apply()
        }, 3000)

        self.$apply()
      })
    }
  }
</script>

小程序总结 | 2018-03-21

APP()

App({
  onLaunch: function(options) {
    // 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
  },
  onShow: function(options) {
      // 当小程序启动,或从后台进入前台显示,会触发 onShow
  },
  onHide: function() {
      // 当小程序从前台进入后台,会触发 onHide
  },
  onError: function(msg) {
    // 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
    console.log(msg)
  },
  globalData: 'I am global data' // 可以添加任意的函数或数据到 Object 参数中,用 this 可以访问
})

getApp()

// other.js
var appInstance = getApp()
console.log(appInstance.globalData) // I am global data

Page()

//index.js
Page({
  data: {
    text: "This is page data."
  },
  onLoad: function(options) {
    // 监听页面加载
  },
  onReady: function() {
    // 监听页面初次渲染完成
  },
  onShow: function() {
    // 监听页面显示
  },
  onHide: function() {
    // 监听页面隐藏
   // 当navigateTo或底部tab切换时调用。
  },
  onUnload: function() {
    // 监听页面卸载
   // 当redirectTo或navigateBack的时候调用。
  },
  onPullDownRefresh: function() {
    // 监听用户下拉动作
  },
  onReachBottom: function() {
    // 页面上拉触底事件的处理函数
  },
  onShareAppMessage: function () {
   // 用户点击右上角转发
   return {
      title: '自定义转发标题',
      path: '/page/user?id=123'
    }
  },
  onPageScroll: function() {
    // 页面滚动触发事件的处理函数
  },
  onTabItemTap(item) {
  // 当前是 tab 页时,点击 tab 时触发
    console.log(item.index)
    console.log(item.pagePath)
    console.log(item.text)
  },
  // Event handler.
  viewTap: function() {
    this.setData({
      text: 'Set some data for updating view.'
    }, function() {
      // this is setData callback
    })
  },
  customData: { // 可以添加任意的函数或数据到 object 参数中,在页面的函数中用 this 可以访问
    hi: 'MINA'
  }
})
  • Page.prototype.route
    • route 字段可以获取到当前页面的路径
  • Page.prototype.setData()

路由

参考链接

模块化

// common.js
function sayHello(name) {
  console.log(`Hello ${name} !`)
}
function sayGoodbye(name) {
  console.log(`Goodbye ${name} !`)
}

module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye

---
var common = require('common.js')
Page({
  helloMINA: function() {
    common.sayHello('MINA')
  },
  goodbyeMINA: function() {
    common.sayGoodbye('MINA')
  }
})

不支持直接引入 node_modules,需要使用到 node_modules 时候建议拷贝出相关的代码到小程序的目录中。

WXML

<!--wxml-->
// 列表循环
<view wx:for="{{array}}"> {{item}} </view>

// 条件渲染
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>

// 事件绑定
<view bindtap="add"> {{count}} </view>

// page.js
Page({
  data: {
    array: [1, 2, 3, 4, 5],
    view: 'MINA',
    count: 1
  },
  add: function(e) {
    this.setData({
      count: this.data.count + 1
    })
  }
})

常用Vue组件库,引入对比 | 2018-05-18

elementUI

// 全部引入
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

// 按需引入
import { Button, Select } from 'element-ui';
// 插件配置示例
Vue.use(Button);
Vue.use(Loading.directive);

Vue.prototype.$loading = Loading.service;
Vue.prototype.$msgbox = MessageBox;
Vue.prototype.$alert = MessageBox.alert;
Vue.prototype.$confirm = MessageBox.confirm;
Vue.prototype.$prompt = MessageBox.prompt;
Vue.prototype.$notify = Notification;
Vue.prototype.$message = Message;

按需引入:

npm install babel-plugin-component -D
// .babelrc
{
  "presets": [["es2015", { "modules": false }]],
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

vux

// 使用插件
import AlertPlugin from 'vux/src/plugins/Alert'
import ToastPlugin from 'vux/src/plugins/Alert'
or
import { AlertPlugin, ToastPlugin } from 'vux'

// 使用组件
import { Group, Cell } from 'vux'

vant

// 全部引入
import Vant from 'vant';
import 'vant/lib/vant-css/index.css';

// 按需引入
import Button from 'vant/lib/button';
import 'vant/lib/vant-css/base.css';
import 'vant/lib/vant-css/button.css';
or 
import { Button } from 'vant';

工具

1、img-2

一个 WebComponent 组件,使用 取代 ,可以只显示第一屏的图片,其他图片通过 Web Worker 预下载,一旦该图片进入可视区域后再加载显示。

2、ReLaXed

一个将 HTML 文件转为 PDF 文件的命令行工具。

3、IPBlade

有的网络服务限制 IP 地址,比如只有**的 IP 地址才能使用。这个 Chrome 插件点击一下就可以改变浏览器的 IP 地址,从而绕过这些限制。免费版只能改成美国的 IP 地址。

4、.gitignore 文件的命令行生成工具

.gitignore 文件设置了哪些文件可以不用进入 Git 版本管理。这个命令行工具可以根据项目类型,自动生成 .gitignore 文件。

5、tlsh-js

一个生成字符串哈希的 JavaScript 库。它的特点是,字符串越相似,或者重复同样的模式,生成的哈希也越相似,可以用来计算两个字符串的相似程度。

6、wired-elements

一个有手绘效果的网页组件库。但是,真正特别之处在于它的底层是 Web components,让我们看到了除了React/Vue之外,还有其他的路。

7、sucrase

一个新的 JavaScript 转码器,号称比 Babel 快20倍。

8、Reach router

React router 的两位创始人闹翻了,其中一位另起门户,写了一个功能相同的 Reach router

日记 | 2018-05-15

待办事项

  • 英语LIST2(早上)

  • 张宇视频第三讲,对应书籍章节过一遍(晚上)

英语LIST2未复习完一遍,明早继续
数学视频过完,书籍未完成,明晚补加第四讲

技术

  1. 发现一个开源技术文档分享网站,很不错,阅读体验很好
  2. Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。
    返回值是一个 DOMRect 对象,包含了一组用于描述边框的只读属性——left、top、right和bottom,单位为像素。

生活

最近想的太多,要慢慢沉下心了。
大脑每天不要输入太多无关东西,毕竟人脑每天记忆量有限。

日记 | 2018-05-31

技术

一些分辨率术语的含义 :

  • 720p: 1280 x 720, 称为 HD
  • 1080p: 1920 x 1080, 称为 FULL HD
  • 1440p: 2560 x 1440, 称为 QHD 或 Quad HD,即4倍的HD
  • 2160p: 3840 x 2160, 称为 4K
  • 4320p: 7680 x 4320, 称为 8K

向服务端传递的数据格式:
ArrayBufferView, Blob, DOMString, 或者 FormData 类型的数据。
Navigator.sendBeacon()

个人名片
https://about.me/amenzai

日记 | 2018-05-17

待办事项

  • 英语LIST3(早上)

  • 张宇视频第四讲,对应书籍章节过一遍(晚上)

技术

生活

UI笔记 | 2018-01-21

  1. 了解就业现状及行业需求

大学生毕业人数多,企业裁员,薪资预期不要太高,行业需求看招聘岗位要求。

关注行业讯息,同行动态,多看好的APP,了解可用性和用户体验。知道该怎么设计,这都是在看APP多的话就会在脑袋里留下印象。

  1. 了解你的企业结构

产品经济时代:以产品为中心的设计,直接看到实物,用户围观。

体验经济时代:只有元素,以用户为中心的设计,用户参与,产品的手段。买的不是产品,是体验。

是卖产品还是卖用户直接的体验。用户直接参与进来,例如那些我们可以自己写内容的产品(微博,博客,社交等)

流程职位。

  1. 了解自己充实自己
    专业能力,视野,创造力,项目能力,沟通表达能力

经验,动力

  1. 提升用户体验是关键

UI设计8件事

怎么火的

百度指数:去找关键词搜索量可以看出他的流行度。

工资为啥高

互联网创业高潮让UI设计师变得炙手可热。

非科班的UI设计师都是来自哪里

源自工业设计,下一个时代是移动互联网,好多人开始转行,平面-网页-UI,培训班出来。

传统设计师一定能做好UI吗

传统设计师是为了推广和宣传,UI为了服务。

平面都是个性 创意,有个人特点。 UI都是形式服务于内容,团队协同设计。

你真的了解UI设计的工作吗

boss-pm-ue-ui-RD-QA-OP

老板有钱、点子、资源;产品需求文档,时间排期;低保真原型,交互说明;视觉设计稿,视觉规范,切图标注适配;代码实现;QA测试,找BUG,可用性测试;产品运营,用户反馈。

UI设计还能火多久

硬件发展的话,就需要UI,只要有操作面板,可视化界面。智能家居、可穿戴设备、VR/AR。传统公司转型。
用户体验设计师,产品思维是未来所有行业的思维方式。
代码实现类设计师
全栈设计师
3D表现类设计师
运用手绘类UI:情感类插图
动效表现设计师,直观表现交互思维

野路子怎么学UI

英语:Medium Dribbble
找参考,找资料,英文非常重要。
看书:用户体验的书籍,交互设计精髓,用户体验设计,用户体验要素,别让我思考,设计师要懂心理学。
手机不去自动更新,每次更新记得截取前一版本的界面设计。
定个小目标,每天督促自己做个小案例。

关于UI市场上的两种声音

产品思维,做产品,别重视软件视觉操作。

圈子学习,社交圈子。
插件学习,快速学习能力,发现问题,解决问题。别再去系统学习完然后在解决问题。
学完以后,出教程。

什么是UI设计

  1. 表现层的设计
  2. 以最大化的商业价值为目的
  3. 是科学与艺术结合的综合技术

UI设计的日常工作

设计出用户内心期望的产品。

风格定位、产品迭代、BANNER、专题活动

做好风格定位的两个关键点:

  1. 抓准方向,根据产品的本质,推导出埋藏在用户内心根本的期望。
  2. 极致的技术,如何把想法实现出来,看作品,找类似,成为以后的设计原则。

流程:

  1. 分析-产品属性-目标用户-竞争产品-产出关键词
  2. 创作-围绕关键词-大胆设计
  3. 筛选-用户调研
  4. 规范-设计规范约束
  5. 制作-界面设计

产品迭代:

诞生-成长-成熟-结束

UI设计的发展路径

PS-临摹-理论-沉淀自己的作品

UI设计师的必备习惯

储备素材-平常整理素材库-创作时的参考

分出它对应的学习点(分类):
交互、文案、摄影、字体设计、活动、配色、BANNER、印刷品、web产品、欢迎页、主界面、ICON、动效

设计思考
培养自己设计的敏感度,感受生活中的美和丑,什么东西让我们产生这种感受,多思考其中原因。

了解行业
通过哪些网站和APP关注相应信息。

面试那些事

准备面试材料

5大系统

修炼设计技法

新闻

1、未来的网站注册流程

目前,W3C 正在设计一个基于密钥的网站注册流程。以后,注册用户时不需要密码,也不用担心破解。
简单说,就是注册的时候,浏览器自动生成公钥和私钥,然后把公钥发给服务器,私钥保留在本地。以后登录的时候,用户只需要输入用户名,浏览器用私钥加密后发给服务器,如果能被公钥解开,就证明了用户的身份。

2、AI 的发展速度

有研究称,2012年开始, AI 的运算速度每过3.5个月翻一倍,至今已经增加了30多万倍。相比之下,摩尔定律(每18个月翻一倍)简直慢得不值一提。要是按照摩尔定律,AI 的运算速度只会增长12倍。

总之,AI 的进化速度远远快于人类的想象,在你不知不觉之间,机器的聪明已经超乎想象。

3、打印的卵巢

美国科学家使用3D打印机做出来的明胶卵巢,替换掉小白鼠的天然卵巢,结果居然有效。7只实验老鼠有3只产下了健康的后代。

《未来简史》描述的场景正在变成现实:未来的人们不再是纯自然的产物,而是半自然、半人工的一种新人类。

4、Firefox 浏览器支持 Web Components

Firefox 浏览器最新的 Nightly测试版本 已经支持 Web Components。这是 Chrome 浏览器5年前开始推广的一种新技术,现在除了 Edge 浏览器,其他主要浏览器都已经支持了。

Web Components 是浏览器原生的组件解决方案。如果你愿意对新技术下赌注,可以考虑它。

5、JavaScript 的新数据类型:大整数 BigInt

经过很长一段时间的测试以后,V8 引擎正式宣布支持 JS 的第8种数据类型:大整数 BigInt。从此,JS 可以精确表示任意位数的整数,再也不受64位双精度浮点数格式的限制了。

6、谷歌的人工智能客服 Google Duplex

谷歌宣布了人工智能客服系统 Google Duplex。以后,你打电话订餐、投诉、咨询,跟你交谈的都不是真人,而是一个软件。客服这个行业从此要被消灭了。

另一方面,如果你意识不到对方是软件,就意味着它通过了图灵测试。这是不是意味着,以后软件冒充人已经没问题了?

7、机器宠物狗(视频)

索尼公司推出了新一代机器宠物狗 aibo(爱宝),根据产品主页的介绍,它跟人的互动达到了前所未有的程度,已经很接近真实的狗。

人跟机器人做伴侣的时代真的不远了。

8、技术发展例子

举例来说,我看到一个消息,麻省理工学院发明了一种远程充电技术,可以隔空用无线电波给微型电子设备充电。他们做了一个实验,把传感器埋入一头猪的体内,大约皮下10公分的地方,然后相隔一米发送无线电波,居然就把传感器驱动起来了!

这意味着微型电子设备从此不需要电池了,可以做得很小(比米粒还小),从而能够植入人体,使用的时候,发送电波就行了。以前做不到,是因为无线电波携带的能量非常微弱,又不知道设备的具体位置,没法用来充电。新技术克服了这些难点。

一旦人体可以植入电子设备,不再有充电的难题,那会带来怎样的变革?我的想象力都不够了……以后可能不再需要身份证了,每个人的体内植入私钥,检查身份的时候,一发信号,返回一个私钥签名的证书,只要跟公钥匹配,立刻就验明正身。

金句

1、人必有痴,而后有成。(林语堂)

2、创业公司成功的原因,这是最难的问题。大多数人只是指出非常明显的事情:”创始人很勤奋,企业文化也非常优秀。“问题在于,其他5000家创业公司也是如此,但都失败了。

3、如果你在很年轻的时候,就遭受到了失败,一定要把它当作老天送你的礼物。如果等到四十岁再失败,你会经受不起的。为什么年纪越大,走路越小心,因为越来越经不起跌倒了。

4、人生就像玻璃窗上的苍蝇,前途一片光明,却找不到出路。

5、十八年前刚刚接触网络,常常有世界触手可及的奇妙感觉。如今技术越来越先进,那种感觉却越来越少。

6、现在的开发者需要具备的,不仅仅是技能树,而是技能森林。

7、现实中的用户处于痛苦和失望的状态,你需要为他们设置一个放松和缓冲的区域,与外部世界隔离,让他们以一种兴奋的状态,进入你的产品。

8、千万别上瘾只想去解决那些困难的问题。如果那些问题本身就是错的,你会浪费时间;如果你解决不了,也会浪费时间。

9、没用分布式架构之前,你只有一个问题:并发性能不足。用了分布式架构,多出了一堆问题: 数据如何同步、主键如何产生、如何熔断、分布式事务如何处理……

10、读再多的书都不如内生动力给人带来的变化大。

刘媛媛语录

找到你早起的真正动力,那应该跟你最渴望实现的梦想有关,然后,明明白白地写在墙上。

找出问题的原因然后解决它。(解决晚睡的问题)

有时候我们很努力,是因为没有能力。没有能力把自己的时间安排好,没有能力控制自己的行为,所以才把自己推到了废寝忘食的境地。

长期坚持就会形成一种固定的思维习惯:“我的一天会在十一点结束,所以一定要珍惜白天的时间,更要珍惜晚上的时间,不要把晚上当作无休止的放纵时间,更不要把晚上当作主要的工作时间。

给自己一个起床时间,找人一起打卡,或者找另外的什么非起不可的理由,逼自己早点睡觉。

每日复盘,制定明日计划。

早上的时间,简直是造物主的恩赐,这是一段跟现实无关的时间,在他人沉睡时静悄悄地起床,这一段时间,最适合去为自己的珍贵梦想做努力,在每一个早晨,都离它更近一点。

要达到目标,只需要做五件事。
1.选择一个清晰的目标。
2.找到那些阻碍目标实现的问题。
3.精确地诊断问题。
4.设计计划并列出任务清单。
5.坚决执行并完成计划里的任务清单。

自己到底需要做什么,还没做什么,先做什么,后做什么,困难是什么,方法是什么。

大部分学生都没有管理自己和规划人生的能力,你被拖着、拽着、鞭策着、鼓励着,也挨着、麻木着,像一台机器一样毫无目的地转动着。

如何规划自己的人生,怎么才能找一个有意义的目标,怎么做才能实现这个目标,如何克服懒惰、对付拖延、安排时间。

设定目标、制定计划、时间管理

让自己变得有趣:
1.积累素材,学习套路。
2.反复试验,分析反馈。
3.形成风格,养成习惯。

为人处世有分寸感,心地善良不讨人厌,看什么都高兴,做什么都好玩,并且能够感染到周围的人,这就是有趣了。

学习前准备:
我为什么要学这些东西?
我今天要解决什么问题?
我预估多久可以学完这些东西?

怎么样学习才能达到目标,这个问题包括三个要素:
A.要达到什么样的目标。考什么学校?这个学校要多少分数?单科目标分数是多少?
B.要做什么事情。都需要学习哪些知识点?这些知识点在哪些书上?都要做哪些题,做几遍?背哪些东西?
C.这些事情要做多久。总共的复习时间是几个月?给每一个任务分配多长时间?
带着明确的目的去做,与模模糊糊,只是知道应该这么做,专注度也会有差别。

脑中一定要有这样的概念:学习时间绝对不可以中断,绝对不可以中断,绝对不中断,就算是无法集中注意力,也不要放弃为集中注意力而努力。

学习过程的干扰因素:杂念(先记下来,统一处理)、烦恼(记下解决方案或忽视)、手机(远离)、暗恋。

我挚爱的记忆方式,就是“说出来”,让自己特别郑重地站在一个地方,然后对着空气说,对着马路说。

我克服拖延和提高效率的办法就是把deadline交到别人的手上。

梦想这个词太概括了,要把它具体化、画面化,去想象做到之后的场景,我会变成什么样子,我会得到什么,父母会很高兴吧,越细越好。

最好是把耗神的任务和机械化的任务交错进行。、

最好把休息的时间固定下来,每天的晚上几点,每周的哪一天。

有进益,有阻碍,开始时没想太多,完成后才惊觉自己神功大成,反而有点落寞。

成功最重要的就是“延迟享受”的能力。也就是自律。

克服拖延:

第一,一定要找到实现目标的明确途径,清楚每一个行动的作用和效果,这样才会愿意行动起来。
准备研究生考试时,我就曾试图把达成目标的任务都明确下来。在复习前先设定理想分数,把需要掌握的知识点列出来,后面标明它们在过去被考的概率,然后像小坦克碾轧一样,一批一批地消灭掉,这过程居然还有点爽呢。
找出这个人,然后看一下成为他、取代他需要做哪几件事,包括需要学习哪些东西,需要掌握什么资源,需要升几级,怎么做会更快,把过程清晰地写出来。

第二,从想做的事情开始做。
每次要开始做一件我非常不想做的事情时,就从一件比较想做的事情开始,或者从那件事情中比较简单的一部分开始。

第三,如果能及时看到行动的反馈,坚持起来就会更容易。
好胜心会让你在听到差评的时候更努力,成就感会让你在听到好评的时候去继续努力。

第四,周期性坚持。
为了避免周一进入学习状态时不适应或者太痛苦,周日晚上就坐在桌子前去熟悉一下周一的事情,稍微做一点简单的任务或者做一个规划。

第五,别去做任何一个你根本做不到的计划。
一定要结合自己现在的水平和实际情况去做一个“一定可以完成”的计划,在时间上留一点余地。

第六,找到那些做出错误决定的瞬间。
记录自己失控的那些瞬间,找到自己失控的原因。

定目标,悄悄干。
当别人还在沉睡的时候,你就出发吧;当别人还在挣扎的时候,你就到达吧。

我算不上优秀,只是足够主动

dfgdfgdfgdf

  • 下次v型才是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的是电风扇的

  • 电风扇的

  • 是电风扇的

requestAnimationFrame 小例子 | 2018-02-09

requestAnimationFrame是浏览器用于定时循环操作的一个接口,类似于setTimeout,主要用途是按帧对网页进行重绘。

requestAnimationFrame的优势,在于充分利用显示器的刷新机制,比较节省系统资源。

html:

<div id="anim">Click here to start animation</div> 

css:

#anim {
  position:absolute;
  left:0px;
  width:150px;
  height:150px;
  background: blue;
  font-size: larger;
  color: white;
  border-radius: 10px;
  padding: 1em;
}

js:

// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame || 
          window.webkitRequestAnimationFrame || 
          window.mozRequestAnimationFrame || 
          window.oRequestAnimationFrame || 
          window.msRequestAnimationFrame || 
          function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element){
            window.setTimeout(callback, 1000 / 60);
          };
})();


var elem = document.getElementById("anim");
var startTime = undefined;
 
function render(time) {
 
  if (time === undefined)
    time = Date.now();
  if (startTime === undefined)
    startTime = time;
 
  elem.style.left = ((time - startTime)/10 % 500) + "px";
}
 
elem.onclick = function() {

    (function animloop(){
      render();
      requestAnimFrame(animloop, elem);
    })();
      
};

谷歌扩展导出 | 2018-03-07

  1. 地址栏输入:chrome://version/,找到个人资料路径,输入到资源管理器,进入
  2. 进入目录下面的Extensions文件夹
  3. 里面的各个文件夹名称为各个扩展的ID名(ID可以在chrome://extensions/这里面找到,记得勾选上面的开发者模式)
  4. 根据ID名查看需要导出的扩展,看清楚路径,例如C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\Extensions\dogkpdfcklifaemcdfbildhcofnopogp\0.6.3_0
  5. 进入chrome://extensions/,点击页面上部的打包扩展程序,填入扩展程序目录,然后打包
  6. 然后,会提示你,打包的crx文件的路径

日记 | 2015-05-16

待办事项

  • 英语LIST1-2(早上)

  • 张宇视频第四讲,对应书籍章节过一遍(晚上)

英语第一单元完毕。
数学由于其他原因,未完成,移至明天完成。

技术
公司开始了Vue的移动端项目,使用了有赞的组件库链接

生活
财政告急,这个月要吃土了-。-

跨域通信的几个点 | 2018-3-12

受同源限制有如下几点:

  • Cookie、LocalStorage 和 IndexedDB 无法读取。
  • DOM 无法获得。
  • AJAX 请求无效(可以发送,但浏览器会拒绝接受响应)。

Cookie

两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain共享 Cookie。

// A网页是http://w1.example.com/a.html,B网页是http://w2.example.com/b.html
document.domain = 'example.com';

// 现在,A 网页通过脚本设置一个 Cookie。
document.cookie = "test1=hello";

// B 网页就可以读到这个 Cookie。
var allCookie = document.cookie;

服务器也可以在设置 Cookie 的时候,指定 Cookie 的所属域名为一级域名,比如.example.com。

Set-Cookie: key=value; domain=.example.com; path=/

这样的话,二级域名和三级域名不用做任何设置,都可以读取这个Cookie。

Iframe

iframe窗口之中的脚本,可以获得父窗口和子窗口。但是,只有在同源的情况下,父窗口和子窗口才能通信;如果跨域,就无法拿到对方的DOM。

// 父窗口运行下面的命令,如果iframe窗口不是同源,就会报错。
document.getElementById("myIFrame").contentWindow.document
// Uncaught DOMException: Blocked a frame from accessing a cross-origin frame.

// 窗口获取主窗口的DOM也会报错。
window.parent.document.body
// 报错

这种情况还适用于window.open方法打开的窗口,只要跨域,父窗口与子窗口之间就无法通信。

如果两个窗口一级域名相同,只是二级域名不同,那么设置上一节介绍的document.domain属性,就可以规避同源政策,拿到DOM。

对于完全不同源的网站,目前有两种方法,可以解决跨域窗口的通信问题。

  • 片段识别符(fragment identifier)
  • 跨文档通信API(Cross-document messaging)

片段识别符

URL的#号后面的部分。如果只是改变片段标识符,页面不会重新刷新。

// 父窗口可以把信息,写入子窗口的片段标识符。
var src = originURL + '#' + data;
document.getElementById('myIFrame').src = src;

// 子窗口通过监听hashchange事件得到通知。
window.onhashchange = checkMessage;

function checkMessage() {
  var message = window.location.hash;
  // ...
}

// 同样的,子窗口也可以改变父窗口的片段标识符。
parent.location.href= target + '#' + hash;

跨文档通信API(window.postMessage)

postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即“协议 + 域名 + 端口”。也可以设为*,表示不限制域名,向所有窗口发送。

// 父窗口aaa.com向子窗口bbb.com发消息
var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');

// 子窗口向父窗口发送消息的写法类似。
window.opener.postMessage('Nice to see you', 'http://aaa.com');

// 父窗口和子窗口都可以通过message事件,监听对方的消息。
window.addEventListener('message', function(e) {
  console.log(e.data);
},false);

event对象的几个属性:

  • event.source:发送消息的窗口
  • event.origin: 消息发向的网址
  • event.data: 消息内容

window.postMessage,也可以读写其他窗口的 LocalStorage

// 主窗口写入iframe子窗口的localStorage
window.onmessage = function(e) {
  if (e.origin !== 'http://bbb.com') {
    return;
  }
  var payload = JSON.parse(e.data);
  localStorage.setItem(payload.key, JSON.stringify(payload.data));
};

// 父窗口发送消息的代码如下。
var win = document.getElementsByTagName('iframe')[0].contentWindow;
var obj = { name: 'Jack' };
win.postMessage(JSON.stringify({key: 'storage', data: obj}), 'http://bbb.com');

Ajax

跨域解决:

  • JSONP
  • WebSocket
  • CORS

JONP

它的基本**是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

function addScriptTag(src) {
  var script = document.createElement('script');
  script.setAttribute("type","text/javascript");
  script.src = src;
  document.body.appendChild(script);
}

window.onload = function () {
  addScriptTag('http://example.com/ip?callback=foo');
}

function foo(data) {
  console.log('Your public IP address is: ' + data.ip);
};

服务器收到这个请求以后,会将数据放在回调函数的参数位置返回。

foo({
  "ip": "8.8.8.8"
});

WebSocket(ws协议)

该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。

浏览器发出的WebSocket请求的头信息

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

服务器可以根据Origin这个字段,判断是否许可本次通信。如果该域名在白名单内,服务器就会做出如下回应。

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

CORS(跨源资源分享)

相比JSONP只能发GET请求,CORS允许任何类型的请求。

只要服务器实现了CORS接口,就可以跨源通信。

// 简单请求
// request
GET /cors HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

// response
Access-Control-Allow-Origin: http://api.bob.com
// 默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8

想要在CORS请求中发送cookie,则需要:
服务器:Access-Control-Allow-Credentials: true
浏览器xhr:var xhr = new XMLHttpRequest(); xhr.withCredentials = true;

需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。

FileApi | 2018-03-09

代码示例

html

<form id="file-form" action="handler.php" method="POST">
    <input type="file" id="file-select" name="photos[]" multiple onchange="handleChanage()"/>
    <button type="submit" id="upload-button">上传</button>
  </form>

js

var fileSelect = document.getElementById('file-select')
function handleChanage(e) {
  var files = fileSelect.files
  var formData = new FormData();

  for (var i = 0; i < files.length; i++) {
    var file = files[i];

    // if (!file.type.match('image')) {
    //   continue;
    // }

    formData.append('photos[]', file, file.name);
  }
  console.log(formData)
}

var formData = new FormData();
formData.append('name','tom');
formData.append('age','12');

资料

1、谷歌面试自学手册

2、Android开发工程师面试指南

3、React in patterns

React 如何使用各种编程模式?

4、css-protips

一个收集 CSS 使用技巧的库。

5、技术面试需要掌握的基础知识整理

6、love2.io

一个收集开源书籍的网站。

7、JavaScript 算法与数据结构

这个仓库收集了30多种算法的 JavaScript 实现。

8、 Python - 100天从新手到大师

一本针对初学者的 Python 教程。

9、Java 面试知识点

这个库收集各种 Java 面试的知识点。

SSE:服务器发送事件 | 2018-02-09

SSE,就是浏览器向服务器发送一个HTTP请求,然后服务器不断单向地向浏览器推送“信息”(message)。这种信息在格式上很简单,就是“信息”加上前缀“data: ”,然后以“\n\n”结尾。

$ curl http://example.com/dates
data: 1394572346452

data: 1394572347457

data: 1394572348463

^C

使用:

// 检查浏览器是否支持
if (!!window.EventSource) {
  // ...
}

// 向服务器发起连接 参数url就是服务器网址,必须与当前网页的网址在同一个网域(domain),而且协议和端口都必须相同。
var source = new EventSource('/dates');  

source.onmessage = function(e){
  console.log(e.data);
};

source.addEventListener("open", function(event) {
  // handle open event
}, false);

// event有以下属性
// data:服务器端传回的数据(文本格式)。
// origin: 服务器端URL的域名部分,即协议、域名和端口。
// lastEventId:数据的编号,由服务器端发送。如果没有编号,这个属性为空。
source.addEventListener("message", function(event) {
  var data = event.data;
  var origin = event.origin;
  var lastEventId = event.lastEventId;
  // handle message
}, false);

source.addEventListener("error", function(event) {
  // handle error event
}, false);

详情参考

日记 | 2018-05-23

技术

语言只是负责描述一个程序,而程序运行速度,其实很大程度不取决于语言,而主要取决于算法和编译器的质量。

技术选型,先选框架再选语言。

判断node项目环境变量:process.env.NODE_ENV === 'production'; 包为cross-env
命令举例:"build": "cross-env NODE_ENV=production wepy build --no-cache",

职场晋升几个要点 | 2018-03-13

  • 要有自己的代表作
    • 把一项工作做到极致,让大家一想到你,就会想到你的某项业绩
  • 学会越位思考
    • 问自己,如果我成了上级,我该怎么做?试着重新做一些规划
  • 展现出管理潜力
    • 从流程、分工、标准意识入手,平时可以看些管理类书籍和参加相关讲座
  • 自我暴露,讲出自己的励志故事和成长故事
  • 积极评价老板
  • 向上同理心、理解老板
  • 帮助上级升职
  • 找一个职业导师,缩短升职路径
    • 企业高管、论坛大佬等
    • 问一个有深度的专业问题,最好没有标准答案的
    • 对方建议很好用,及时给予反馈、表达感谢
  • 找到你的职业外挂,将你的短板变为长板
    • 给自己的朋友根据专业技能分类,多结交不同行业朋友
    • 懂得技能交换,对方求帮忙,一定要帮
  • 个人技能标签化
    • 自我介绍给自己贴标签
    • 利用朋友圈强化你的标签,做人设
    • 发展细分领域的标签,成为大神
      压缩别的工作时间,在这件事上高度专注、高度聚焦,完成一万小时的积累。
      每天复盘,总结自己做对了什么,做错了什么,定期整理,形成方法论。

JS中小数的加减乘除 | 2018-04-27

//加法函数
function accAdd(arg1, arg2) {
    var r1, r2, m;
    try {
        r1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
        r2 = 0;
    }
    m = Math.pow(10, Math.max(r1, r2));
    return (arg1 * m + arg2 * m) / m;
} 
//给Number类型增加一个add方法,,使用时直接用 .add 即可完成计算。 
Number.prototype.add = function (arg) {
    return accAdd(arg, this);
};


//减法函数
function Subtr(arg1, arg2) {
    var r1, r2, m, n;
    try {
        r1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
        r2 = 0;
    }
    m = Math.pow(10, Math.max(r1, r2));
     //last modify by deeka
     //动态控制精度长度
    n = (r1 >= r2) ? r1 : r2;
    return ((arg1 * m - arg2 * m) / m).toFixed(n);
}

//给Number类型增加一个sub方法,,使用时直接用 .sub 即可完成计算。 
Number.prototype.sub = function (arg) {
    return Subtr(this, arg);
};


//乘法函数
function accMul(arg1, arg2) {
    var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
    try {
        m += s1.split(".")[1].length;
    }
    catch (e) {
    }
    try {
        m += s2.split(".")[1].length;
    }
    catch (e) {
    }
    return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
} 
//给Number类型增加一个mul方法,使用时直接用 .mul 即可完成计算。 
Number.prototype.mul = function (arg) {
    return accMul(arg, this);
}; 


//除法函数
function accDiv(arg1, arg2) {
    var t1 = 0, t2 = 0, r1, r2;
    try {
        t1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
    }
    try {
        t2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
    }
    with (Math) {
        r1 = Number(arg1.toString().replace(".", ""));
        r2 = Number(arg2.toString().replace(".", ""));
        return (r1 / r2) * pow(10, t2 - t1);
    }
} 
//给Number类型增加一个div方法,,使用时直接用 .div 即可完成计算。 
Number.prototype.div = function (arg) {
    return accDiv(this, arg);
};

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.