首页 > 行业动态 > 正文

爱创课堂纯干货---前端大牛经验分享
2016-11-17 17:46:00   来源:   评论:0 点击:

爱创课堂分享-列表项项目是利用docker容器与daocloud部署在阿里云的云服务器ECS上线方式:通过git hook,检测github的tag版本变化,自动更

爱创课堂分享

  • -
 

列表项

项目是利用docker容器与daocloud部署在阿里云的云服务器ECS 
上线方式:通过git hook,检测github的tag版本变化,自动更新部署新的代码。 
项目架构:淘宝的sui框架 gulp bower

 

自我介绍

  • 曾就职于电商公司,担任web工程师,负责sql开发与商城开发。
  • 在百度地图任职于rd职位,负责开放平台,bbs,内部bms,与政府合作应用于直达号的新违建平台等项目。
  • 目前在一家创业公司,公司服务于青年线下社交的平台,主要负责前端开发、顺便写一些后端代码、api。
 

目录

  • 介绍10个JavaScript的开发技巧
  • 性能优化-预加载与懒加载
  • gulp,bower环境搭建
  • someet首页无线滚动实战
  • 聊聊someet架构
  • 项目自动部署
  • 分享几个自己工作生活中总结的观念
 

分享几个js技巧

我们在使用js的时候一些常用方法我们以为已经掌握它了,但是有些细节,我们可能没注意到!

 

  1. 我们习惯使用
  2. setTimeout(function(){
  3. alert(1111111)
  4. },1000)
  5.  
  6. 这样使用也可以
  7. 后面是是回调参数
  8. setTimeout(function(num){
  9. alert(num)
  10. },1000,111111)
 

拼接字符串

 

  1.  
  2. window.onload = function(){
  3. document.body.innerHTML = "<div>div</div><span>span</span><p>p</p>";
  4. }
  5.  
  6.  
  7. window.onload = function(){
  8. document.body.innerHTML = "<div>div</div>"+
  9. "<span>span</span>"+
  10. "<p>p</p>"+
  11. "55555555555";
  12. }
  13.  
  14.  
  15. window.onload = function(){
  16. document.body.innerHTML = "<div>div</div>\
  17. <span>span</span>\
  18. <p>p</p>\
  19. 55555555555";
  20. }
 

console.log 设置颜色变量

 

  1. var a = 'hello';
  2. console.log('%c'+a,'font-size:400%;color:red;');
  3. var people = "stark";
  4. var years = 18;
  5. console.log("%s is %d years old.", people, years);
 

typeof

 

  1. var arr = [];
  2. console.log( typeof arr);
  3.  
  4. arr.num = 10;
  5. console.log( typeof arr);
  6. console.log( typeof(arr));
  7.  
  8. console.log(arr instanceof Object);
  9. console.log(arr instanceof(Object));
  10.  
  11. console.log( 'num' in arr);
  12. console.log( 'num' in(arr));
 

停止嵌套循环

 

  1. for(var i=0;i<5;i++){
  2. for(var j=0;j<1;j++){
  3. if ( i== 3) {
  4. break;
  5. }
  6.  
  7. alert(i);
  8. }
  9. }
  10.  
  11. 只是3不弹出外面没有停止
  12.  
  13. 有时候有需求把所有的循环都跳出
  14.  
  15. a : for(var i=0;i<5;i++){
  16. for(var j=0;j<1;j++){
  17. if ( i== 3) {
  18. break a;
  19. }
  20.  
  21. alert(i);
  22. }
  23. }
  24.  
 

for循环的其他写法

 

  1. var i = 0;
  2. for(;;){
  3. alert(i);
  4. if (++i>5) {
  5. break;
  6. }
  7. }
 

call 指向window

 

  1. var obj = {
  2. aaa:function(){
  3. alert(this);
  4. }
  5. };
  6.  
  7. var arr = [1,2,3];
  8.  
  9. obj.aaa.call(arr);
  10.  
  11. 不写任何参数就可以指向window
  12. var obj = {
  13. aaa:function(){
  14. alert(this);
  15. }
  16. };
  17.  
  18. var arr = [1,2,3];
  19.  
  20. obj.aaa.call(window);
  21.  
  22. apply 也有此写法
  23. var obj = {
  24. aaa:function(){
  25. alert(this);
  26. }
  27. };
  28.  
  29. var arr = [1,2,3];
  30.  
  31. obj.aaa.apply();
  32.  
 

appendChild 添加到后面

 

  1.  
  2. <input type="button" value="添加" id="input1">
  3. <ul id="ul1">
  4. </ul>
  5.  
  6.  
  7. var oInput = document.getElementById('input1');
  8. var oUl = document.getElementById('ul1');
  9. var iNow = 0;
  10. var aLi = oUl.getElementsByTagName('li');
  11. oInput.onclick = function(){
  12. var oLi = document.createElement('li');
  13. oLi.innerHTML = iNow++;
  14.  
  15. oUl.insertBefore(oLi,aLi[0]);
  16. }
  17.  
  18. insertBefore 自带一种默认行为当为null的时候和appendChild机制一样自带的一种行为,当我们理解了这种行为,遇到这种需求就可以操作了。
  19.  
  20.  
  21.  
  22. var oInput = document.getElementById('input1');
  23. var oUl = document.getElementById('ul1');
  24. var iNow = 0;
  25. var aLi = oUl.getElementsByTagName('li');
  26. oInput.onclick = function(){
  27. var oLi = document.createElement('li');
  28. oLi.innerHTML = iNow++;
  29.  
  30. if (!aLi.length) {
  31. oUl.appendChild(oLi);
  32. }else{
  33. oUl.insertBefore(oLi,aLi[0]);
  34. }
  35. }
 

匿名函数自执行

 

  1. // (function(){
  2. // alert(1111);
  3. // })()
  4.  
  5. // 在函数前面不加小括号,加上位运算符都可以解决这个问题 ~ +
  6. +function(){
  7. alert(111);
  8. }();
  9. 不一定是小括号
 

创建对象可以省略括号 系统对象也有类似的形式

 

  1. function Aaa(){
  2. }
  3. var a1 = new Aaa;
  4. alert(a1);
  5. var arr = new Array;
  6. alert( arr.length);
 

懒加载

 

lazyLoad简介及作用:

懒加载有很多种名字,例如:延迟加载、惰性加载、按需加载 
页面如果有很多图片的时候,当你滚动到相应的行时,当前行的图片才即时加载的,这样子的话页面在打开只加可视区域的图片,而其它隐藏的图片则不加载。

 

使用场合

涉及到图片,falsh资源,iframe,网页编辑器(CK),JS文件 等占用较大带宽,避免网页打开时加载过多资源,让用户等待太久。 
或者用户没有浏览到的地方,就会不去加载,节省很多资源,减轻服务器压力。

 

使用方式

1.你怎么知道用户想看那张图片 
2.当这个图片标签在这里,怎么把图片地址给它 
绑定滚动方式

 

  1. // 构建图片列表
  2. var html = []
  3. for (var i=0; i< 10; i++) {
  4. html.push('<p><img data-src="image/'+(i%5)+'.jpg?'+i+'" width="560" height="305"></p>')
  5. }
  6.  
  7. $('#images').html(html.join(''))
  8.  
  9. // 滚动事件
  10. $(window).on('scroll', function() {
  11. alert('onscroll')
  12. })

判断元素是否可见

 

  1. // 判断一个元素是否在可视范围
  2. // 即图片的顶部或底部在可视范围当中
  3. $.fn.isVisible = function() {
  4. var o = this
  5.  
  6. // 可视范围边界
  7. // scrollTop() 方法返回或设置匹配元素的滚动条的垂直位置。
  8. // scroll top offset 指的是滚动条相对于其顶部的偏移。
  9. // 如果该方法未设置参数,则返回以像素计的相对滚动条顶部的偏移。
  10. var minHeight = $(window).scrollTop()
  11. var maxHeight = minHeight + $(window).height()
  12.  
  13. // 元素的顶部和底部 offset() 方法返回或设置匹配元素相对于文档的偏移(位置)。
  14. var elementTop = o.offset().top
  15. console.log(elementTop);
  16. var elementHeight = o.height()
  17. console.log(elementHeight);
  18.  
  19. // 比较元素的位置和可视区域
  20. if ( (elementTop >= minHeight && elementTop < maxHeight)
  21. || (elementTop + elementHeight >= minHeight && elementTop + elementHeight < maxHeight)
  22. ) {
  23. return true
  24. }
  25.  
  26. return false
  27. }
  28.  
  29. console.log(imgs.first().isVisible() +', '+imgs.last().isVisible() )
 

判断滚动到底部

 

  1. $(window).scroll(function(){
  2.   var scrollTop = $(this).scrollTop();
  3.  
  4. // 文档的高度
  5.   var scrollHeight = $(document).height();
  6. // 窗口的高度
  7.   var windowHeight = $(this).height();
  8.  
  9.   if(scrollTop + windowHeight > scrollHeight - 10){
  10. console.log(1111)
  11.   }
  12. });
 

原生js的案列

 

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>懒加载</title>
  6. <style>
  7. #ul1 {margin: 100px auto 0; padding: 0;}
  8. li {float: left; margin:0 0 10px 10px; list-style:none; border: 1px solid black;}
  9. img {width: 290px; height: 200px; display: block;}
  10. </style>
  11. <script>
  12. window.onload = function() {
  13. var oUl = document.getElementById('ul1');
  14. var aImg = oUl.getElementsByTagName('img');
  15.  
  16. showImage();
  17.  
  18. window.onscroll = showImage;
  19.  
  20. function showImage() {
  21.  
  22. var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  23. console.log(document.documentElement.clientHeight);
  24. console.log(scrollTop);
  25. for (var i=0; i<aImg.length; i++) {
  26. if ( !aImg[i].isLoad && getTop(aImg[i]) < scrollTop + document.documentElement.clientHeight ) {
  27. //alert(i);
  28. aImg[i].src = aImg[i].getAttribute('_src');
  29. aImg[i].isLoad = true;
  30. }
  31. }
  32.  
  33. }
  34.  
  35. function getTop(obj) {
  36. var iTop = 0;
  37. while(obj) {
  38. iTop += obj.offsetTop;
  39. obj = obj.offsetParent;
  40. }
  41. return iTop;
  42. }
  43.  
  44. }
  45. </script>
  46. </head>
  47.  
  48. <body>
  49. <ul id="ul1">
  50. <li><img _src="img/1.jpg" src="img/white.JPG" /></li>
  51. <li><img _src="img/2.jpg" src="img/white.JPG" /></li>
  52. <li><img _src="img/3.jpg" src="img/white.JPG" /></li>
  53. <li><img _src="img/4.jpg" src="img/white.JPG" /></li>
  54. <li><img _src="img/5.jpg" src="img/white.JPG" /></li>
  55. <li><img _src="img/6.jpg" src="img/white.JPG" /></li>
  56. <li><img _src="img/7.jpg" src="img/white.JPG" /></li>
  57. <li><img _src="img/1.jpg" src="img/white.JPG" /></li>
  58. <li><img _src="img/2.jpg" src="img/white.JPG" /></li>
  59. <li><img _src="img/3.jpg" src="img/white.JPG" /></li>
  60. <li><img _src="img/4.jpg" src="img/white.JPG" /></li>
  61. <li><img _src="img/5.jpg" src="img/white.JPG" /></li>
  62. <li><img _src="img/6.jpg" src="img/white.JPG" /></li>
  63. <li><img _src="img/7.jpg" src="img/white.JPG" /></li>
  64. <li><img _src="img/1.jpg" src="img/white.JPG" /></li>
  65. <li><img _src="img/2.jpg" src="img/white.JPG" /></li>
  66. <li><img _src="img/3.jpg" src="img/white.JPG" /></li>
  67. <li><img _src="img/4.jpg" src="img/white.JPG" /></li>
  68. <li><img _src="img/5.jpg" src="img/white.JPG" /></li>
  69. <li><img _src="img/6.jpg" src="img/white.JPG" /></li>
  70. <li><img _src="img/7.jpg" src="img/white.JPG" /></li>
  71. <li><img _src="img/1.jpg" src="img/white.JPG" /></li>
  72. <li><img _src="img/2.jpg" src="img/white.JPG" /></li>
  73. <li><img _src="img/3.jpg" src="img/white.JPG" /></li>
  74. <li><img _src="img/4.jpg" src="img/white.JPG" /></li>
  75. <li><img _src="img/5.jpg" src="img/white.JPG" /></li>
  76. <li><img _src="img/6.jpg" src="img/white.JPG" /></li>
  77. <li><img _src="img/7.jpg" src="img/white.JPG" /></li>
  78. <li><img _src="img/1.jpg" src="img/white.JPG" /></li>
  79. <li><img _src="img/2.jpg" src="img/white.JPG" /></li>
  80. <li><img _src="img/3.jpg" src="img/white.JPG" /></li>
  81. <li><img _src="img/4.jpg" src="img/white.JPG" /></li>
  82. <li><img _src="img/5.jpg" src="img/white.JPG" /></li>
  83. <li><img _src="img/6.jpg" src="img/white.JPG" /></li>
  84. <li><img _src="img/7.jpg" src="img/white.JPG" /></li>
  85. <li><img _src="img/1.jpg" src="img/white.JPG" /></li>
  86. <li><img _src="img/2.jpg" src="img/white.JPG" /></li>
  87. <li><img _src="img/3.jpg" src="img/white.JPG" /></li>
  88. <li><img _src="img/4.jpg" src="img/white.JPG" /></li>
  89. <li><img _src="img/5.jpg" src="img/white.JPG" /></li>
  90. <li><img _src="img/6.jpg" src="img/white.JPG" /></li>
  91. <li><img _src="img/7.jpg" src="img/white.JPG" /></li>
  92. <li><img _src="img/1.jpg" src="img/white.JPG" /></li>
  93. <li><img _src="img/2.jpg" src="img/white.JPG" /></li>
  94. <li><img _src="img/3.jpg" src="img/white.JPG" /></li>
  95. <li><img _src="img/4.jpg" src="img/white.JPG" /></li>
  96. <li><img _src="img/5.jpg" src="img/white.JPG" /></li>
  97. <li><img _src="img/6.jpg" src="img/white.JPG" /></li>
  98. <li><img _src="img/7.jpg" src="img/white.JPG" /></li>
  99. <li><img _src="img/1.jpg" src="img/white.JPG" /></li>
  100. <li><img _src="img/2.jpg" src="img/white.JPG" /></li>
  101. <li><img _src="img/3.jpg" src="img/white.JPG" /></li>
  102. <li><img _src="img/4.jpg" src="img/white.JPG" /></li>
  103. <li><img _src="img/5.jpg" src="img/white.JPG" /></li>
  104. <li><img _src="img/6.jpg" src="img/white.JPG" /></li>
  105. <li><img _src="img/7.jpg" src="img/white.JPG" /></li>
  106. </ul>
  107. </body>
  108. </html>
 

利用jQuery方式

 

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>图片延迟加载</title>
  6. </head>
  7. <body>
  8. <div id="images"></div>
  9.  
  10. <script src="../lib/jquery-1.11.0.min.js"></script>
  11. <script>
  12. // 构建图片列表
  13. var html = []
  14. for (var i=0; i< 10; i++) {
  15. html.push('<p><img data-src="image/'+(i%5)+'.jpg?'+i+'" width="560" height="305"></p>')
  16. }
  17.  
  18. $('div').html(html.join(''))
  19.  
  20. // 延迟加载
  21. var timer
  22. $(window).on('scroll.lazyload', function() {
  23. clearTimeout(timer)
  24.  
  25. timer = setTimeout(function() {
  26. find()
  27. }, 200)
  28. })
  29.  
  30. //find()
  31.  
  32. // 遍历所有未加载的图片
  33. function find() {
  34. var imgs = $('#images img').not('[src]')
  35.  
  36. log('尚有 '+imgs.length + ' 张图片未加载')
  37.  
  38. if (imgs.length) {
  39. imgs.each(function() {
  40. var o = $(this)
  41. if (o.isVisible()) {
  42. o.attr('src', o.data('src'))
  43. }
  44. })
  45. } else {
  46. $(window).off('scroll.lazyload')
  47. log('图片全部加载完毕,已解除相关滚动事件')
  48. }
  49. }
  50.  
  51. // 判断一个元素是否在可视范围
  52. // 即图片的顶部或底部在可视范围当中
  53. $.fn.isVisible = function() {
  54. var o = this
  55. var minHeight = $(window).scrollTop()
  56. var maxHeight = minHeight + $(window).height()
  57.  
  58. var top = o.offset().top
  59. var height = o.height()
  60.  
  61.  
  62. if ( (top >= minHeight && top < maxHeight)
  63. || (top + height >= minHeight && top + height < maxHeight)
  64. ) {
  65. return true
  66. }
  67.  
  68. return false
  69. }
  70.  
  71. // 日志助手
  72. // 仅在url当中包含 debug 标识时打印日志
  73. function log(data, method) {
  74. method = method || 'log'
  75.  
  76. if (/(^file:|[?&]debug\b)/.test(window.top.location.href) && typeof console === 'object') {
  77.  
  78. method = console[method] ? method : 'log'
  79.  
  80. if ( data instanceof Array ) {
  81. // 将 console.log(['1', {1:1,2:2}, '3'])
  82. // 改为:console.log('1', {1:1,2:2}, '3')
  83. // 日志的显示效果会更直观一些
  84. console[method].apply(console, data)
  85. } else {
  86. console[method](data)
  87. }
  88.  
  89. }
  90. }
  91.  
  92.  
  93. find()
  94. </script>
  95. </body>
  96. </html>
 

在jQuery中有个插件封装了很多功能来解决懒加载问题

官网地址 
Lazy Load Plugin for jQuery 
http://www.appelsiini.net/projects/lazyload

Lazy Load is delays loading of images in long web pages. Images outside of viewport are not loaded until user scrolls to them. This is opposite of image preloading. 
Using Lazy Load on long web pages will make the page load faster. In some cases it can also help to reduce server load.

For those in hurry there are several demo pages: basic options, with fadein effect, noscript fallback, horizontal scrolling, horizontal scrolling inside container, vertical scrolling inside container, page with gazillion images, load images using timeout and load images using AJAX(H).

When checking the demos clear browser cache between each request. You can check what is actually loaded with developers console (Chrome, Safari and IE) or FireBug (Firefox).

 


  • 基本功能 

     

    淡入效果 
    对不支持JavaScript浏览器的降级处理 
    水平滚动 
    容器内水平滚动 
    容器内垂直滚动 
    页面内存在N多图片 
    经过五秒钟的延迟后加载图片 
    用AJAX来加载图片



 

1,用图片提前占位 
placeholder : “img/grey.gif”, 
参数:placeholder,值为某一图片路径.此图片用来占据将要加载的图片的位置,待图片加载时,占位图则会隐藏

2,载入使用何种效果 
effect : “fadeIn”, 
参数:effect(特效),值有show(直接显示),fadeIn(淡入),slideDown(下拉)等,常用fadeIn

3,提前开始加载 
threshold : 200, 
参数:threshold,值为数字,代表页面高度.如设置为200,表示滚动条在离目标位置还有200的高度时就开始加载图片,可以做到不让用户察觉.

4,事件触发时才加载 
event : “click”, 
参数:event,值有click(点击),mouseover(鼠标划过),sporty(运动的),foobar(…).可以实现鼠标莫过或点击图片才开始加载,后两个值未测试…

5,对某容器中的图片实现效果 
container: $(”#container”), 
参数:container,值为某容器.lazyload默认在拉动浏览器滚动条时生效,这个参数可以让你在拉动某DIV的滚动条时依次加载其中的图片

6,图片排序混乱时 
failurelimit : 10, 
参数:failurelimit,值为数字.lazyload默认在找到第一张不在可见区域里的图片时则不再继续加载,但当HTML容器混乱的时候可能出现可见区域内图片并没加载出来的情况,failurelimit意在加载N张可见区域外的图片,以避免出现这个问题.

 

预加载

我们经常会用下载软件下载电视剧,一个电视剧可以能有N集。 
1.先把所所有的集数全部下载完成,然后一个个开开心心的看。你真的开心吗? 
2.我们先下一集,然后看完,看完以后再去下下一集,然后再看。 
3.我们先下第一集,下载完成以后,再看第一集的时候去下载后面的内容,这样,我们可以在看前面的内容的时候,把后面的下完了,节约了很多的时间 
在页面刚打开的时候,我们去加载第一张图片,然后页面加载完成以后,在用户看的时间内,去加载后面的内容,那么我们必须有个工具(迅雷) -> Image对象

 

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>无标题文档</title>
  6. <script>
  7. window.onload = function() {
  8.  
  9. var oImg = document.getElementById('img1');
  10.  
  11. var oImage = new Image();
  12. /*
  13. 属性:
  14. src : 当我们给Image对象的src属性赋值一个url的时候,这个Image对象就去会加载url资源,加载完成以后的资源被保存到了浏览器的缓存文件夹里面,下次如果我们要去调用这个url地址的时候,直接是从缓存文件夹读取到的,所以速度很快。
  15. onload : 当资源加载完成的时候触发
  16. onerror : 当资源加载失败的时候触发
  17. */
  18. oImage.src = 'http://b.hiphotos.baidu.com/image/w%3D2048/sign=526ef7bda41ea8d38a227304a332314e/1ad5ad6eddc451dae05f4cedb4fd5266d016320e.jpg';
  19. oImage.onload = function() {
  20. alert('加载完成');
  21.  
  22. document.onclick = function() {
  23. oImg.src = 'http://b.hiphotos.baidu.com/image/w%3D2048/sign=526ef7bda41ea8d38a227304a332314e/1ad5ad6eddc451dae05f4cedb4fd5266d016320e.jpg';
  24. }
  25. }
  26.  
  27. /*oImage.onerror = function() {
  28. alert('加载出错');
  29. }*/
  30.  
  31.  
  32. }
  33. </script>
  34. </head>
  35.  
  36. <body>
  37. <img src="" id="img1" />
  38. </body>
  39. </html>

聊聊someet架构 
Someet架构流程 
- 基于github搭建项目 
- 把项目拆成多个库, 使用GIT SUBTREE集成项目到子目录 
- 基础框架:yii2-dockerized

搭建基础框架

分拆项目:github新建两个库 mobile_web common 
composer 安装 yii2-dockerized 
复制.env 与 docker-comopse.yml 规范:dotenv 
将yii2-dockerized push到mobile_web ,作为基础框架 
mobile_web 对 common 的依赖 
在mobile_web中新建packages, 引入 common,创建composer.json 
修改common的composer.json,name:”someet/common” 
修改common的composer.json 
subtree

http://aoxuis.me/post/2013-08-06-git-subtree

docker启动

安装一个新的docker虚拟机:docker-machine create alisimba 
切换环境变量:docker-machine env alisimba 
daocloud加速 
拉取镜像:docker-compose up -d

微信线下调试工具

使用 ngrok,内网穿透工具 
http://blog.phpor.me/tools/2015/11/04/share-ngrok.html

微信与服务器对接

创建一个微信测试帐号 
使用ngrok将本地与线上域名做映射 
把域名配置到微信回调 
在服务器程序中配置微信开发组件 callmez/yii2-wechat 
关闭yii2-crsf

一个网站通用的模块 
博客 
通知中心 
用户模块 
通用的应用架构 
web 
微信公众号 
ios 
android 
y 已使用 n 未使用 
语言 PHP y 
框架 Yii2 y 
关系型数据库 MySQL y 
缓存数据库 Redis y 
消息队列 Beanstalkd y 
阿里云主机 ECS 付费 y 
阿里云数据库 RDS 付费 y 
容器技术 Docker y 
国内Docker平台 Daocloud y 
图片存储 Qiniu 付费 y 
短信平台 yunpian 付费 y 创蓝 y 
队列 Yii2-beanstalkd y 
视频存储 Youku视频 直接使用 n 
搜索引擎 elasticsearch n 
安全协议 zzidc.com/ssl 企业级OV 通配型证书, 一个域名 付费 y 
远程方法调用 thrift Hprose n 
后台前端框架 angularjs y 
后台设计规范 material y 
后台前端自动化构建工具 gulp y 
后台前端包管理 bower y 
手机页面 framework7 y 
计划任务 croon 的其中一种 n 
移动端推送Jpush 极文 付费 n 
代码托管 Github 付费 y 
团队协作工具 pubu.im y 
团队协作任务平台 teambition y 
技术团队的知识管理 quip y 
密码管理 lastpassword/洋葱 1password 付费 y 
微信开发本地调试必备工具 ngrok 付费 y 实际上这个不好用, 自己搭建一个速度比较快 
微信用户统一 微信开放平台, 将网站, 公众号和移动端的帐号统一起来 
http://blog.qqbrowser.cc/ 使用官方的这个调试速度最快, 后来发现也有问题 
npm加速用淘宝镜像 http://npm.taobao.org/ y 
docker加速 daocloud加速器 y 
错误收集中心 sentry 付费 y 暂时免费 
性能分析 amp newrelic.com 付费 y 
单元测试 phpunit n 用于较复杂的逻辑或算法 
集成测试使用 circle / daocloud提供的集成测试 
e2e测试 ui测试 http://sentsin.com/web/658.html n 
前端测试框架 protractor n 
php 代码检查工具 php code sniffer 
php代码规范 psr1/2/3/4 http://segmentfault.com/a/1190000002521577 
灰度发布 
规范:PSR规划 
注释:phpdocumentor http://www.laruence.com/2009/04/21/680.html 
要学习的内容 
docker 
daocloud 
composer 
yii2 
redis 
elasticsearch 
angularjs 
material 
gulp 
git 
ngrok 
sentry 
newrelic 
用到的第三方扩展程序 
正式环境 
yii2 
yii2-bootstrap 
yii2-jui 
yii2-swiftmailer 
yii2-streamlog 
yii2-yunpian 
后台应用 
yii2-authclient 
yii2-user 
yii2-rbac 
yii2-redis 
yii2-elasticsearch 
yii2-queue 
前台应用 
yii2-wechat-sdk 
调试模式 
yii2-debug 
yii2-gii 
yii2-codeception 
yii2-faker 
未来会用yii2以下的几个扩展 
微博 
微信公众号授权 
微信服务号授权 
qq互联授权 https://easypao.com/post/15 http://www.cnsecer.com/7549.htmlhttp://blog.csdn.net/wjtlht928/article/details/46406899 
未来的api使用yii2-json-rpc

工作流程: 
理解需求: 
☐表达自己理解的需求和 PM 达成一致 
分析需求: 
☐需求细分画流程图 
根据流程图写伪代码, 伪代码加for, if 以及注释

正式开发: 
按照伪代码填写代码,注释指导工作 
每完成一个细分的需求就提交一次 
逐步完成整个需求 
开发收尾: 
整理代码,删除测试代码 
测试 
验收: 
最后经过验收,通过后上线,不通过返工 
上线完成后测试所做的更改 
小结: 
回顾工作中的不足和亮点

 

gulp,bower环境搭建,项目自动部署

![此处输入图片的描述][1] 
一、简介(增强和使你的工作自动化) 
1. 使用简单 
没有繁琐的配置,一个任务一个task。通过代码优于配置的策略,Gulp 让简单的任务简单,复杂的任务可管理。

  1. 高效 
    利用node强大的工作流,快速的构建项目并减少频繁的 IO 操作。

  2. 高质量 
    gulp生态圈有相当多优秀的插件以供我们使用,Gulp 严格的插件指南确保插件如你期望的那样简洁高质得工作。

  3. 易学 
    通过最少的 API,掌握 Gulp 毫不费力,构建工作尽在掌握:如同一系列流管道。

二、gulp相关api 
1. gulp.src: 来源 
2. gulp.dest: 目标 
3. gulp.pipe: 管道 
4. gulp.watch: 热加载 
5. gulp.task: 任务 
6. gulp.task('default') 
默认任务,必须存在

三、使用(工作流程) 
1. 全局安装gulp 
npm install -g gulp

  1. 建立项目 
    mkdir gulp-test && cd gulp-test

  2. 初始化项目 
    npm init -y (会生成package.json)

  3. 安装项目依赖 
    npm install --save-dev gulp

创建配置文件 
touch gulpfile.js 
6. gulp常用的功能 
转码(gulp-babel babel-preset-es2015 gulp-sass gulp-less gulp-react)、合并(gulp-concat)、压缩(gulp-uglify)、模块化(gulp-browserify)、测试(gulp-jasmine),请依次安装这些依赖。

  1. 小常识 
    因为国外的网站比较慢 npm经常会卡住。我们可以设置镜像源或使用cnpm或者设置镜像源npm config set registryhttps://registry.npm.taobao.org

  2. 写配置 
    (gulpfile一定有一个default的任务,你可以把每个任务分文件书写然后再require进来,这种方式适合多人同时书写任务时,可以防止多人修改同一文件导致的冲突)

var gulp = require("gulp"); 
var babel = require("gulp-babel"); 
var react = require("gulp-react"); 
var sass = require("gulp-sass"); 
var less = require("gulp-less"); 
var uglify = require("gulp-uglify"); 
var jasmine = require("gulp-jasmine"); 
var concat = require("gulp-concat");

//定义常量 
const transformJs = "transformJs"; 
const transformSass = "transformSass"; 
const transformLess = "transformLess"; 
const test = 'test';

//js 
gulp.task(transformJs, function () { 
return gulp.src("src/*.js") 
.pipe(react()) 
.pipe(babel( 

presets: ["babel-preset-es2015"] 

)) 
.pipe(concat('bundle.min.js')) 
.pipe(uglify()) 
.pipe(gulp.dest("./dist")) 
});

// scss 
gulp.task(transformSass, function () { 
return gulp.src("src/css/*.scss") 
.pipe(sass()) 
.pipe(gulp.dest("./dist")) 
});

// less 
gulp.task(transformLess, function () { 
return gulp.src("src/css/*.less") 
.pipe(less()) 
.pipe(gulp.dest("./dist")) 
});

// jasmine 
gulp.task(test, function () { 
return gulp.src("./test/*.js") 
.pipe(jasmine()) 
});

gulp.task("default", [transformJs, transformSass, transformLess, test]); 
四、配置文件解读 
1. 第一部分 
一堆reqire,是引用gulp相应的插件。在引用之前要确保己经安装。

  1. 第二部分 
    几个const,是定义任务名常量,有多几任务就定义多少常量。

  2. 第三部分 
    几个task,每个task对应一个任务,具有不同的功能。可以使用 gulp xxx来启动这个任务。

  3. 第四部分 
    default,是执行gulp之后就会开始的任务 常用参数('default',[task1,task2,...],callback[可选])。

五、执行 
如果要执行default任务,直接gulp 
[09:56:04] Using gulpfile e:\oscchina\gulp-start-kit\gulpfile.js 
[09:56:04] Starting 'transformJs'... 
[09:56:04] Starting 'transformSass'... 
[09:56:04] Starting 'transformLess'... 
[09:56:04] Starting 'test'... 
.

1 spec, 0 failures 
Finished in 0 seconds 
[09:56:04] Finished 'test' after 62 ms 
[09:56:06] Finished 'transformLess' after 2.66 s 
[09:56:06] Finished 'transformSass' after 2.68 s 
[09:56:06] Finished 'transformJs' after 2.7 s 
[09:56:06] Finished 'default' after 32 μs

Process finished with exit code 0 
如果想要执行单个任务,请输入 gulp taskName,例如gulp test 
[09:56:47] Using gulpfile e:\oscchina\gulp-start-kit\gulpfile.js 
[09:56:47] Starting 'test'... 
.

1 spec, 0 failures 
Finished in 0 seconds 
[09:56:47] Finished 'test' after 77 ms

Process finished with exit code 0 
六、gulp常见任务 
1. 处理js 
(包括转码、合并、压缩) gulp-babel babel-preset-es2015 gulp-concat gulp-uglify

gulp.task(transformJs, function () { 
return gulp.src("src/*.js") 
.pipe(react()) 
.pipe(babel( 

presets: ["babel-preset-es2015"] 

)) 
.pipe(concat('bundle.min.js')) 
.pipe(uglify()) 
.pipe(gulp.dest("./dist")) 
}); 
2. 处理scss 
(包括转码、合并、压缩) gulp-sass gulp-concat gulp-uglify

// scss 
gulp.task(transformSass, function () { 
return gulp.src("src/css/*.scss") 
.pipe(sass()) 
.pipe(gulp.dest("./dist")) 
}); 
3. 处理less 
(包括转码、合并、压缩) gulp-less gulp-concat gulp-uglify

// less 
gulp.task(transformLess, function () { 
return gulp.src("src/css/*.less") 
.pipe(less()) 
.pipe(gulp.dest("./dist")) 
}); 
4. 测试 
gulp-jasmine

// jasmine 
gulp.task(test, function () { 
return gulp.src("./test/*.js") 
.pipe(jasmine()) 
});

//测试文件 test.spec.js 
describe('test one', function () { 
it('test', function () { 
expect(true).toBe(true); 
}) 
}); 
5. 清理 
gulp-clean

gulp.task('clean', function () { 
return gulp.src(config.dist + '/*', {read: false}) 
.pipe(clean()); 
}); 
6. 热加载 
gulp-util gulp-watch

var util = require('gulp-util'); 
var watch = require('gulp-watch'); 
var config = {}; 
config.dist = 'dist'; 
config.static = [ 
'bin/**/*', 
'package.json' 
]; 
// sync static resource in production mode 
gulp.task('static-sync', function () { 
return gulp.src(config.static, {base: './'}) 
.pipe(gulp.dest(config.dist)); 
});

gulp.task('static-sync:dev', ['static-sync'], function () { 
util.log('[Sync] starting file watch'); 
return watch(config.static, function (obj) { 
if (obj.event === 'change' || obj.event === 'add') 
return gulp.src(obj.path, {base: './'}) 
.pipe(gulp.dest(config.dist)) 
.pipe(print(function () { 
return '[Sync] file sync success: ' + obj.path.replace(obj.base, ''); 
})); 
else if (obj.event === 'unlink') { 
var distFilePath = obj.path.replace(__dirname, __dirname + '/' + config.dist); 
return gulp.src(distFilePath) 
.pipe(clean()) 
.pipe(print(function () { 
return '[Sync] file remove success: ' + obj.path.replace(obj.base, ''); 
})); 

}); 
}); 
7. debug 
gulp-print

//下载 
npm install gulp-print 
//引用 
var gulp = require('gulp'); 
var print = require('gulp-print'); 
// 注册任务 
gulp.task('print', function() { 
gulp.src('test/*.js') 
.pipe(print()) 
}); 
8. sourceMap 
gulp-sourcemaps

var sourcemaps = require('gulp-sourcemaps'); 
// compile server script in production mode 
gulp.task('compile:server', function () { 
if (config.babel.sourceMaps){ 
return gulp.src('/.es6', {base: './'}) 
.pipe(sourcemaps.init()) 
.pipe(babel(config.babel)) 
.pipe(sourcemaps.write('.', {sourceRoot: '/ustar'})) 
.pipe(gulp.dest(config.dist)); 
}else{ 
return gulp.src('
/.es6', {base: './'}) 
.pipe(babel({ 
preset:'babel-preset-es2015' 
})) 
.pipe(gulp.dest('./dist')); 
}); 
9. 复制静态资源 
gulp.task('static-sync', function () { 
return gulp.src('src/css/*', {base: './'}) 
.pipe(gulp.dest('./dist')); 
}); 
10. 处理css雪碧图 
gulp-css-spriter

var gulp = require('gulp'); 
var spriter = require('gulp-css-spriter');

gulp.task('css', function() { 
return gulp.src('./src/css/styles.css') 
.pipe(spriter({ 
// The path and file name of where we will save the sprite sheet 
'spriteSheet': './dist/images/spritesheet.png', 
// Because we don't know where you will end up saving the CSS file at this point in the pipe, 
// we need a litle help identifying where it will be. 
'pathToSpriteSheetFromCSS': '../images/spritesheet.png' 
})) 
.pipe(gulp.dest('./dist/css')); 
}); 
11. 压缩css 
gulp-minify-css

gulp.task(gulp_minify_css,function () { 
return gulp.src('./dist/*.css') 
.pipe(print()) 
.pipe(minifycss()) 
.pipe(gulp.dest(config.dist)) 
}); 
12. 压缩图片 
gulp-imagemin

// 压缩图片 
gulp.task('img', function() { 
return gulp.src('src/images/*') 
.pipe(imagemin({ 
progressive: true, 
svgoPlugins: [{removeViewBox: false}], 
use: [pngcrush()] 
})) 
.pipe(gulp.dest('./dest/images/')) 
.pipe(notify({ message: 'img task ok' })); 
}); 
13. 检查js 
gulp-jshint gulp-jshint

// 检查js 
gulp.task('lint', function() { 
return gulp.src('src/js/*.js') 
.pipe(jshint()) 
.pipe(jshint.reporter('default')) 
.pipe(notify({ message: 'lint task ok' })); 
}); 
14. gzip压缩 
gulp-gzip

var gulp = require('gulp'); 
var gzip = require('gulp-gzip');

gulp.task('compress', function() { 
gulp.src('./dev/scripts/*.js') 
.pipe(gzip()) 
.pipe(gulp.dest('./public/scripts')); 
}); 
15. 处理前缀 
gulp-autoprefixer

全选复制放进笔记 var gulp = require('gulp'); 
var autoprefixer = require('gulp-autoprefixer');

gulp.task('default', function () { 
return gulp.src('src/app.css') 
.pipe(sourcemaps.init()) 
.pipe(autoprefixer({ 
browsers: ['last 2 versions'], 
cascade: false 
})) 
.pipe(concat('all.css')) 
.pipe(sourcemaps.write('.',{sourceRoot:config.dist})) 
.pipe(gulp.dest('dist')); 
});

 

someet首页无线滚动实战

ui 框架 淘宝的sui框架 
网址http://m.sui.taobao.org/components/ 
无限滚动 
无限滚动用来在页面滚动到接近底部时加载新内容或进行其他操作。

在底部的无限滚动 
你只需在可滚动的容器上添加“infinite-scroll”类,一般是页面滚动区域 - div.content

<style type="text/css">
      .infinite-scroll-preloader {
        margin-top:-20px;
      }
      </style>

      <header class="bar bar-nav">
          <h1 class="title">底部无限滚动</h1>
      </header>
      <!-- 添加 class infinite-scroll 和 data-distance  向下无限滚动可不加infinite-scroll-bottom类,这里加上是为了和下面的向上无限滚动区分-->
      <div class="content infinite-scroll infinite-scroll-bottom" data-distance="100">
          <div class="list-block">
              <ul class="list-container">
              </ul>
          </div>
          <!-- 加载提示符 -->
          <div class="infinite-scroll-preloader">
              <div class="preloader"></div>
          </div>
      </div>

其中:

div class="content infinite-scroll" -是我们无限滚动的容器 
data-distance - 属性用来配置页面滚动到离底部多远时触发无限滚动事件,默认是50 (px) 
javacript:

// 加载flag
      var loading = false;
      // 最多可加载的条目
      var maxItems = 100;

      // 每次加载添加多少条目
      var itemsPerLoad = 20;

      function addItems(number, lastIndex) {
              // 生成新条目的HTML
              var html = '';
              for (var i = lastIndex + 1; i <= lastIndex + number; i++) {
                  html += '<li class="item-content"><div class="item-inner"><div class="item-title">Item ' + i + '</div></div></li>';
              }
              // 添加新条目
              $('.infinite-scroll-bottom .list-container').append(html);

          }
          //预先加载20条
      addItems(itemsPerLoad, 0);

      // 上次加载的序号

      var lastIndex = 20;

      // 注册'infinite'事件处理函数
      $(document).on('infinite', '.infinite-scroll-bottom',function() {

          // 如果正在加载,则退出
          if (loading) return;

          // 设置flag
          loading = true;

          // 模拟1s的加载过程
          setTimeout(function() {
              // 重置加载flag
              loading = false;

              if (lastIndex >= maxItems) {
                  // 加载完毕,则注销无限加载事件,以防不必要的加载
                  $.detachInfiniteScroll($('.infinite-scroll'));
                  // 删除加载提示符
                  $('.infinite-scroll-preloader').remove();
                  return;
              }

              // 添加新条目
              addItems(itemsPerLoad, lastIndex);
              // 更新最后加载的序号
              lastIndex = $('.list-container li').length;
                  //容器发生改变,如果是js滚动,需要刷新滚动
                  $.refreshScroller();
          }, 1000);
      });
 

工作流程

 

理解需求:

表达自己理解的需求和 PM 达成一致

 

分析需求:

需求细分画流程图 
根据流程图写伪代码, 伪代码加for, if 以及注释

 

正式开发:

按照伪代码填写代码,注释指导工作 
每完成一个细分的需求就提交一次 
逐步完成整个需求

 

开发流程

开发示范 
1.接到需求,整理后在Teambition上面添加任务 
2.进一步的分析,将分析的情况分成多个任务,或者描述的更详细(可以画草图,或请人帮忙) 
3.拉取项目最新代码,检出一个新分支进行开发 
4.开发的过程中不断的兑需求 
5.开发好了之后再兑一下需求,发现没问题再进行推送到远程 
6.已经测试完可以上线了,请求一下 Pull Request, 然后让同事(项目经理或负责你的人)对你的代码进行Review 
7.如果是api或前台项目直接打一个Tag, 如果是后台项目则和同事说,进行上线 
8.然后在Daocloud上面检查镜像构建过程,以及应用编排过程,当应用编排重新部署成功后则可以查看最新更新内容 
9.测试线上是否ok 
10.然后和给你发布这个需求的人,看是否符合需求,当完成,则在Teambition上面打钩完成

 

开发收尾:

整理代码,删除测试代码 
测试

 

验收:

最后经过验收,通过后上线,不通过返工 
上线完成后测试所做的更改

 

小结:

回顾工作中的不足和亮点 记录开发这个项目中的自己有什么创意,或者解决了什么问题,记录下来,以免之后继续用。 
   回顾工作中的不足和亮点 
可以把整个工作中的过程记录在为之笔记或印象笔记,如果是一个比较新的或者自己有创意完成的任务,可以使用markdown形式写一片博客发表在自己的博客平台或者segmentfault.com上面比较推荐segmentfault.com上面有很多伙伴和你互动,会有一些存在感,这是你的工作经验,也是你的名片,对你以后去其它公司面试或者应聘来说,很短的时间内,看到你写的文章就可以看出你都涉及了什么方面的技术有多深,对你来说是一个加分项。

 

翻墙

推荐Shadowsocks 自己搭建很简单,可以找几个伙伴一块买一个国外的vps网上有一键安装脚本,记住端口和密码就可以,推荐https://www.digitalocean.com 
这个主机,已经使用了两年速度挺快。5美元一个月。 
平时尽量多用谷歌搜索,信息比较准确,

 

遇到问题

http://stackoverflow.com/ 一般国外出的产品问题像框架一般都是国外的,上面都能找到答案 
Github.com可以去搜索答案 
如果你使用了某个插件或某个框架问题,通过百度或谷歌还有身边同事实在解决不了就去 
你使用的产品的官方github的issue 去提问 或者国外 stackoverflow.com 和国内的 segmentfault.com 去提问

 

Npm 代理

Npm 最佳代理方式 
平时都是使用 
npm install -g cnpm --registry=https://registry.npm.taobao.org 
西使npm install [name]

 

分享几个自己工作生活中总结的观念

 

是否具备结果导向思维将影响你的一生

以实现目的为目标,不要想着做出多么炫的效果,如果时间充裕还可以,当老板要求的时间内没有完成,不但影响自己的心情,还会受到批评,影响公司进度,可以先实现后再想着优化。

 

先设计在动手

当接到手的任务时,一定要和产品再三的对好需求,不然花了很多时间做出来后和产品的要求不一致,然后重新来做,会浪费了大量的时间,同样当你理解的需求和产品的一致时,也不要立刻就动手去做,除非你信心十足,或者你经验很丰富,建议你先去设计,画图纸也好,再脑子过一遍整个环节,尽量多想到一些细节,可以写一些伪代码,感觉逻辑都差不多清晰了后,再去动手,设计花的时间越长你写代码的时间就会越短,如果前期设计的不到位,你会不断的返工,这样会浪费了你大量的时间。

 

不要拿多少工资做多少事情

因为老板给你的钱少,你只能凑活的干,就因为你凑活的干,老板就给你这么少的钱,成了死循环,生活中很多这种心态的人,美其名曰这叫职业,给多少钱干多少活,职业杀手才有这个职业,给两万要条腿,给十万要条命,而我们作为一个打工的人,作为一个工作者,老板给你8千能不能干2万的活?你的价值不取决于老板给了你多少钱,你的价值取决于你创造了多少价值,你的能力是否得到提升! 
如果存在这种心态,那是在浪费你自己的生命,浪费自己的时间,等时间流失了后,你去下一家找工作就有点麻烦了。

 

一定要把学习英语学好

一定要学好英语,将对于我们一生都会有很大的帮助,尤其是我们从事的行业 
推荐几个学英文的方式,可以先从美语口语开始,推荐赖世雄美语口语从头学,学好发音,然后会有一些自信,能与别人交流更有自信,尽量多去看英文技术文档,把生词积累下来,慢慢就熟悉了,毕竟专业的词汇量不是很多,每天早上早去公司半个小时,可以读写技术文档,比如reactjs官方文档,angularjs api的官方文档 docker的技术文档

相关热词搜索:干货 前端经验

上一篇:javascript for循环里面的settimeout执行问题
下一篇:爱创课堂2016年Angular.JS前端开发从入门到上手企业开发视频

分享到: 收藏