<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JavaScript &#8211; Larry的午茶時光</title>
	<atom:link href="https://blog.yuyansoftware.com.tw/category/frontend/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.yuyansoftware.com.tw</link>
	<description></description>
	<lastBuildDate>Mon, 14 Apr 2025 04:34:19 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog.yuyansoftware.com.tw/wp-content/uploads/2022/10/favicon-45x45.png</url>
	<title>JavaScript &#8211; Larry的午茶時光</title>
	<link>https://blog.yuyansoftware.com.tw</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>JavaScript ES6 的模組化功能：import, export。建置前端時 require 與 import 有何不同？</title>
		<link>https://blog.yuyansoftware.com.tw/2023/09/javascript-export-import-require/</link>
		
		<dc:creator><![CDATA[Larry]]></dc:creator>
		<pubDate>Sun, 17 Sep 2023 03:08:41 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[前端工程]]></category>
		<category><![CDATA[gulp]]></category>
		<guid isPermaLink="false">https://blog.yuyansoftware.com.tw/?p=16865</guid>

					<description><![CDATA[這篇文章我們來聊一個不新，但重要的議題：JavaScript 的模組化。2015年，JavaScript ECMAScript 2015 發布，也稱為ES6，從此開始，JavaScript 導入了模組化的概念以及語法。]]></description>
										<content:encoded><![CDATA[
<p>這篇文章我們來聊一個不新，但重要的議題：JavaScript 的模組化。</p>



<p>其實 JavaScript 早期只是一個腳本式語言，做做 HTML DOM 的簡單變化而已。也許直接寫在 HTML 裡，也許引用幾支 JS 檔，這樣而已。</p>



<p>2010 年 AngularJS 問世，開啟了 201x 年前端工程的飛速成長，包含各種前端框架的興起，與 Single Page Application (單頁式網站)。AngularJS 後來變成了 Angular，加上 React、Vue.js，這三大家前端框架維持了好一段時間。</p>



<p>延伸閱讀，後來 Laravel 預設的前端框架從 Vue.js 改為使用 Alpine.js (<a href="https://blog.yuyansoftware.com.tw/2021/05/alpine-js-frontend-framework/">我的文章</a>)</p>



<p>2015年，JavaScript <strong>ECMAScript</strong> 2015 發布，也稱為 <strong>ES6</strong>。為什麼是 6 這個數字？是 JavaScript 這個語言的第 6 版。也就是從 ES6 開始，JavaScript 導入了模組化的概念以及語法。</p>



<h2 class="wp-block-heading">ES6 的 import、export</h2>



<p>基本上一個 JS 檔案就是一個模組，用 export 語法，將你想要輸出的變數、函式、物件、類別，都可以輸出。例如</p>



<pre class="wp-block-code"><code>export const your_var = 'test';

export function your_func() {
    // …
}</code></pre>



<p>假設上面檔案叫 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">your_module.js</mark></code>。你可以在 HTML 裡直接輸入 JS 模組，注意一定要寫 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">type="module"</mark></code>，且 import 的後方是大括號</p>



<pre class="wp-block-code"><code>&lt;script type="module"&gt;
    import { your_var, your_func, your_object, your_class } from './your_module.js';

    // 就可以使用 your_var, your_func …
&lt;/script&gt;</code></pre>



<p>或是在另一支 JS (假設名稱是 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">abc.js</mark></code>) 裡面 import，HTML 直接引用 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">abc.js</mark></code>，注意一樣要寫 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">type="module"</mark></code>。也就是 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">your_module.js</mark></code> 的變數輸入到 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">abc.js</mark></code>，並在 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">abc.js</mark></code> 執行</p>



<pre class="wp-block-code"><code>&lt;script type="module" src="./abc.js"&gt;&lt;/script&gt;</code></pre>



<h3 class="wp-block-heading">輸出或輸入都可以改變數名稱</h3>



<p>在輸出時可以改變數名稱</p>



<pre class="wp-block-code"><code>export { your_var as new_name, your_function as new_func };</code></pre>



<p>當然，輸入時就要用新名稱輸入。</p>



<p>輸入時也可以改名</p>



<pre class="wp-block-code"><code>import { your_var as new_name } from "./your_module.js";</code></pre>



<p>這樣在輸入模組就是用新名稱。</p>



<p>還有一種寫法也滿常見的，把整個模組輸入</p>



<pre class="wp-block-code"><code>import * as your_module from './your_module.js';

your_module.func_a();  // 在 your_module.js, func_a 要 named export</code></pre>



<h3 class="wp-block-heading">named 與 default export / import</h3>



<p>以上的 export / import 範例是 <strong>named</strong> export / import (具名輸出/輸入)，還有一種是 <strong>default</strong> export / import。例如</p>



<pre class="wp-block-code"><code>// 輸出
export default your_var;
// 輸入
import new_name from './your_module.js';</code></pre>



<p><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">default export<strong> </strong>最重要的就是在輸出模組「只能出現一次」。</mark>在輸入模組則是任意取名去接。</p>



<p>這樣就是一個最簡單的 export / import 架構了。完整的 export / import 寫法還有很多變形，可以參考 MDN 的 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export" target="_blank" rel="noreferrer noopener nofollow">export 語法文件</a>、<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import" target="_blank" rel="noreferrer noopener nofollow">import 語法文件</a></p>



<h2 class="wp-block-heading">CommonJS 的 require</h2>



<p>目前大部分網站，都是在 Node.js 開發環境 build 前端。常常會看到一個 JS 關鍵字 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">require('...')</mark></code></p>



<p>require 來自於 <strong>CommonJS</strong>，始於開發者的獨立專案。後來 Node.js 用 CommonJS 實作，也採用了 require，直至今日。但必須說明，require 並非 JavaScript ES6 的原生規格。</p>



<p><code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">require</mark></code> 的參數常常是「不加」檔名，為什麼？例如</p>



<pre class="wp-block-code"><code>require(‘./your_your_module’);</code></pre>



<p>依照 <a href="https://nodejs.org/api/modules.html#modules_file_modules" target="_blank" rel="noreferrer noopener nofollow">Node.js 官方文件</a>，Node.js 會先找 .js、.json、.node。如果你要輸入的不是這3個副檔名，require 參數就要寫檔名全稱 (包含副檔名)。</p>



<p><code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">require</mark></code> 參數也可以填入 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">package.json</mark></code> 中列出的套件名稱，這樣 Node.js 就會知道要輸入的檔案路徑 (通常是在 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">node_modules</mark></code> 資料夾底下)。</p>



<h2 class="wp-block-heading">建置前端時 require 與 import 的不同</h2>



<p>我們以 Laravel 舉例。基本上 Laravel 是用 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">require</mark></code>，因為 Laravel 前端建置基底是 Node.js，用的是 CommonJS module system。當然，Node.js 稍作調整可以支援 ES6 module system，不在這裡討論。</p>



<p>如果你有 <strong>local module</strong> (非 Node.js 核心，非 npm 安裝，開發者自己擺在專案的 js 檔案)，require 跟 import 都可以。</p>



<p>這邊要說明一下，不管是 require 或 import，一般情形只是「執行」該 js 檔案。在建置前端時，是將輸入的模組一起 compile 起來。</p>



<h2 class="wp-block-heading">結語</h2>



<p>本篇回顧了一下 JavaScript ES6 的 import / export，也藉這個機會比較了 Node.js 建置前端時用的 require。</p>



<p>本篇重點並「不在」比較 <strong>CommonJS</strong> 與 <strong>ES6</strong> module system，兩者寫法不同，規格也不同。例如，require 輸入的是整個模組，import 可以輸入一個模組中部分的變數、函式、物件、類別。</p>



<p>import / export 與 require 不是新題目，但卻是現代前端技術很重要的模組化功能。很多前端建置工具是基於 Node.js (例如 Laravel)，require 與 import 也大量被使用，很值得再回顧一下。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>初探 Alpine.js — Laravel 預設的前端框架從 Vue.js 改為使用 Alpine.js</title>
		<link>https://blog.yuyansoftware.com.tw/2021/05/alpine-js-frontend-framework/</link>
		
		<dc:creator><![CDATA[Larry]]></dc:creator>
		<pubDate>Sun, 30 May 2021 14:19:26 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[前端工程]]></category>
		<guid isPermaLink="false">https://blog.yuyansoftware.com.tw/?p=7856</guid>

					<description><![CDATA[從 Laravel 5 預設是 Vue.js，到 vue 只是一個選項，到 Laravel 8 預設使用 Alpine.js。就 Laravel 的態度而言，整個趨勢是從 Vue.js 轉到 Alpine.js。本篇我們就來聊一下 Alpine.js]]></description>
										<content:encoded><![CDATA[
<p>這幾年到目前 (2021年5月) 為止，最受歡迎的 JavaScript framework 主要還是三大家：Angular, React, Vue.js。</p>



<p>Laravel 從 5.x 版開始用 Vue.js 當預設的前端框架，Laravel 5 的那一段時間，開發者數量成長很快，相信也間接推動了 Vue.js 的普及。</p>



<p>接下來 Laravel 6 和 7 是使用一個 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">laravel/ui</mark></code> 套件來建構前端，<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">laravel/ui</mark></code> 建構時可以選擇 bootstrap, vue, react 三選一。納入更多選擇，也可以解讀為 Laravel 漸漸脫離 Vue.js 的相依性。</p>



<p>目前 (2021年5月) Laravel 8 則是用一個 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">laravel/breeze</mark></code> 套件來建構前端，<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">laravel/breeze</mark></code> 預設是使用 Alpine.js，但也可以指定要用 vue 或 react。</p>



<p>所以可以看出來，從 Laravel 5 預設是 Vue.js，到 vue 只是一個選項，到 Laravel 8 預設使用 Alpine.js。就 Laravel 的態度而言，整個趨勢是從 Vue.js 轉到 Alpine.js。</p>



<p>本篇我們就來聊一下 Alpine.js</p>



<p>Alpine.js 是一個相對非常年輕的前端框架，1.0 版是 2019 年 12 月釋出。作者是 Caleb Porzio，他是 Laravel 開發者和 Laravel 框架本身的開發者。所以他當時也是用 Vue.js，後來才創作了 Laravel Livewire 及 Alpine.js。</p>



<p>因爲作者 Caleb Porzio 的背景是 Laravel 開發者，想要簡化前端的工作，所以 Alpine.js 的創作精神就是輕量、簡化。Alpine.js 的檔案size很小，安裝及使用簡單，不會因為簡單功能就需要寫一堆 JS code，更沒有編譯 TypeScript 等事情。</p>



<p>Alpine.js 官方網頁 <a rel="noreferrer noopener" href="https://github.com/alpinejs/alpine" target="_blank">https://github.com/alpinejs/alpine</a></p>



<p>Alpine.js 的使用首先用 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-data</mark></code> 宣告一個 component scope。<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-data</mark></code> 裡宣告的變數，在這個 component scope 裡都能存取。</p>



<pre class="wp-block-code"><code>&lt;div x-data="{ foo: 'bar' }"&gt;
...
&lt;/div&gt;</code></pre>



<p>用 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-text</mark></code>, <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-html</mark></code> 可以將變數填入DOM。<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-html</mark></code> 因為內容可以是 html，沒有 escape，所以使用者編輯的內容，不要使用 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-html</mark></code></p>



<pre class="wp-block-code"><code>&lt;span x-text="foo"&gt;&lt;/span&gt;
&lt;span x-html="foo"&gt;&lt;/span&gt;
</code></pre>



<p>使用 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-on:[event]</mark></code> 可以設定 event handler，例如 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-on:click</mark></code>，也可以縮寫成 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">@click</mark></code></p>



<pre class="wp-block-code"><code>&lt;button x-on:click="foo = 'bar'"&gt;&lt;/button&gt;
// 縮寫
&lt;button @click="foo = 'bar'"&gt;&lt;/button&gt;
</code></pre>



<p>使用 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-model</mark></code> 可以雙向綁定 DOM 上顯示的值和 component scope 裡變數的值</p>



<pre class="wp-block-code"><code>&lt;input type="text" x-model="foo"&gt;</code></pre>



<p><code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-if</mark></code> 可以達成 if else 的功能，注意 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-if</mark></code> 需要搭配 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">&lt;template&gt;</mark></code> 使用。官方文件有說，因為 <strong>Alpine.js 不使用虛擬 DOM (virtual DOM)，而是使用真實的 DOM (real DOM)</strong>，使用 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">&lt;template&gt;</mark></code> 以達成輕量、簡化的效果。</p>



<p>另外注意 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-if</mark></code> 和 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-show</mark></code> 的差別，<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-if</mark></code> 判斷式是 false 時，整個 DOM 都會拿掉。<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-show</mark></code> 判斷式是 false 時，該 DOM 還會在，只是 css 設成 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">display: none</mark></code></p>



<pre class="wp-block-code"><code>&lt;template x-if="foo"&gt;
	&lt;div&gt;Some Element&lt;/div&gt;
&lt;/template&gt;
</code></pre>



<p><code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-for</mark></code> 可以達成迴圈的功能，注意 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-for</mark></code> 也需要搭配 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">&lt;template&gt;</mark></code> 使用。如果 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-for</mark></code> 中的 array 資料有可能增減、變換順序，記得要指定 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">:key</mark></code>。照官方文件的說法，每次 iterate 都會標記一個 key，這樣 array 資料有增減、變換順序時，DOM 的變化才會正確。</p>



<pre class="wp-block-code"><code>&lt;template x-for="item in items" :key="item.id"&gt;
    &lt;div x-text="item.content"&gt;&lt;/div&gt;
&lt;/template&gt;

// 如果迴圈中要取用 index, 這樣寫. 而且 index 也可以當 key
&lt;template x-for="(item, index) in items" :key="index"&gt;
    &lt;div x-text="item.content"&gt;&lt;/div&gt;
&lt;/template&gt;
</code></pre>



<p><code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-show</mark></code> 與上方 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-if</mark></code> 比較，保留了 DOM，只是 css 設成 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">display: none</mark></code>。直接使用在 DOM 上，不需要 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">&lt;template&gt;</mark></code>。另外可以使用 transition 來讓 show/hide 更流暢。</p>



<pre class="wp-block-code"><code>/* x-show.transition.in, x-show.transition.out, x-show.transition.scale, x-show.transition.duration …
*/
&lt;div x-show.transition="open"&gt;
    These contents will be transitioned in and out.
&lt;/div&gt;
</code></pre>



<p><code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-bind</mark></code> 可以填入 html 屬性，例如</p>



<pre class="wp-block-code"><code>// 填入圖片來源
&lt;img x-bind:src=”yourImageUrl”&gt;
// 縮寫
&lt;img :src=”yourImageUrl”&gt;

// 指定 input type
&lt;input x-bind:type="inputType"&gt;
// 縮寫
&lt;input :type="inputType"&gt;
</code></pre>



<p>CSS class 的 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-bind</mark></code> 寫法不同</p>



<pre class="wp-block-code"><code>// foo==true 時才會填上 'hidden'
&lt;div x-bind:class="{ 'hidden': foo }"&gt;&lt;/div&gt;
// 縮寫
&lt;div :class="{ 'hidden': foo }"&gt;&lt;/div&gt;
</code></pre>



<p>二元屬性 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">x-bind</mark></code> 的寫法也不同 (二元屬性例如：disabled, readonly, required &#8230;)</p>



<pre class="wp-block-code"><code>// myVar==true 時才會填上 disabled, myVar==false 時整個 disabled 屬性拿掉
&lt;button x-bind:disabled="myVar"&gt;Click me&lt;/button&gt;
// 縮寫
&lt;button :disabled="myVar"&gt;Click me&lt;/button&gt;
</code></pre>



<h4 class="wp-block-heading">結論</h4>



<p>本篇文章主要是想聊一下 Alpine.js 的來龍去脈，以及整個 Alpine.js 的運作邏輯，因此並沒有包含太多細節。</p>



<p>跟其他 JavaScript framework 相比，Alpine.js 很大的特點是<strong>不使用虛擬 DOM (virtual DOM)</strong>，一來輕量、簡化；二來不會因為要寫個簡單功能，就要額外再寫一大堆 JS code。</p>



<p>如果讀者是 Laravel 的開發者，可以研究一下 Alpine.js 的使用，因為畢竟目前 (2021年5月) Laravel 8 的前端預設是用 Alpine.js。甚至 larry 覺得，一般應用如果要做簡單的前端 templating，也可以考慮使用 Alpine.js，而不是那些大型框架。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>網頁滾動元素動畫 AOS.js</title>
		<link>https://blog.yuyansoftware.com.tw/2020/06/aos-js/</link>
		
		<dc:creator><![CDATA[Larry]]></dc:creator>
		<pubDate>Thu, 11 Jun 2020 07:30:00 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[前端工程]]></category>
		<guid isPermaLink="false">https://blog.yuyansoftware.com.tw/?p=3695</guid>

					<description><![CDATA[現在很多網頁，像是手機產品的網頁，當使用者往下拉時，會有圖片或文案浮現的效果。要達成這樣的效果，可以考慮使用 AOS.js。以目前 (2020年6月) 來說，類似功能的插件，應該是以 AOS.js 為主。]]></description>
										<content:encoded><![CDATA[
<p>圖片來源，AOS 官網 <a rel="noreferrer noopener" href="https://michalsnik.github.io/aos/" target="_blank">https://michalsnik.github.io/aos/</a></p>



<p>現在很多網頁，像是手機產品的網頁，當使用者往下拉時，會有圖片或文案浮現的效果。要達成這樣的效果，可以考慮使用 AOS.js。以目前 (2020年6月) 來說，類似功能的插件，應該是以 AOS.js 為主。</p>



<p>安裝上很簡單，沒有相依的插件，將 html 加上 aos.css, aos.js 後，如下方初始化就可以使用</p>



<pre class="wp-block-code"><code>&lt;script&gt;
  AOS.init();
&lt;/script&gt;</code></pre>



<p>將你想要產生動畫的 html 元素加上 data-aos 屬性，例如</p>



<pre class="wp-block-code"><code>&lt;div data-aos="fade-up"&gt;&lt;/div&gt;</code></pre>



<p>當網頁捲動到這個元素時，它就會有一個小小往上 fade in 的動畫。不一定要 &#8220;fade-up&#8221;，fade 系列如</p>



<pre class="wp-block-code"><code>&lt;div data-aos="fade-down"&gt;&lt;/div&gt;
&lt;div data-aos="fade-left"&gt;&lt;/div&gt;
&lt;div data-aos="fade-up-left"&gt;&lt;/div&gt;</code></pre>



<p>以上沒有列出全部的 fade 語法，全部 fade 語法請參考 aos.js 官網。</p>



<p>元素翻轉系列</p>



<pre class="wp-block-code"><code>&lt;div data-aos="flip-up"&gt;&lt;/div&gt;
&lt;div data-aos="flip-down"&gt;&lt;/div&gt;
&lt;div data-aos="flip-left"&gt;&lt;/div&gt;</code></pre>



<p>Zoom in zoom out 系列</p>



<pre class="wp-block-code"><code>&lt;div data-aos="zoom-in"&gt;&lt;/div&gt;
&lt;div data-aos="zoom-in-up"&gt;&lt;/div&gt;
&lt;div data-aos="zoom-out"&gt;&lt;/div&gt;
&lt;div data-aos="zoom-out-up"&gt;&lt;/div&gt;</code></pre>



<p>Again，這邊沒有列出全部的語法，全部語法請參考 aos.js 官網。</p>



<p>另外還有一些其他的設定</p>



<pre class="wp-block-code"><code>data-aos-duration="3000" // 動畫的持續時間，default is 400ms
data-aos-easing="linear" // 動畫的速度曲線，default is ease
data-aos-offset="300" // 調整本來觸發點的offset(in px)，default is 120
data-aos-delay="300" // 動畫的延遲啟動時間，default is 0</code></pre>



<p>另外可以調整該元素動畫在視窗的哪個位置被觸發</p>



<pre class="wp-block-code"><code>data-aos-anchor-placement="top-bottom" // default
data-aos-anchor-placement="center-bottom"
data-aos-anchor-placement="bottom-bottom"</code></pre>



<p>&#8220;top-bottom&#8221; 指的是「該元素的頂端」在瀏覽器的下方，也就是剛剛要出現時，觸發動畫。&#8221;center-bottom&#8221; 指的是「該元素的中間」在瀏覽器的下方時，觸發動畫。&#8221;bottom-bottom&#8221; 指的是「該元素的底部」在瀏覽器的下方時，觸發動畫。所以一般從上往下捲動網頁時，該元素的出現快慢是 &#8220;top-bottom&#8221; &gt; &#8220;center-bottom&#8221; &gt; &#8220;bottom-bottom&#8221;。</p>



<p>anchor-placement 也可以是 &#8220;top-center&#8221; &#8220;center-center&#8221; &#8220;bottom-center&#8221;，理解方式如上一段。xxx-center 因為都是等該元素在瀏覽器的中間時，才觸發動畫。所以一般從上往下捲動網頁時，xxx-center 會比 xxx-bottom 「晚」觸發動畫。</p>



<p>實作時，可能要微調動畫觸發的時機，就可以使用 data-aos-anchor-placement 和上方提到的 data-aos-offset。</p>



<p>結論，aos.js 安裝、撰寫都簡單。如果是網頁設計師，或是前端工程師的讀者，larry 是建議可以考慮使用，而且常常使用。加一些簡單的元素浮出的效果，可以讓你的網頁比較生動，看起來也會比較有現代感。</p>



<p>相關文章：<br><a rel="noreferrer noopener" href="https://blog.yuyansoftware.com.tw/2018/02/fullpage-js.html" target="_blank">全屏滾動網頁 fullPage.js</a><br><a href="https://blog.yuyansoftware.com.tw/2016/01/gulp-css-js-browser-cache.html" target="_blank" rel="noreferrer noopener">如何利用 gulp 自動添加 JS 及 CSS 版號 (auto-versioning)，避免瀏覽器快取</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>全屏滾動網頁 fullPage.js</title>
		<link>https://blog.yuyansoftware.com.tw/2018/02/fullpage-js/</link>
		
		<dc:creator><![CDATA[Larry]]></dc:creator>
		<pubDate>Fri, 23 Feb 2018 02:27:00 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[前端工程]]></category>
		<guid isPermaLink="false"></guid>

					<description><![CDATA[fullPage.js 是一款滿多人使用的全屏滾動網頁框架，如果說把全屏滾動網頁形容成上下播放的投影片，一個 section 就是其中一張投影片，一個網頁可以包含N張投影片，外部要用一個 wrapper 包住 (不能是 html body).]]></description>
										<content:encoded><![CDATA[
<p>圖片來源 <a href="https://github.com/alvarotrigo/fullpage.js" target="_blank" rel="noreferrer noopener" aria-label=" (在新分頁中開啟)">https://github.com/alvarotrigo/fullpage.js</a></p>



<p><a rel="noreferrer noopener" aria-label="https://alvarotrigo.com/fullPage (在新分頁中開啟)" href="https://alvarotrigo.com/fullPage" target="_blank">https://alvarotrigo.com/fullPage</a><br>fullPage.js 是一款滿多人使用的全屏滾動網頁框架，官網右上角 Examples 範例滿多的，例如 <a rel="noreferrer noopener" aria-label="https://alvarotrigo.com/fullPage/examples/navigationV.html (在新分頁中開啟)" href="https://alvarotrigo.com/fullPage/examples/navigationV.html" target="_blank">https://alvarotrigo.com/fullPage/examples/navigationV.html</a><br>就是很好的範例，也就是說這類型的網頁可以考慮使用 fullPage.js 來開發。</p>



<p>fullPage.js 的基本架構是</p>



<pre class="wp-block-preformatted">&lt;div id="your_wrapper_id"&gt;
    &lt;div class="section"&gt;Some section&lt;/div&gt;
    &lt;div class="section"&gt;Some section&lt;/div&gt;
    &lt;div class="section"&gt;Some section&lt;/div&gt;
    &lt;div class="section"&gt;Some section&lt;/div&gt;
&lt;/div&gt;</pre>



<p>如果說把全屏滾動網頁形容成上下播放的投影片，一個 section 就是其中一張投影片，以上方程式碼來說，這個網頁包含四張投影片，外部要用一個 wrapper 包住 (不能是<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">&lt;body&gt;</mark></code>)，網頁初始化時</p>



<pre class="wp-block-preformatted">$('#your_wrapper_id').fullpage({
    ....
});</pre>



<p>…. 處可以填一些 option, 例如 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">sectionsColor</mark></code> 和 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">anchors</mark></code> 是常用的兩個 option</p>



<pre class="wp-block-preformatted">$('#your_wrapper_id').fullpage({
    anchors: ['firstPage', 'secondPage', '3rdPage'],
    sectionsColor: ['#C63D0F', '#1BBC9B', '#7E8F7C'],
});</pre>



<p><code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">anchors</mark></code> 指定每個 section 的頁內位置，例如第二個 section 就是 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-cyan-bluish-gray-color">http://你的網址#secondPage</mark></code><br><code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">sectionsColor</mark></code> 指定每個 section 的背景顏色。</p>



<p>在一個 section 裡也可以塞一些橫的投影片</p>



<pre class="wp-block-preformatted">&lt;div class="section"&gt;
    &lt;div class="slide"&gt; Slide1 &lt;/div&gt;
    &lt;div class="slide"&gt; Slide2 &lt;/div&gt;
    &lt;div class="slide"&gt; Slide3 &lt;/div&gt;
&lt;/div&gt;</pre>



<p>有的設計會在網頁上方固定一個 menu (不隨頁面捲動)，html 寫法如下</p>



<pre class="wp-block-preformatted">&lt;ul id="your_menu_wrapper"&gt;
    &lt;li data-menuanchor="your_anchor1"&gt; Menu1 &lt;/li&gt;
    &lt;li data-menuanchor="your_anchor2"&gt; Menu2 &lt;/li&gt;
    &lt;li data-menuanchor="your_anchor3"&gt; Menu3 &lt;/li&gt;
&lt;/ul&gt;</pre>



<p>需要跟 fullPage 註冊</p>



<pre class="wp-block-preformatted">$('#your_wrapper_id').fullpage({
    menu: '#your_menu_wrapper',
    ....
});</pre>



<p>註冊後當捲到某一個 section 時, 對應的 anchor 的 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">&lt;li&gt;</mark></code> 會自動加上 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">class="active"</mark></code>, 開發者就可以在上面做 style.</p>



<p>很多全屏滾動網頁會在右方有「點點點」導覽，例如這範例頁的右側<br><a rel="noreferrer noopener" aria-label=" (在新分頁中開啟)" href="https://alvarotrigo.com/fullPage/examples/navigationV.html" target="_blank">https://alvarotrigo.com/fullPage/examples/navigationV.html</a><br>初始化時需要下 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">navigation: true</mark></code><br>橫的 slide 也可以有「點點點」導覽，下 <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">slidesNavigation: true</mark></code><br>另外還有一些 option: <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">navigationPosition</mark></code>, <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">navigationTooltips</mark></code> 等，可以自行查一下官網，此處不再贅言。</p>



<p>有時候會希望在顯示 section 時加一點動畫 (例如有些手機廠商網頁，往下捲時手機會移動浮現之類)，這時候就需要 fullPage 的 callbacks, 在裡面做動畫：<br>onLeave (離開 section)<br>afterLoad (進入 section)<br>onSlideLeave (離開 slide)<br>afterSlideLoad (進入 slide)</p>



<p>fullPage.js 預設每個 section 高度佔滿整個 viewport, 官網有提到可以達成單 section auto height, 但如果要使用 fullPage.js, 再去改成每個 section auto height, 是沒有意義的。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>&#8220;It is possible to create sections which height is smaller or bigger than the viewport. This is ideal for footers. It is important to realise that it doesn&#39;t make sense to have all of your sections using this feature.&#8221;</p>
</blockquote>



<p>因為 fullPage.js 每個 section 高度佔滿整個 viewport, 所以他只適合類似投影片上下捲動的設計，不太適合有連續性的一頁式網頁，或是每個 section 自訂高度的網頁。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>[好文分享] 5 Surprises for PHP Developers Coming to JavaScript</title>
		<link>https://blog.yuyansoftware.com.tw/2016/06/5-surprises-for-php-developers-to-js/</link>
					<comments>https://blog.yuyansoftware.com.tw/2016/06/5-surprises-for-php-developers-to-js/#respond</comments>
		
		<dc:creator><![CDATA[Larry]]></dc:creator>
		<pubDate>Sun, 12 Jun 2016 12:09:00 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[前端工程]]></category>
		<category><![CDATA[好文記錄與分享]]></category>
		<category><![CDATA[Link4]]></category>
		<guid isPermaLink="false">http://test234.yuyansoftware.com.tw/2016/06/12/%e5%a5%bd%e6%96%87%e5%88%86%e4%ba%ab-5-surprises-for-php-developers-coming-to-javascript/</guid>

					<description><![CDATA[http://radar.oreilly.com/2013/06/5-surprises-for-php-de &#8230; ]]></description>
										<content:encoded><![CDATA[<div><a href="http://radar.oreilly.com/2013/06/5-surprises-for-php-developers-coming-to-javascript.html" target="_blank" rel="noopener noreferrer"><span style="font-size: large;">http://radar.oreilly.com/2013/06/5-surprises-for-php-developers-coming-to-javascript.html</span></a></div>
<div><span style="font-size: large;"><br />
</span></div>
<p><span style="font-size: large;">1. Functions are objects</span></p>
<div><span style="font-size: large;"><br />
</span></div>
<div><span style="font-size: large;">* function 是一種 object, 所以它也有 built-in property 或是動態設定 property.</span></div>
<div><span style="font-size: large;"><br />
</span></div>
<div><span style="font-size: large;">* function 可以當 input argument, 也可以當 return variable.</span></div>
<div><span style="font-size: large;"><br />
</span></div>
<div><span style="font-size: large;">2. Function scope</span></div>
<div><span style="font-size: large;"><br />
</span></div>
<div><span style="font-size: large;">* nested function 子層級的 function 可以看到父層級 function 的 variable, PHP 不行，PHP 下層 scope 也看不到 global variable, 除非用 global keyword.</span></div>
<div><span style="font-size: large;"><br />
</span></div>
<div><span style="font-size: large;">3. Hoisting</span></div>
<div><span style="font-size: large;"><br />
</span></div>
<div><span style="font-size: large;">* 變數或 function 宣告都自動提升到該 scope 的上方。注意提升到上方的變數初始為 undefined, 所以如果不是一開始就初始的變數，在初始之前是 undefined.</span></div>
<div><span style="font-size: large;"><br />
</span></div>
<div><span style="font-size: large;">* 一般 function 宣告會 hoisting，但如果是 assign function as a variable, 一樣，該 variable 會 hoisting 到上方初始為 undefined.</span></div>
<div><span style="font-size: large;"></span><br />
<a name="more"></a><span style="font-size: large;">4. No classes</span></div>
<div><span style="font-size: large;"><br />
</span></div>
<div><span style="font-size: large;">* 這是 JS 和一般 OO 語言最大的不同之一，沒有 class，而且 object 可以動態新增 property.</span></div>
<div><span style="font-size: large;"><br />
</span></div>
<div><span style="font-size: large;">5. Constructors and prototypes</span></div>
<div><span style="font-size: large;"><br />
</span></div>
<div><span style="font-size: large;">* JS 的 constructor 是 &#8220;constructor function&#8221;, PHP 是 (double underscore)</span></div>
<div><span style="font-size: large;"><br />
</span></div>
<div>
<div><span style="font-size: large;">function __construct() {</span></div>
<div><span style="font-size: large;">&nbsp; &nbsp; &nbsp;&nbsp;</span></div>
<div><span style="font-size: large;">}</span></div>
</div>
<div><span style="font-size: large;"><br />
</span></div>
<div><span style="font-size: large;">* JS 的繼承實作</span></div>
<div><span style="font-size: large;"><br />
</span></div>
<div>
<div><span style="font-size: large;">function Animal() {</span></div>
<div><span style="font-size: large;"><br />
</span></div>
<div><span style="font-size: large;">}</span></div>
<div><span style="font-size: large;">&nbsp;&nbsp;</span></div>
<div><span style="font-size: large;">function Dog() {</span></div>
<div><span style="font-size: large;"><br />
</span></div>
<div><span style="font-size: large;">}</span></div>
<div><span style="font-size: large;">&nbsp;&nbsp;</span></div>
<div><span style="font-size: large;">Dog.prototype = new Animal();</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">注意子類別新的 property 不會出現在 prototype 裡 (ex: Dog.prototype)。另外子類別可以複寫父類別的 property (constructing 順序的問題)。</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">* JS&nbsp;ECMAScript 6 有導入 class, constructor, extends 等 keyword.</span></p>
</div>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.yuyansoftware.com.tw/2016/06/5-surprises-for-php-developers-to-js/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AngularJS (4)</title>
		<link>https://blog.yuyansoftware.com.tw/2016/03/angularjs-4/</link>
		
		<dc:creator><![CDATA[Larry]]></dc:creator>
		<pubDate>Mon, 21 Mar 2016 15:56:00 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[前端工程]]></category>
		<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">http://test234.yuyansoftware.com.tw/2016/03/21/angularjs-4/</guid>

					<description><![CDATA[這兩天試了一下 Angular 2. 與其說是 Angular 的二代，倒不如說整個打掉重練 XD 1. 首先 &#8230; ]]></description>
										<content:encoded><![CDATA[<p><span style="font-size: large;">這兩天試了一下 Angular 2. 與其說是 Angular 的二代，倒不如說整個打掉重練 XD</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">1. 首先，Angular 2 是一個 component based UI framework, 而 Angular 1 還算是 html driven 的框架。這幾年前端的演進很快，就這個時間點而言，似乎 component based 的架構是主流。</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">2. Angular 2 與套件管理工具 npm 有強相關。包含後續會提到的 TypeScript 編譯執行和 local server watching.</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">3. 導入了 TypeScript. TypeScript 是微軟 host 的一個 JavaScript 的再包裝語言(需要 compile 成 JavaScript)。TypeScript 就編寫上可以為 JavaScript 帶來 OO (object oriented) 的概念，它提供了 interface, class 等 keyword, static type check 的概念。值得一提的是，TypeScript 的 project leader 是C#之父 Anders Hejlsberg, 連結是他去年底拜訪中國(推廣TypeScript)的一些會議記錄，非常值得一讀 <a href="https://segmentfault.com/a/1190000003944860" target="_blank" rel="noopener noreferrer">https://segmentfault.com/a/1190000003944860</a></span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">4. 因為導入了 TypeScript, 有很強的 class 的設計概念在裡面。拿掉了 Angular 1 的 controller/scope, Angular 2 的每個 class 就代表一個 scope 的概念。</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">5. Angular 2 的每個 component 就檔案結構上可以擺成 component.html/css/ts(TypeScript). 有 Angular 1 客製化 directive 的感覺，但架構上更正式化。&nbsp;</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">6. 呈5, 正因為這樣所以碎檔很多，官方教程的範例甚至做到了資料程式分離(good practice)，碎檔就更多了。在實戰上會不會比較難管理？是日後可以關注的地方。</span></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>如何利用 gulp 自動添加 JS 及 CSS 版號 (auto-versioning)，避免瀏覽器快取</title>
		<link>https://blog.yuyansoftware.com.tw/2016/01/gulp-css-js-browser-cache/</link>
		
		<dc:creator><![CDATA[Larry]]></dc:creator>
		<pubDate>Sun, 03 Jan 2016 06:07:00 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[前端工程]]></category>
		<category><![CDATA[gulp]]></category>
		<guid isPermaLink="false">http://test234.yuyansoftware.com.tw/2016/01/03/%e5%a6%82%e4%bd%95%e5%88%a9%e7%94%a8-gulp-%e6%9b%bf-css-js-%e5%8a%a0%e4%b8%8a%e7%89%88%e8%99%9f%ef%bc%8c%e9%81%bf%e5%85%8d-browser-cache/</guid>

					<description><![CDATA[當一個使用者瀏覽了你的網站，過沒幾天你更新了 JS 或 CSS，但因為該使用者的瀏覽器記住了上次瀏覽的 JS / CSS，以至於你更新的 JS / CSS 不會在他的瀏覽器上生效。同理，也不會對其他最近瀏覽你網站的使用者生效。]]></description>
										<content:encoded><![CDATA[
<p>圖片來源 <a href="https://github.com/gulpjs/gulp" target="_blank" rel="noreferrer noopener nofollow">https://github.com/gulpjs/gulp</a></p>



<p>一般來說，當使用者開過一個網站，他的瀏覽器會快取網站的 JS 及 CSS (就是記在瀏覽器的意思)。所以當一個使用者瀏覽了你的網站，過沒幾天你更新了 JS 或 CSS，但因為該使用者的瀏覽器記住了上次瀏覽的 JS / CSS，以至於你更新的 JS / CSS 不會在他的瀏覽器上生效。</p>



<p>同理，其他最近瀏覽你網站的使用者(已快取)，如果再打開你的網站，也看不到你剛剛更新的 JS / CSS。</p>



<p>每次更新時自動添加 JS 及 CSS 版號 (auto-versioning) 是一個避免瀏覽器快取的方法。前端工具 gulp 有一套完整的解法，本篇文章會依照 <a href="https://www.npmjs.com/package/gulp-rev-replace" target="_blank" rel="noreferrer noopener nofollow">gulp-rev-replace</a> 的做法一步一步來看。首先它使用&nbsp;<a href="https://www.npmjs.com/package/gulp-useref" target="_blank" rel="noreferrer noopener nofollow">gulp-useref</a> 分別合併 JS 及 CSS.&nbsp;</p>



<pre class="wp-block-code"><code>&lt;!-- build:css css/combined.css --&gt;
your css &lt;link&gt;...
&lt;!-- endbuild --&gt;

&lt;!-- build:js scripts/combined.js --&gt;
your js &lt;script&gt;...
&lt;!-- endbuild --&gt;</code></pre>



<p>照上述 html 轉完後會變成</p>



<pre class="wp-block-code"><code>&lt;link rel="stylesheet" href="css/combined.css"/&gt;

&lt;script src="scripts/combined.js"&gt;&lt;/script&gt; </code></pre>



<p>要注意的是 combined.css, combined.js 目前都還未壓縮，要使用 <a href="https://www.npmjs.com/package/gulp-uglify" target="_blank" rel="noreferrer noopener nofollow">gulp-uglify</a> 壓縮 JS 檔，使用 <a href="https://www.npmjs.com/package/gulp-csso" target="_blank" rel="noreferrer noopener nofollow">gulp-csso</a> 壓縮 CSS 檔，接著使用 <a href="https://github.com/sindresorhus/gulp-rev" target="_blank" rel="noreferrer noopener nofollow">gulp-rev</a> 去改目前 file stream 上的檔案名稱。</p>



<p>例如 combined.js 會改成 combined-12345abcde.js 放在你的 destination folder，combined.css 也會被更名，這個步驟就是所謂的「上版號」。</p>



<p>最後再用 <a href="https://www.npmjs.com/package/gulp-rev-replace" target="_blank" rel="noreferrer noopener nofollow">gulp-rev-replace</a> 將 source html 中的 &lt;link>, &lt;script> 改成指向加上版號的 JS 及 CSS，例如</p>



<pre class="wp-block-code"><code>&lt;link rel="stylesheet" href="css/combined-12345abcde.css"/&gt;

&lt;script src="scripts/combined-12345abcde.js"&gt;&lt;/script&gt; </code></pre>



<p>以上就是 <a href="https://www.npmjs.com/package/gulp-rev-replace" target="_blank" rel="noreferrer noopener nofollow">gulp-rev-replace</a> 文件裡介紹的自動上版號 (auto-versioning) 的流程。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>AngularJS (3)</title>
		<link>https://blog.yuyansoftware.com.tw/2015/12/angularjs-3/</link>
		
		<dc:creator><![CDATA[Larry]]></dc:creator>
		<pubDate>Tue, 15 Dec 2015 13:06:00 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[前端工程]]></category>
		<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">http://test234.yuyansoftware.com.tw/2015/12/15/angularjs-3/</guid>

					<description><![CDATA[https://docs.angularjs.org/tutorial&#160; 一直以來沒有真正走過官方教 &#8230; ]]></description>
										<content:encoded><![CDATA[<p><span style="font-size: large;"><a href="https://docs.angularjs.org/tutorial" target="_blank" rel="noopener noreferrer">https://docs.angularjs.org/tutorial</a>&nbsp; </span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">一直以來沒有真正走過官方教程。其實這官方教程有一些很基本扎實的東西，尤其是 coding convention 的部分可以參考。</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">1. ng-app 宣告在 html tag, ng-controller 宣告在 body tag.</span><br />
<span style="font-size: large;">2. object array 換行，indent 的方式 </span></p>
<pre>$scope.phones = [
  {'name': 'Nexus S',
   'snippet': 'Fast just got faster with Nexus S.'},
  {'name': 'Motorola XOOM&#x2122; with Wi-Fi',
   'snippet': 'The Next, Next Generation tablet.'},
  {'name': 'MOTOROLA XOOM&#x2122;',
   'snippet': 'The Next, Next Generation tablet.'}
];
</pre>
<p><span style="font-size: large;">3. Filtering Repeaters. ng-repeat 可以加上 filter. 另外也可以選擇 sort &#8216;orderBy&#8217;</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">4. $http. 首先教程上 sample code&nbsp;$http.get(&#8216;url&#8217;).success(&#8230;</span><br />
<span style="font-size: large;"><a href="https://docs.angularjs.org/api/ng/service/$http" target="_blank" rel="noopener noreferrer">https://docs.angularjs.org/api/ng/service/$http</a>&nbsp;有提到</span><br />
<span style="font-size: large;"><span style="color: #999999;">&#8220;The $http legacy promise methods success and error have been deprecated. Use the standard then method instead.&#8221;</span></span><br />
<span style="font-size: large;">=&gt; 用 then 而不是 success / error.</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">get 回來的 data 一定要是 json 格式，如果 callback function input 是 &#8216;response&#8217;, url 上放的 data 是 {&#8220;PPP&#8221;: &#8220;QQQ&#8221;}, 則在 callback function 中 response.data.PPP 中存的就是 &#8220;QQQ&#8221;. 另外要特別注意的是 json 的 object array 最後不能有逗點。上述 $scope.phones array 最後一個 object 的後方加逗號是 ok 的，但在 json 不行。另外如果 json 中要直接指定 array 的話，直接用上述 object array 的格式即可，中括號開頭，中括號結尾。Again, 如果 callback function input 是 &#8216;response&#8217;, response.data 存的就是該 array.</span></p>
<p><a name="more"></a><a href="https://docs.angularjs.org/tutorial/step_05" target="_blank" rel="noopener noreferrer"><span style="font-size: large;">https://docs.angularjs.org/tutorial/step_05</span></a><br />
<span style="color: #999999; font-size: large;">&#8220;$ Prefix Naming Convention</span><br />
<span style="color: #999999; font-size: large;">As a naming convention, Angular&#39;s built-in services, Scope methods and a few other Angular APIs have a $ prefix in front of the name.&nbsp;</span><br />
<span style="color: #999999; font-size: large;"><br />
</span><span style="font-size: large;"><span style="color: #999999;">The $ prefix is there to namespace Angular-provided services. To prevent collisions it&#39;s best to avoid naming your services and models anything that begins with a $.&#8221;</span></span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">也是 Coding convention 的東西，inject service to controller 方法一： </span></p>
<pre>function PhoneListCtrl($scope, $http) {...}
PhoneListCtrl.$inject = ['$scope', '$http'];
phonecatApp.controller('PhoneListCtrl', PhoneListCtrl);
</pre>
<p><span style="font-size: large;">方法二 </span></p>
<pre>phonecatApp.controller('PhoneListCtrl', ['$scope', '$http', function($scope, $http) {...}]);
</pre>
<p><span style="font-size: large;">因為 $scope, $http 是 Angular 內建 services, 可以省略 </span></p>
<pre>phonecatApp.controller('PhoneListCtrl', function($scope, $http) {...});
</pre>
<p><span style="font-size: large;">5. ng-route.&nbsp;<a href="https://docs.angularjs.org/tutorial/step_07" target="_blank" rel="noopener noreferrer">https://docs.angularjs.org/tutorial/step_07</a></span><br />
<span style="color: #999999; font-size: large;">&#8220;Providers can only be injected into config functions. Thus you could not inject $routeProvider into PhoneListCtrl. </span><br />
<span style="font-size: large;"><span style="color: #999999;">Starti</span><span style="color: #999999;">n</span></span><span style="color: #999999; font-size: large;">g with AngularJS version 1.2, ngRoute is in its own module and must be loaded by loading the additional angular-route.js file.&#8221;</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">這章節的 sample 新增一個 module &#8216;phonecatControllers&#8217;, 將多個 view 的 controller 設定在 &#8216;phonecatControllers&#8217; 底下，再將 &#8216;phonecatControllers&#8217; inject 進 app module &#8216;phonecatApp&#8217;, 在 &#8216;phonecatApp&#8217; config 中就可以指定 route templateUrl 和 controller 了。</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">6. custom filter. Add filter module, add filter name, add the filter module to the dependencies of app module, then html can use the filter.</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">7. REST and Custom Services&nbsp;<a href="https://docs.angularjs.org/tutorial/step_11" target="_blank" rel="noopener noreferrer">https://docs.angularjs.org/tutorial/step_11</a></span><br />
<span style="font-size: large;">首先 inject 進 controller 時，如果有自定的 services, 即使是 Angular 內建的 services 也要列出 (下例中 $scope 要列出，不能省略)</span></p>
<pre>phonecatControllers.controller('PhoneListCtrl', ['$scope', 'Phone', function ($scope, Phone) {

}]);
</pre>
<p><span style="color: #666666;"><span style="color: #999999; font-size: large;">&#8220;An important thing to notice in the code above is that we don&#39;t pass any callback functions when invoking methods of our Phone service. Although it looks as if the result were returned synchronously, that is not the case at all. What is returned synchronously is a &#8220;future&#8221; — an object, which will be filled with data when the XHR response returns.&#8221;</span></span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">有些人會認為&#8221;當下 return 後來填上&#8221;的方式&nbsp;ambiguous, 所以教程上也提供了設定 callback 的方式。</span></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>AngularJS (2)</title>
		<link>https://blog.yuyansoftware.com.tw/2015/08/angularjs-2/</link>
		
		<dc:creator><![CDATA[Larry]]></dc:creator>
		<pubDate>Sat, 15 Aug 2015 15:38:00 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[前端工程]]></category>
		<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">http://test234.yuyansoftware.com.tw/2015/08/15/angularjs-2/</guid>

					<description><![CDATA[1. 開發環境 Sublime, install AngularJS and AngularJS Snippe &#8230; ]]></description>
										<content:encoded><![CDATA[<p><span style="font-size: large;">1. 開發環境 Sublime, install AngularJS and AngularJS Snippets</span><br />
<span style="font-size: large;">2. Use ex: &#8220;myCtrl as m&#8221; and then use m.ooo, m.xxx in html.&nbsp;</span><span style="font-size: large;">利用這方式在 html 提供一個 scope, 這樣 controller 和 child controllers 的變數就不會混淆.</span><br />
<span style="font-size: large;">3. 不管在 parent/child controller 注入 $scope 設定變數 ex: $scope.name = &#8220;ABC&#8221;, name 變數是屬於整個 module 的 (不屬於個別 controller scope), 因為 $scope 是 global singleton.</span><br />
<span style="font-size: large;">4. html 中在 child controller 範圍可以拿到 parent controller 的變數 (當然 parent 不能拿 child controller 的變數)</span><br />
<span style="font-size: large;">5. value, factory, service, provider 的關係. Refer to Anuglar source &#8220;// $provider&#8221; block. 基本上都是 provider 的不同包裝, 階層關係是 value, service -&gt; factory -&gt; provider.</span><br />
<span style="font-size: large;">provider 必須定義 this.$get, which returns an object in it.</span><br />
<span style="font-size: large;">factory directly returns an object.</span><br />
<span style="font-size: large;">service 有更強的物件化, ex: this.prop1 = &#8220;ooo&#8221;, this.prop2 = &#8220;xxx&#8221;</span><br />
<span style="font-size: large;">value 是最簡化的包裝.</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">6. Services 可以在 angular.module.config 初始化, 在 angular.module.run 指定給 $rootScope. 或是注入 controller 指定給 controller member.</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">7. 如何從 view (html) 觸發 service? 對於 native javascript, button handler 裡 $injector.get(&#8216;service_name&#8217;) 可以拿到 service object. 另外 ng-click handler 可以調用 controller scope 底下的 function, 在 controller 中可以指定 service function 為 controller scope 底下的 function.</span></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>AngularJS (1)</title>
		<link>https://blog.yuyansoftware.com.tw/2015/06/angularjs-1/</link>
		
		<dc:creator><![CDATA[Larry]]></dc:creator>
		<pubDate>Sun, 14 Jun 2015 07:48:00 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[前端工程]]></category>
		<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">http://test234.yuyansoftware.com.tw/2015/06/14/angularjs-1/</guid>

					<description><![CDATA[初探 AngularJS 的一些心得: 1. 當然他是 UI 拿來做 data binding 的一個 fra &#8230; ]]></description>
										<content:encoded><![CDATA[<p><span style="font-size: large;">初探 AngularJS 的一些心得:</span><br />
<span style="font-size: large;"><br />
</span><span style="font-size: large;">1. 當然他是 UI 拿來做 data binding 的一個 framework.</span><br />
<span style="font-size: large;">2. Modularization. 宣告 html 區塊成為模組, 底下的 JavaScript 函式與變數都給上 scope, 改善 JS source files, functions, variables 基本上都是 global (in a page) 的問題.</span><br />
<span style="font-size: large;">3. 承上, nested controller 是被鼓勵的. Nested controller 可以達成 scope inheritance 的效果, 在指定區塊自行開一個 scope.</span><br />
<span style="font-size: large;">4. Inline JavaScript. Angular 有自己的 template engine. 但須注意 Angular template language 有時會與其他 template language 衝突, ex: Jinja2, 此時要更改 Angular template 的 starting / ending symbol.</span><br />
<span style="font-size: large;">5. Dependency injection. 之前有談過 dependency injection (<a href="http://larrysmatchawaffle.blogspot.tw/2013/12/inversion-of-control.html" target="_blank" rel="noopener noreferrer">link</a>). Dependency injection 旨在解除相依性, 在開發當下模組時不用考慮相依模組的進度. Angular 自 controller 以下基本上都是 dependency injection 的概念.</span><br />
<span style="font-size: large;">6. ng-repeat 是一個 powerful directive. 在前端動態增減 table 項目時完全不需對 html component 做操作.</span></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
