JavaScript

  • 使用jQuery 控制CSS變換不同Class樣式,達到同一頁面切換成不同顯示效果。如以下使用圖文模式圖片模式文字模式,分別為三種class(.vw_01、.vw_02.、vw_03)做切換。
     

  • 在自己的網站上坎入Youtube 播放影片,是一件簡單且輕鬆的事,Youtube提供了完美的平台,迅速且流暢的播放速度,遠比將影片放在自己的主機上方便許多。

  • A JavaScript library for building user interfaces
    用於構建用戶界面的 JavaScript 庫。
    React 是 facebook 官方所維護的開放原始碼 JavaScript 函式庫,可以降低互動式網頁應用程式開發難度,自動處理各種複雜 UI 組件與資料間的連動關係,改善應用程式執行效能。

    使用React這套 JavaScript 函式庫,可以很有效率的開發前端互動式網頁應用,且是許多開源來自世界的社群開發者都在使用,並發展了許多好的 plugins 模組等,所以很多東西都不用自行再造輪子,只要懂得怎麼使用,你可以很快的製造好一台跑車。當然 React 也解決了許多前端開發的痛,讓網頁設計真的可以達到前後端分離,不管你的後端使用的是什麼語言,前端只有 Javascript、CSS、HTML,任何的資料請求都經由 AJAX ,你完全拋離了過去靠著使用者請求 Server,Server 在 render 出網頁的方式,這說明了網頁可以做出互動性高的應用。

  • 5個最好的庫,用於在React中進行AJAX調用

    api-img

    以下React為例,如其他javascript框架與庫也是適用於其中,如vue.js。

    在過去的兩年裡一直和React合作。許多React初學者提出的問題之一是:“從服務器獲取數據的React方式是什麼?”或“我應該如何在React中進行AJAX調用”?要回答你的問題,盡可能多的開發者會告訴你,React只是一個視圖庫,你可以隨意使用任何你喜歡的東西。然而,這並沒有多大幫助 - 特別是當JavaScript格局變化如此之快時。因此,在本文中,我將嘗試回答這個基本問題,並列出5個簡單的庫,用於在React中進行AJAX調用。

  • 使用update()函數經過AJAX方法更新表單。

    var ajaxCallLiveSubs = function(){
    
        // endopoint
        var url = 'https://jsonplaceholder.typicode.com/posts/1';
    
        var interval = 5000;
    
        var time = 0;
    
        // Live Subs Charts
        var ctx_live = document.getElementById("myChart");
    
        var liveChart = new Chart(ctx_live, {
            type: 'line',
            data: {
                labels: [],
                datasets: [{
                    data: [],
                    borderWidth: 1,
                    borderColor:'#00c0ef',
                    label: 'liveCount',
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                legend: {
                    display: false
                },
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero:true,
                        }
                    }]
                }
            }
        });
    
        var doAjax = function() {
    
            $.ajax({
                        url: url,
                        success: function(){
                            var currentTime = ++time
                            var currentValue = Math.random()*1000;
                            liveChart.data.labels.push(currentTime);
                            liveChart.data.datasets[0].data.push(currentValue);
    
                            liveChart.update();
    
                        },
                        complete: function () {
                                // Schedule the next
                                setTimeout(doAjax, interval);
                        }
                    });
        };
    
        doAjax();
    
    };
    
    ajaxCallLiveSubs();
  • 終極解決Javascript非同步

    異步操作是JavaScript編程的麻煩事,麻煩到一直有人提出各種各樣的方案,試圖解決這個問題。

    從最早的回調函數,到Promise對象,再到Generator函數,每次都有所改進,但又讓人覺得不徹底。它們都有額外的複雜性,都需要理解抽象的底層運行機制。

    異步I / O不就是讀取一個文件嗎,幹嘛要搞得這麼複雜?異步編程的最高境界,就是根本不用關心它是不是異步。

    async函數就是隧道盡頭的亮光,很多人認為它是異步操作的終極解決方案。

    異步函數是什麼?

    一句話,async函數就是Generator函數的語法糖。

    前文有一個Generator函數,依次讀取兩個文件。

    var fs = require('fs');
    
    var readFile = function (fileName){
      return new Promise(function (resolve, reject){
        fs.readFile(fileName, function(error, data){
          if (error) reject(error);
          resolve(data);
        });
      });
    };
    
    var gen = function* (){
      var f1 = yield readFile('/etc/fstab');
      var f2 = yield readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };
  • 過去我們可以使用 for, while, do while, for...in 等內在的函式來處理資料,而在 ES6 中我們多了 for...of 這個簡易的用法來處理這些疊代型的資料(iterable objects),包含陣列、字串、map、set、等等...。

    陣列中 for...of 的基本用法

    for...of 的使用非常簡單,以陣列為例:

    let arr = [10, 20, 30]
    
    for(let value of arr){
      console.log(value);  // 10, 20, 30
    }

    只要用這樣的方式,就可以把陣列的值一個個取出,不用像過去寫一大串像是 for(let i = 0; i < arr.length; i++){...} 是不是方便許多呢

  • 在 ES6 中,我們多了一個非常好用的模版字符串(template literal),如果你會在 JS 中「放入 HTML 的內容」、或者有「很長的字串包含換行」、又或者會有「字串連結變數」這樣的需求,模版字符串會是非常方便的作法。

    另外,在 ES6 中可以將模版字符串和函式結合使用,形成一個標籤模版(tagged template),可以以此過濾 HTML 字串,避免使用者輸入惡意內容。

    模版字符串(template literal)的基本應用

    模版字符串的使用非常簡單,就是使用反引號" ` "(鍵盤左上角的~),舉例來說,如果我們會在 JS 的字串中放入 HTML 內容,在過去我們可能需要這樣寫:

    let component_es5 = 
    '<header>\n'+
        '<div class="banner">\n'+
            '<img src="/img1.jpg"\n'+
        '</div>\n'+
    '</header>'

    這麼寫相當麻煩,而且不易閱讀。而在 ES6 中我們可以用反引號快速的解決這樣的狀況:

    let component_es6 = `
    <header>
        <div class='banner'>
            <img src="/img1.jpg>
        </div>
    </header>
    `
  • Javascript table 轉 Excel檔案

    讀取HTML table 將document.write寫入檔案

    function fnExcelReport()
    {
        var tab_text="<table border='2px'><tr bgcolor='#87AFC6'>";
        var textRange; var j=0;
        tab = document.getElementById('headerTable'); // id of table
    
        for(j = 0 ; j < tab.rows.length ; j++) 
        {     
            tab_text=tab_text+tab.rows[j].innerHTML+"</tr>";
            //tab_text=tab_text+"</tr>";
        }
    
        tab_text=tab_text+"</table>";
        tab_text= tab_text.replace(/<A[^>]*>|<\/A>/g, "");//remove if u want links in your table
        tab_text= tab_text.replace(/<img[^>]*>/gi,""); // remove if u want images in your table
        tab_text= tab_text.replace(/<input[^>]*>|<\/input>/gi, ""); // reomves input params
    
        var ua = window.navigator.userAgent;
        var msie = ua.indexOf("MSIE "); 
    
        if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./))      // If Internet Explorer
        {
            txtArea1.document.open("txt/html","replace");
            txtArea1.document.write(tab_text);
            txtArea1.document.close();
            txtArea1.focus(); 
            sa=txtArea1.document.execCommand("SaveAs",true,"Say Thanks to Sumit.xls");
        }  
        else                 //other browser not tested on IE 11
            sa = window.open('data:application/vnd.ms-excel,' + encodeURIComponent(tab_text));  
    
        return (sa);
    }
  • 使用方法

    var curMonthDays = new Date(year,month,0).getDate();
  • 有時候我們會用在網址後面帶參數的做法來在網頁間傳遞一些簡單的資料(QueryString),例如:index.aspx?id=U001&name=GQSM,而JavaScript目前沒有Function可以直接取到後方的資料,所以就得使用一些方式。

    //先取得網址字串,假設此頁網址為「index.aspx?id=U001&name=GQSM」
    var url = location.href;
    
    //再來用去尋找網址列中是否有資料傳遞(QueryString)
    if(url.indexOf('?')!=-1)
    {
        //之後去分割字串把分割後的字串放進陣列中
        var ary1 = url.split('?');
        //此時ary1裡的內容為:
        //ary1[0] = 'index.aspx',ary2[1] = 'id=U001&name=GQSM'
    
        //下一步把後方傳遞的每組資料各自分割
        var ary2 = ary1[1].split('&');
        //此時ary2裡的內容為:
        //ary2[0] = 'id=U001',ary2[1] = 'name=GQSM'
    
        //最後如果我們要找id的資料就直接取ary[0]下手,name的話就是ary[1]
        var ary3 = ary2[0].split('=');
        //此時ary3裡的內容為:
        //ary3[0] = 'id',ary3[1] = 'U001'
    
        //取得id值
        var id = ary3[1];
    
    }
  • navigator 對像中的這幾個與 language 相關的屬性。

    navigator 對象包含有關瀏覽器的信息。沒有應用於 navigator 對象的公開標準,不過所有瀏覽器都支持該對象。但是其內部一些屬性及其返回值在各瀏覽器並不統一。

    language:返回當前的瀏覽器語言(來自 Mozilla Developer Center)

    userLanguage:返回操作系統設定的自然語言(來自 MSDN)

    browserLanguage:返回當前的瀏覽器語言(來自 MSDN)

    systemLanguage:返回當前操作系統的缺省語言(來自 MSDN)

  • JavaScript 歷史與發展

    各位先前可能聽過 ECMAScript 若不知道也沒關係,ES6的出現就他有關係,在1995年時 Netscape(網景)公司與 Sun(昇陽)公司合作 設計一個網頁程式語言名為 JavaScript 名稱屬 Sun(昇陽)公司擁有,後來被Oracle(甲骨文)公司所收購。1996年11月,網景公司將 JavaScript 提交給歐洲計算機製造商協會(ECMA)進行標準。各位可以發現ES4為什麼沒釋出?由於此版本更新幅度太大更新許多功能,怕龐大的變動讓使用者吃不消所以最後決定每年固定釋出更新直到最近的 ES6、ES7。

    規格與版本

    • ECMA-262的第一個版本於1997年6月被 ECMA 組織採納
    • ECMAScript 3 (ES3) 發行於1999年底
    • ECMAScript 4 (ES4) 棄用(原因是貿然大幅度更新對用戶不太好所以改成每年逐一釋出)
    • ECMAScript 5 (ES5) 發行於2009年底
    • ECMAScript 6 (ES6) 發行於2015年中,為目前最新的官方版本
  • 陣列 Array

    這篇文章要來介紹容器,首先先來談談陣列,陣列是有順序地存放大量資料的結構,大多數程式語言都是 0 為起始點,例如 arr[0] , JavaScript 也不例外,當然 JavaScript 的陣列也內建很多函式可以直接呼叫例如 length、match...等。

    陣列的使用

    陣列的初始化有兩種方式一種是立即給值,另一種是後續給值。

    • 立即給值
    const arr = [1, 2, 3]
    console.log(arr.length) // 3
    • 後續給值
    const arr = []
    arr[0] = 1
    arr[1] = 2
    arr[2] = 3
    console.log(arr.length) // 3
  • 如下將fetch寫成函數,返回值時會發現,控制台顯示我的數據Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]],這樣的方式要如何取得資料來應用呢?。

    將提取api fetch寫成函式調用

    function apiGetAll (api) {
        return fetch(api, {
            headers: { "content-type": "application/json" }
        })
            .then(response => response.json().then(json => ({ json, response })))
            .then(({ json, response }) => {
                if (!response.ok) {
                    return Promise.reject(json);
                }
    
                return json;
            })
            .then(response => response, error => error);
    }
  • 控制流程

    任何一種程式語言程式碼都是由上而下逐一執行的,此外有時候必須程式判斷依照不同的數值給予不同的路徑輸出,稱之為控制流程。

    區塊(block)

    ES6 中新增了程式區塊是用大括號包起來的區域:

    {
      statement 1
      statement 2
     ...
      statement n
    }
  • toISOString()轉換解决方式

    台灣的所屬時區比協調世界時快8小時,UTC+8 或是 GMT+8,這裡的 +8 是指比 UTC 或是 GMT 快8小時的意思。 就如Sun Jun 30 2019 00:00:00 GMT+0800 (台北標準時間),使用toISOString().substr(0, 10)轉換擷取前面10個字串,會得到2019-06-29,相差了一天的日期。

    GMT+0800 (台北標準時間),toISOString()轉換因為時區問題會相差8小時。

    //解决方式
    const date = new Date(+new Date() + 8 * 3600 * 1000); //加入相差的8小時
    const currentMonth = date.toISOString().substr(0, 10);
  • 迴圈

    迴圈總共分為三種寫法分別有 for、while、do while,其中最常見也被最常使用的就非 for 迴圈莫屬了,故這邊就先只提 for 一種。

    for 語句

    for 迴圈的小括號內有三個參數用分號隔開,它們各自有其功用,for迴圈的基本語法如下:

    • 參數一控制變數初始值
    • 參數二設定週期
    • 參數三設定每次間隔
    for (let i = 0 ; i < 10 ; i +=1){
        console.log(i);
    }

    這邊值得一提的是我並不是使用 i++ 做每次間隔,由於 ESLint 建議Unary operator '++' used. (no-plusplus) 不要使用 ++ -- 官方是這樣說的

    Why? Per the eslint documentation, unary increment and decrement statements are subject to automatic semicolon insertion and can cause silent errors with incrementing or decrementing values within an application. It is also more expressive to mutate your values with statements like num += 1 instead of num++ or num ++. Disallowing unary increment and decrement statements also prevents you from pre-incrementing/pre-decrementing values unintentionally which can also cause unexpected behavior in your programs.

    簡單來說使用一元遞增(減)會導致程序中的意外行為所以盡量不要使用

  • Javascript filter函式,可以幫助我們過濾一個陣列中符合條件的元素,若不符合則刪除。不更改原陣列,而回傳新陣列。

    filter 函式,接受一個 callback 函式,callback 可以有三個參數(element, index, array),

    • element:陣列元素的值。
    • index:陣列元素的所在位置。
    • arr:已經過 filter 處理的陣列

    過濾陣列中值小於10的元素

    var numbers = [20, 10, 9, 25, 1, 3, 8, 11];
    var result = numbers.filter(function(element, index, arr){
        return element<=10;
    });
    console.log(result);
    // [20, 10, 25, 11]

    callback 中,回傳 false 的元素將會被移除,但注意元陣列並未改變,而是回傳新陣列。

  • 動態import()引入了一種新的類似功能的形式,import與靜態相比,可以解鎖新功能import。本文對這兩者進行了比較,並概述了新的內容。

    靜態import(概述)

    模塊./utils.mjs

    // Default export
    export default () => {
        console.log('Hi from the default export!');
    };
    
    // Named export `doStuff`
    export const doStuff = () => {
        console.log('Doing stuff…');
    };