普通视图

发现新文章,点击刷新页面。
昨天以前前端工程师 Toweave

程序员的文字障

2021年5月28日 10:31
甲骨文

甲骨文

文字障、知见障是佛学的名词,用来说明很多时候,读经律论的时候过于执著于文字,而不能透过文字了解真实奥义,又或者过于执著于自己以往的成功经验,自己以往证得的念想,那么这些原来的成就,反而成为了阻止自己了解大道的障碍,此是佛家的说法。(摘自百度百科)

数组函数妙用

2019年4月28日 20:26
  1. 统计数组元素出现次数
var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];

var countedNames = names.reduce(function (allNames, name) {  
  if (name in allNames) {
    allNames[name]++;
  } else {
    allNames[name] = 1;
  }
  return allNames;
}, {});
// countedNames is:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
  1. 按属性对object分类
var people = [  
  { name: 'Alice', age: 21 },
  { name: 'Max', age: 20 },
  { name: 'Jane', age: 20 }
];

function groupBy(objectArray, property) {  
  return objectArray.reduce(function (acc, obj) {
    var key = obj[property];
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(obj);
    return acc;
  }, {});
}

var groupedPeople = groupBy(people, 'age');  
// groupedPeople is:
// { 
//   20: [
//     { name: 'Max', age: 20 }, 
//     { name: 'Jane', age: 20 }
//   ], 
//   21: [{ name: 'Alice', age: 21 }] 
// }
  1. 使用扩展运算符和 initialValue 绑定包含在对象数组中的数组
// friends - 对象数组
// where object field "books" - list of favorite books 
var friends = [{  
  name: 'Anna',
  books: ['Bible', 'Harry Potter'],
  age: 21
}, {
  name: 'Bob',
  books: ['War and peace', 'Romeo and Juliet'],
  age: 26
}, {
  name: 'Alice',
  books: ['The Lord of the Rings', 'The Shining'],
  age: 18
}];

// allbooks - list which will contain all friends' books +  
// additional list contained in initialValue
var allbooks = friends.reduce(function(prev, curr) {  
  return [...prev, ...curr.books];
}, ['Alphabet']);

// allbooks = [
//   'Alphabet', 'Bible', 'Harry Potter', 'War and peace', 
//   'Romeo and Juliet', 'The Lord of the Rings',
//   'The Shining'
// ]

扩展 Array 方法

2019年4月28日 19:26

实现一个简单的数组个元素相等的判断

Array.prototype.equals = function (arr) {  
  const len = this.length
  if (len !== arr.length) {
    return false
  }
  for (let i = 0; i < len; i++) {
    if (this[i] !== arr[i]) {
      return false
    }
  }
  return true
}

;[1, 2].equals([1, 2]) // true
;[1, 2].equals([0]) // false

DOM 优化操作

2019年4月28日 18:26

渲染树转换为网页布局,称为“布局流”(flow);布局显示到页面的这个过程,称为“绘制”(paint)。它们都具有阻塞效应,并且会耗费很多时间和计算资源。

页面生成以后,脚本操作和样式表操作,都会触发重流(reflow)和重绘(repaint)。用户的互动,也会触发,比如设置了鼠标悬停(a:hover)效果、页面滚动、在输入框中输入文本、改变窗口大小等等。

重流和重绘并不一定一起发生,重流必然导致重绘,重绘不一定需要重流。比如改变元素颜色,只会导致重绘,而不会导致重流;改变元素的布局,则会导致重绘和重流。

大多数情况下,浏览器会智能判断,将重流和重绘只限制到相关的子树上面,最小化所耗费的代价,而不会全局重新生成网页。

作为开发者,应该尽量设法降低重绘的次数和成本。比如,尽量不要变动高层的DOM元素,而以底层DOM元素的变动代替;再比如,重绘table布局和flex布局,开销都会比较大。

  1. 读取DOM或者写入DOM,尽量写在一起,不要混杂
  2. 缓存DOM信息
  3. 不要一项一项地改变样式,而是使用CSS class一次性改变样式
  4. 使用document fragment操作DOM
  5. 动画时使用absolute定位或fixed定位,这样可以减少对其他元素的影响
  6. 只在必要时才显示元素
  7. 使用window.requestAnimationFrame(),因为它可以把代码推迟到下一次重流时执行,而不是立即要求页面重流
  8. 使用虚拟DOM(virtual DOM)库

实现一个链式调用函数

2019年4月28日 18:26

实现一个简单的链式调用方法

"use strict";
async function delay (time, callback) {
  return new Promise(function(resolve, reject) {
    setTimeout(() => {
      resolve(callback());
    }, time * 1000)
  });
}
class QueueItem {
  constructor(time, callback) {
    this.time = time;
    this.callback = callback;
  }
}
class Point {
  constructor(name) {
    let funcStart = new QueueItem(0, () => {
      console.log(`start ${name}`)
      return void 0;
    });
    this.name = name;
    this.queue = [funcStart]
  }
  do(action) {
    // this.action = action
    let funcDo = new QueueItem(0, () => {
      console.log(`${this.name} - ${action}`)
      return void 0;
    });
    this.queue.push(funcDo)
    return this
  }
  wait (time) {
    // this.time = time
    let funcWait = new QueueItem(time, () => {
      console.log(`wait - ${time}`)
      return void 0;
    });
    this.queue.push(funcWait)
    return this
  }
  waitFirst (time) {
    // this.timeWaitFirst = time
    let funcWait = new QueueItem(time, () => {
      console.log(`wait first - ${time}`)
      return void 0;
    })
    this.queue.unshift(funcWait)
    return this
  }
  async execute() {
    for (let i = 0; i < this.queue.length; i++) {
      let item = this.queue[i]
      console.log(67, i)
        if (!item.time) {
          item.callback();
        } else {
          await delay(item.time, item.callback);
        }
    }
  }
}
function machine(name) {
  return new Point(name);
}
machine('123').wait(2).do('eat').waitFirst(3).execute()


// 运行结果
// 67 0
// wait first - 3
// 67 1
// start 123
// 67 2
// wait - 2
// 67 3
// 123 - eat

HTML 标签

2019年4月11日 17:50

HTML 标签待整理

HTML 标签待整理

  var isHTMLTag = makeMap(
    'html,body,base,head,link,meta,style,title,' +
    'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +
    'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' +
    'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +
    's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +
    'embed,object,param,source,canvas,script,noscript,del,ins,' +
    'caption,col,colgroup,table,thead,tbody,td,th,tr,' +
    'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +
    'output,progress,select,textarea,' +
    'details,dialog,menu,menuitem,summary,' +
    'content,element,shadow,template,blockquote,iframe,tfoot'
  );
  
   var isSVG = makeMap(
      'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' +
      'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +
      'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',
      true
    );

vue 实例生命周期钩子

2019年4月11日 17:15

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、 将实例挂载到 DOM 并在数据变化时更新 DOM 等。 同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

  const ASSET_TYPES = [
    'component',
    'directive',
    'filter'
  ];

  const LIFECYCLE_HOOKS = [
    'beforeCreate',
    'created',
    'beforeMount',
    'mounted',
    'beforeUpdate',
    'updated',
    'beforeDestroy',
    'destroyed',
    'activated',
    'deactivated',
    'errorCaptured',
    'serverPrefetch'
  ];

生命周期图示

浏览器运行环境判断

2019年4月11日 17:05

常用的浏览器运行环境判断

  // Browser environment sniffing
  var inBrowser = typeof window !== 'undefined';
  var inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform;
  var weexPlatform = inWeex && WXEnvironment.platform.toLowerCase();
  var UA = inBrowser && window.navigator.userAgent.toLowerCase();
  var isIE = UA && /msie|trident/.test(UA);
  var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
  var isEdge = UA && UA.indexOf('edge/') > 0;
  var isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android');
  var isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios');
  var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
  var isPhantomJS = UA && /phantomjs/.test(UA);
  var isFF = UA && UA.match(/firefox\/(\d+)/);

git 常用命令

2019年4月4日 10:51
  • ssh生成秘钥

    ssh-keygen -t rsa -C "toweave@163.com"
  • 删除远程分支

    git branch -r -d origin/branch-name  
    git push origin :branch-name
  • 删除本地分支

    git branch -D origin/branch-name
  • git添加tag

    git tag v1.0.0-xxx-tag-name
    git push origin v1.0.0-xxx-tag-name
    git tag -a v1.4 -m 'my version 1.4'
  • git本地分支添加到远程

    git push --set-upstream origin branch-name`
  • 初始化git项目

…or create a new repository on the command line

echo "# exercise" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin git@github.com:toweave/exercise.git
git push -u origin master

…or push an existing repository from the command line

git remote add origin git@github.com:toweave/exercise.git
git push -u origin master
  • git stash: 备份当前的工作区的内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同时,将当前的工作区内容保存到Git栈中。
  • git stash pop: 从Git栈中读取最近一次保存的内容,恢复工作区的相关内容。由于可能存在多个Stash的内容,所以用栈来管理,pop会从最近的一个stash中读取内容并恢复。
  • git stash list: 显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复。
  • git stash clear: 清空Git栈。此时使用gitg等图形化工具会发现,原来stash的哪些节点都消失了。

CR回车 LF 换行 Windows/Dos CRLF \r\n Linux/Unix LF \n MacOS CR \r 解决方法是:打开命令行,进行设置,如果你是在 Windows 下开发,建议设置 autocrlf 为true。 2014/08/20 补充:如果你文件编码是 UTF8 并且包含中文文字,那还是把 autocrlf 设置为 false,并且把所有文件转换为 Linux 编码(即 LF\n),开启 safecrlf 检查。

  • 一、AutoCRLF

提交时转换为LF,检出时转换为CRLF

git config --global core.autocrlf true

提交时转换为LF,检出时不转换

git config --global core.autocrlf input

提交检出均不转换

git config --global core.autocrlf false
  • 二、SafeCRLF

拒绝提交包含混合换行符的文件

git config --global core.safecrlf true

允许提交包含混合换行符的文件

git config --global core.safecrlf false

提交包含混合换行符的文件时给出警告

git config --global core.safecrlf warn

设置中文乱码问题

git config --global core.quotepath false

git config保存密码

[credential]
     helper = store

git 删除本地暂存库缓存

git rm --cached --force build/*

常用正则表达式

2019年4月3日 11:47

正则表达式,一个十分古老而又强大的文本处理工具,仅仅用一段非常简短的表达式语句,便能够快速实现一个非常复杂的业务逻辑。熟练地掌握正则表达式的话,能够使你的开发效率得到极大的提升。下面是在前端开发中经常使用到的20个正则表达式。

正则表达式经常被用于字段或任意字符串的校验,如下面这段校验基本日期格式的JavaScript代码:

var reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/;
var r = fieldValue.match(reg);
if (r === null) alert('Date format error!');

1 . 校验密码强度

密码的强度必须是包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间。

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$

2. 校验中文

字符串仅能是中文。

^[\u4e00-\u9fa5]{0,}$

3. 由数字、26个英文字母或下划线组成的字符串

^\w+$

4. 校验E-Mail 地址

同密码一样,下面是E-mail地址合规性的正则检查语句。

[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?

5. 校验身份证号码

下面是身份证号码的正则校验。15 或 18位。

15位:

^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$

18位:

 ^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$

6. 校验日期

“yyyy-mm-dd” 格式的日期校验,已考虑平闰年。

^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$

7. 校验金额

金额校验,精确到2位小数。

^[0-9]+(.[0-9]{2})?$
var reg = /^(([1-9][0-9]*)|(([0]\.\d{1,2}|[1-9][0-9]*\.\d{1,2})))$/;

8. 校验手机号

下面是国内 13、15、18开头的手机号正则表达式。(可根据目前国内收集号扩展前两位开头号码)

^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$

9. 判断IE的版本

IE目前还没被完全取代,很多页面还是需要做版本兼容,下面是IE版本检查的表达式。

^.*MSIE [5-8](?:\.[0-9]+)?(?!.*Trident\/[5-9]\.0).*$

10. 校验IP-v4地址

IP4 正则语句。

\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

11. 校验IP-v6地址

IP6 正则语句。

(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))

12. 检查URL的前缀

应用开发中很多时候需要区分请求是HTTPS还是HTTP,通过下面的表达式可以取出一个url的前缀然后再逻辑判断。

if (!s.match(/^[a-zA-Z]+:\/\//)) {
    s = 'http://' + s;
}

13. 提取URL链接

下面的这个表达式可以筛选出一段文本中的URL。

^(f|ht){1}(tp|tps):\/\/([\w-]+\.)+[\w-]+(\/[\w- ./?%&=]*)?

14. 文件路径及扩展名校验

验证windows下文件路径和扩展名(下面的例子中为.txt文件)

^([a-zA-Z]\:|\\)\\([^\\]+\\)*[^\/:*?"<>|]+\.txt(l)?$

15. 提取Color Hex Codes

有时需要抽取网页中的颜色代码,可以使用下面的表达式。

^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$

16. 提取网页图片

假若你想提取网页中所有图片信息,可以利用下面的表达式。

\< *[img][^\\>]*[src] *= *[\"\']{0,1}([^\"\'\ >]*)

17. 提取页面超链接

提取html中的超链接。

(<a\s*(?!.*\brel=)[^>]*)(href="https?:\/\/)((?!(?:(?:www\.)?'.implode('|(?:www\.)?', $follow_list).'))[^"]+)"((?!.*\brel=)[^>]*)(?:[^>]*)>`

18. 查找CSS属性

通过下面的表达式,可以搜索到相匹配的CSS属性。

^\s*[a-zA-Z\-]+\s*[:]{1}\s[a-zA-Z0-9\s.#]+[;]{1}

19. 抽取注释

如果你需要移除HMTL中的注释,可以使用如下的表达式。

<!--(.*?)-->

20. 匹配HTML标签

通过下面的表达式可以匹配出HTML中的标签属性。

<\/?\w+((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[\^'">\s]+))?)+\s*|\s*)\/?>

Material Design 中文版

2019年4月2日 17:28

核心思想
Material Design的核心思想,就是把物理世界的体验带进屏幕。去掉现实中的杂质和随机性,保留其最原始纯净的形态、空间关系、变化与过渡,配合虚拟世界的灵活特性,还原最贴近真实的体验,达到简洁与直观的效果。

Material design是最重视跨平台体验的一套设计语言。由于规范严格细致,保证它在各个平台使用体验高度一致。不过目前还只有Google自家的服务这么做,毕竟其他平台有自己的规范与风格。

极客学院 Wiki 提供文档,感觉很好,赶快看看吧!

Material Design 中文版

console 你知道到吗?

2019年4月1日 18:31

console 主要方法: 一般情况下我们用来输入信息的方法主要是用到如下四个

  • 1、console.log 用于输出普通信息
  • 2、console.info 用于输出提示性信息
  • 3、console.error 用于输出错误信息
  • 4、console.warn 用于输出警示信息
  • 5、console.group 输出一组信息的开头
  • 6、console.groupEnd 结束一组输出信息
  • 7、console.assert 对输入的表达式进行断言,只 有表达式为false时,才输出相应的信息到控制台
  • 8、console.count (这个方法非常实用哦)当你想统计代码被执行的次数
  • 9、console.dir (这个方法是我经常使用的 可不知道比for in方便了多少) 直接将该DOM结点以DOM树的结构进行输出,可以详细查对象的方法发展等等
  • 10、console.time 计时开始
  • 11、console.timeEnd 计时结束(看了下面的图你瞬间就感受到它的厉害了)
  • 12、console.profile 和 console.profileEnd 配合一起使用来查看CPU使用相关信息
  • 13、console.timeLine 和 console.timeLineEnd 配合一起记录一段时间轴
  • 14、console.trace 堆栈跟踪相关的调试
  • 15、console.table 表格形式展示
❌
❌