經驗分享

目錄

  • 介紹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. : 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的技術文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章